2013-02-21 4 views
1

Я использую Qt для разработки настраиваемого интерфейса управления для xmgrace, 2D-графической библиотеки. У меня есть 3 компонента в моем проекте:QProcess: Разрушен, пока процесс все еще запущен

  1. Графический интерфейс выполнен в Qt
  2. QThread который запускает некоторый общий код объекта из C в фоновом потоке.
  3. Окно xmgrace, соединенное с обоими выше, с использованием трубы. (Использование библиотеки grace_np)

Связь с (1) --> (2) осуществляется путем изменения статуса некоторых глобальных переменных, объявленных в общем объектном коде.

Связь с (1) --> (3) & (2) --> (3) использует встроенные функции, предоставляемые библиотекой grace_np.

Теперь сообщение от (2) --> (1) является тем, что вызывает проблемы. Я пробовал два возможных способа, о которых я мог думать: a) Объявление общего объекта в Qt-коде, который испускает Qt-сигнал и вызывается внутри кода C. b) Возврат из потока и использование возвращаемого значения для выполнения некоторой операции, а затем перезапуск потока.

Обе эти методологии дали ненадежные результаты. Мой GUI застревает/вызывает ошибку сегментации и я получаю сообщение:

QProcess: Destroyed while process is still running

Я не использую класс QProcess где-нибудь в моем коде. Так что это стало загадкой. Просьба предоставить информацию о возможных причинах этого.

PS: Труба до (3) является одним из способов и требуется только в этом направлении.

Edit 1:

FYI Я использую Qt 4.2, поэтому я не могу использовать подход QObject, а затем использовать movetothread() Я прошу прощения за не прикладывая код, как я не может из-за политики компании, а также потому, что я не знаю, что поставить (ее слишком много). Общий код c составляет 400k + строк

Я считаю, что я нашел виновника своей проблемы. Похоже, что использование класса QMessageBox вызывает эту проблему. Сначала я использовал статическую функцию QMessageBox. Теперь я попытался объявить его как стек, так и кучу, но проблема все еще сохраняется. Но я обнаружил, что удаление всех вызовов QMessageBox из моего кода решает проблему. Но тогда проблема в том, как показывать сообщения? Я просто размышляю здесь, но возможно ли, что модальная природа QMessageBox блокирует существующую между моей программой и xmgrace трубу и впоследствии вызывает ее? Тогда создание пользовательского QMessageBox (не модальное) может решить эту проблему.

Edit 2:

Я не вызывая QMessageBox из рабочего потока. Плюс, как я использую рабочий поток, он никогда не возвращается, если я не закрываю программу.Чтобы дать представление о моей QThread :: запустить функцию имеет вид:

QThread_Object::run() 
{ 
    c_init(); 
    c_main(); 
} 

где c_init & c_run являются функции, связанные с общим кодом гр. Таким образом, невозможно напрямую вызвать QMessageBox изнутри. На данный момент я планирую отказаться от QMessageBox и вместо этого использовать строку состояния QMainWindow. Но тогда это не дает всей функциональности. Я полагаю, что это может быть ошибка в Qt 4.2

Edit 3:

я упоминал ранее, что сообщение от (2) --> (1) было то, что вызывает проблемы. Теперь я полностью покончил с этим сообщением и более точно обнаружил, что проблема вызвана вызовом QMessageBox в любое время после запуска рабочего потока. Ранее упомянутое выше сообщение заставляло Qt излучать сигнал опосредованно и ссылаться на QMessageBox, который, я считаю, был виновником.

Редактировать 4:

Хорошо, я забыл упомянуть самую большую тайну, окружающую эту проблему с самого начала. Я в основном работаю (место A) через ssh на рабочей станции (место B), на которой я кодирую и запускаю эту программу. B подключен к двум физическим сетям. A подключается к B через сеть 1. Теперь эта проблема имеет никогда не было во время работы с моим терминалом в точке A (т.е. на ssh через сеть 1). Но он постоянно возникает, когда я напрямую обращаюсь к B или через ssh через сеть 2. Обратите внимание, что каждый раз, когда код выполняется только на B. Обе эти сети используются хендерами.

Edit 5

Наконец, я решил мою проблему суб-причислять QDialog и созданием пользовательского MessageBox, как я на самом деле не требуют расширенной функциональности QMessageBox. Я все еще не знаю, что именно в QMessageBox вызывало проблему. Я предполагаю, что в Qt есть ошибка, которая всегда останется загадкой.

+2

нет код? как насчет печенья? –

+1

Мы не можем ответить, если мы не знаем, как вы делаете 1, 2 и 3. «Я не называл QProcess, но он врезался в мою программу», это не дает нам многого. – Phlucious

ответ

1

Поскольку кода нет, я немного стреляю в темноте, но похоже, что ваш QProcess был создан в стеке, умышленно или нет, или ваш QThread будет уничтожен преждевременно. Я поместил деньги на ваши объекты QThread, запущенные неправильно. Трудно обвинить вас, поскольку документация (или до недавнего времени) была отвратительной. Рассмотрите возможность чтения this thread и this thread и вообще не выполняйте класс QThread.

Edit: Если QMessageBox ваш преступник, то я предполагаю, что вы показываете его из дочернего потока. Из documentation:

В приложениях с графическим интерфейсом пользователя главный поток также называется GUI поток , потому что это единственный поток, который может выполнять GUI связанных операций.

Существует несколько способов отображения сообщений из дочернего потока. Лично я использую схему отчетности об ошибках qt и перенаправляет qCritical, qDebug и т. Д. На stderr. Еще один простой способ сделать это будет для вас emit сигнал QString из рабочего потока, который пойман вашим потоком GUI, который затем отображает/собирает ошибку. Мне нравится, когда мой MainWindow собирает ошибки, а затем отображает их все сразу, когда рабочий поток заканчивается.

Edit 2: Поскольку проблема, как представляется, QMessageBox быть модальным (т.е. блокирует основной поток в то время как рабочий поток движется вперед), вы можете легко решить эту проблему с помощью QMessageBox в его покадрово режимах. Просто передайте 0 в качестве родительского виджета в конструкторе QMessageBox/статической функции. Обработка будет продолжаться, не дожидаясь выхода пользователя из окна - это может также привести к тому, что одновременно откроются несколько ящиков сообщений. Если это поможет вам избежать ошибки, внимательно прочитайте свой код, чтобы убедиться, что окна были уничтожены после закрытия.

+0

Спасибо, что посмотрели на это, но, к сожалению, я не могу попробовать другой подход, так как я использую Qt4.2, где единственным вариантом является подкласс QThread. Я сожалею о том, что не ставил код, поскольку я не могу из-за политики компании, а также потому, что я не знаю, что поставить. – theta

+0

Я рассмотрел ваш вопрос с помощью редактирования. См. Мои правки выше. – Phlucious

+0

К сожалению, я считаю, что это не проблема напрямую, но она может быть как-то связана с этой концепцией внутри Qt из-за поведения проблемы, с которой я столкнулся. – theta