我正在编写一个Qt(5.3)程序,其中包含一个操纵杆测试UI,但是我需要一个单独的线程来进行无限循环,通过SDL查找操纵杆轴/按钮值的变化。这部分代码工作正常,因为我可以有线程qDebug()消息,它似乎工作。但是从主窗口,当我尝试打开测试操纵杆UI时,程序崩溃了。我已经让测试操纵杆UI在没有JoystickThread线程的情况下运行分离,它似乎打开了很好。
错误消息虽然不一致 - 有时候,我只是
该程序意外完成。 / home / narendran / QtWorkspace / build-LinkControl-Desktop-Debug / LinkControl崩溃
这已经出现过一次:
QXcbWindow:未处理的客户端消息:“_ GTK_LOAD_ICONTHEMES”
还有其他几次:
[xcb]处理队列时序列号未知 [xcb]这很可能是一个多线程客户端,而且还没有调用XInitThreads [xcb]中止,对不起。 star:../../ src / xcb_io.c:274:poll_for_event:断言`!xcb_xlib_threads_sequence_lost'失败。
我发现这很常见,如果是XInitThreads();不是在main函数中运行,但即使它在那里,它也会崩溃并出现相同的错误。
的main.cpp
#include <qsplashscreen.h>
#include "linkcontrol.h"
#include "configure.h"
#include <unistd.h>
#include <QApplication>
#include <QPixmap>
#include <QStyle>
#include <QDesktopWidget>
#include "linkports.h"
#include "joystickthread.h"
#include <X11/Xlib.h>
int main(int argc, char *argv[])
{
XInitThreads();
QApplication a(argc, argv);
QPixmap pix(":splash.png");
QSplashScreen splash(pix);
splash.show();
a.processEvents();
JoystickThread jsThread;
jsThread.start();
LinkControl linkcontrol;
usleep(1000000);
splash.finish(&linkcontrol);
usleep(100000);
linkcontrol.show();
linkcontrol.setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,linkcontrol.size(),a.desktop()->availableGeometry()));
return a.exec();
}
实际线程位于 joystickthread.cpp
#include "joystickthread.h"
#include "global.h"
#include "unistd.h"
/* JoystickThread::JoystickThread(int _interval)
{
this->interval_us = _interval;
} */
void JoystickThread::run()
{
while(1)
{
if(joystick->connected)
{
joystick->updateJSData();
// Check for changed values
for(int i=0; i<joystick->axis.count(); i++)
{
if(joystick->axis.value(i) != joystick->axis_last[i])
{
joystick->axisUpdateEmit(i);
// qDebug() << "AXIS: " << i << "\tVALUE: " << joystick->axis.value(i);
}
joystick->axis_last[i] = joystick->axis.value(i);
}
for(int i=0; i<joystick->button.count(); i++)
{
if(joystick->button.value(i) != joystick->button_last[i])
{
joystick->btnUpdateEmit(i);
// qDebug() << "BUTTON: " << i << "\tVALUE: " << joystick->button.value(i);
}
joystick->button_last[i] = joystick->button.value(i);
}
}
usleep(2500);
}
}
导致程序崩溃的函数在 linkcontrol.cpp
中void LinkControl::on_actionJoystick_Test_triggered()
{
qDebug() << "STARTING CHECK";
if(!js_test->initialized) {
qDebug() << "NOT INIT";
js_test = new TestJoystick();
js_test->initialized = true;
qDebug() << "FININSH INIT";
}
if(joystick->connected) {
qDebug() << "SHOWING UI";
js_test->show();
} else {
QMessageBox::critical(this, tr("No Joystick Connected!"), tr("Please connect a joystick first..."));
}
}
js_test 在 linkcontrol.h 文件中声明为 TestJoystick 对象
public:
explicit LinkControl(QWidget *parent = 0);
QSlider *portSliders[16];
QLineEdit *setVals[16];
SerialTerminal *ser_term;
TestJoystick *js_test;
~LinkControl();
非常感谢!如果您需要更多信息,请告诉我。
答案 0 :(得分:0)
QThread
对于最初习惯来说有点棘手,并且有一些困难。
您应该在运行功能的顶部构建和连接适当的项目。
如果您在其他地方执行此操作,则需要确保不使用Qt::AutoConnection
,而是使用Qt:QueuedConnection
。
http://qt-project.org/doc/qt-5/qt.html#ConnectionType-enum
某些元素只能从&#34; GUI&#34;线程或程序的主线程。这是QApplication::exec();
运行的线程。它有一个传播消息的事件循环。
查看应用程序输出,了解Qt将告诉您的运行时错误。
跨越线程边界时,请务必使用信号和插槽。
如果您从该线程外部访问线程类的成员,请务必使用线程同步和实践,例如使用QMutexLocker locker(m_mutex);
为这些成员添加所有访问权限。
http://qt-project.org/doc/qt-5/threads.html
正如标题&#34; GUI线程&#34;所暗示的那样,它是唯一允许执行某些操作的线程,例如绘制QPixmap
和访问QWidget
的某些部分第
希望有所帮助。