Я использую Qt для разработки пользовательского интерфейса управления для библиотеки 2D-графиков xmgrace.
У меня есть 3 компонента в моем проекте:
Сообщение от (1) --> (2)
это делается путем изменения статуса некоторых глобальных переменных, объявленных в коде общего объекта.
Сообщение от (1) --> (3)
& (2) --> (3)
использует встроенные функции, предоставляемые библиотекой grace_np.
Теперь общение с (2) --> (1)
это то, что вызывает проблемы. Я попробовал 2 возможных способа, которыми мог придумать:
а) Объявление общего объекта в коде Qt, который испускает сигнал Qt и вызывается в коде C.
б) Возврат из потока и использование возвращаемого значения для выполнения какой-либо операции, а затем перезапустите поток.
Обе эти методики дали ненадежные результаты. Мой графический интерфейс застревает / вызывает ошибку сегментации, и я получаю сообщение:
QProcess: Destroyed while process is still running
Я не использую класс QProcess нигде в моем коде. Так что это стало загадкой.
Пожалуйста, предоставьте некоторую информацию о возможных причинах этого.
PS: труба в (3)
является одним из способов и требуется только таким образом.
Изменить 1:
К вашему сведению, я использую Qt 4.2, поэтому я не могу использовать подход QObject, а затем использовать movetothread ()
Прошу прощения за то, что не поместил код, поскольку я не могу из-за политики компании, а также потому, что я не знаю, что поставить (это слишком много). Общий код c составляет 400 000 строк
Я считаю, что нашел виновника в моей проблеме. Кажется, что использование класса QMessageBox вызывает эту проблему. Я изначально использовал статическую функцию QMessageBox. Теперь я попытался объявить его как в стеке, так и в куче, но проблема все еще сохраняется.
Но я обнаружил, что удаление всех вызовов QMessageBox из моего кода решает проблему.
Но тогда проблема в том, как мне показать сообщения?
Я просто размышляю здесь, но возможно ли, что модальная природа QMessageBox блокирует канал, существующий между моей программой и xmgrace, и впоследствии вызывает его выход? Тогда создание пользовательского QMessageBox (не модального) может решить эту проблему.
Изменить 2:
Я не вызываю QMessageBox из рабочего потока. Плюс то, как я использую рабочий поток, он никогда не вернется, если я не закрою программу. Чтобы дать представление, моя функция QThread :: run имеет вид:
QThread_Object::run()
{
c_init();
c_main();
}
где c_init & c_run — это функции, связанные с общим кодом c. Так что нельзя напрямую вызывать QMessageBox из них.
Сейчас я планирую покончить с QMessageBox и использовать вместо него строку состояния QMainWindow. Но тогда это не дает всей функциональности. Я полагаю, это может быть ошибка в Qt 4.2
Изменить 3:
Я упоминал ранее, что сообщение от (2) --> (1)
было то, что вызывало проблемы. Теперь я полностью покончил с этим сообщением и более точно обнаружил, что проблема вызвана вызовом QMessageBox в любое время после запуска рабочего потока. Ранее упомянутое выше сообщение заставляло Qt косвенно излучать сигнал и вызывать QMessageBox, который, я считаю, был виновником.
Изменить 4:
Хорошо, я забыл упомянуть самую большую загадку вокруг этой проблемы с самого начала. Я в основном работаю (место A) через ssh на рабочей станции (место B), на которой я пишу код и запускаю эту программу.
B подключен по 2 физическим сетям. A подключен к B через сеть 1. Теперь эта проблема имеет никогда произошло во время работы с моего терминала в A (то есть на SSH через сеть 1). Но это происходит постоянно, когда я получаю доступ к B напрямую или через ssh через сеть 2. Обратите внимание, что каждый раз, когда код выполняется только на B. Обе эти сети используются сотнями.
Редактировать 5
Наконец, я решил свою проблему с помощью подкласса QDialog и создания собственного MessageBox, поскольку мне действительно не требуется расширенная функциональность QMessageBox. Я до сих пор не знаю, что именно в QMessageBox вызывало проблему. Я предполагаю некоторую ошибку в Qt, которая всегда будет оставаться загадкой.
Поскольку здесь нет кода, я немного снимаю в темноте, но похоже, что ваш QProcess был создан в стеке, намеренно или нет, или ваш QThread преждевременно уничтожается. Я бы положил деньги на ваши объекты QThread, которые запускаются неправильно. Трудно винить вас, так как документация является (или была до недавнего времени) виной. Рассмотреть вопрос о прочтении эта тема а также эта тема и не делайте подкласса QThread вообще.
Редактировать:
Если QMessageBox — ваш виновник, тогда я предполагаю, что вы отображаете его из дочернего потока. От документация:
В приложениях с графическим интерфейсом основной поток также называется потоком с графическим интерфейсом
потому что это единственный поток, которому разрешено выполнять связанные с GUI
операции.
Существует несколько способов отображения сообщений из дочерней темы. Лично я использую схему сообщений об ошибках qt и перенаправляю qCritical, qDebug и т. Д. stderr
, Еще один более простой способ сделать это для вас emit
сигнал QString от вашего рабочего потока, который перехватывается вашим потоком GUI, который затем отображает / собирает ошибку. Мне нравится, когда мое MainWindow собирает ошибки, а затем отображает их сразу после завершения рабочего потока.
Изменить 2:
Поскольку проблема, кажется, QMessageBox будучи модальным (то есть блокируя ваш основной поток, пока рабочий поток движется вперед), вы можете легко решить эту проблему, используя QMessageBox в его немодальных режимах. Просто пройти 0
как родительский виджет в конструкторе / статической функции QMessageBox. Обработка будет продолжена без ожидания выхода пользователя из окна — это может также привести к одновременному открытию нескольких окон сообщений. Если это поможет вам избежать ошибки, внимательно просмотрите код, чтобы убедиться, что окна закрываются после закрытия.
Других решений пока нет …