gpt4 book ai didi

c++ - 使用多线程时 Qt Creator 崩溃

转载 作者:行者123 更新时间:2023-12-02 10:29:46 29 4
gpt4 key购买 nike

我正在编写一个 Qt (5.3) 程序,其中有一个操纵杆测试 UI,但我需要一个单独的线程来进行无限 while 循环,通过 SDL 查找操纵杆轴/按钮值的变化。这部分代码工作正常,因为我可以拥有线程 qDebug() 消息,并且它似乎工作正常。但是从主窗口中,当我尝试打开测试操纵杆 UI 时,程序崩溃了。我已经让测试操纵杆 UI 在没有 JoystickThread 线程的情况下运行分离,并且它似乎打开得很好。

尽管错误消息不一致 - 有时,我只是得到

The program has unexpectedly finished. /home/narendran/QtWorkspace/build-LinkControl-Desktop-Debug/LinkControl crashed

这已经出现过一次:

QXcbWindow: Unhandled client message: "_GTK_LOAD_ICONTHEMES"

还有其他几次:

[xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. star: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.

我发现这很常见 if XInitThreads();不在主函数中运行,但即使在那里运行,它也会因相同的错误而崩溃。

ma​​in.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_testlinkcontrol.h 文件中声明为 TestJoystick 对象

public:
explicit LinkControl(QWidget *parent = 0);
QSlider *portSliders[16];
QLineEdit *setVals[16];
SerialTerminal *ser_term;
TestJoystick *js_test;
~LinkControl();

非常感谢!如果您需要更多信息,请告诉我。

最佳答案

QThread 最初有点难以适应,并且也有一些陷阱。

您应该在运行函数的顶部构建并连接适当的项目。

如果您在其他地方执行此操作,则需要确保不使用 Qt::AutoConnection,而是使用 Qt:QueuedConnection

http://qt-project.org/doc/qt-5/qt.html#ConnectionType-enum

某些元素只能从“GUI”线程或程序的主线程访问。这是运行 QApplication::exec(); 的线程。它有一个事件循环来传播消息。

查看应用程序输出中 Qt 会告诉您的运行时错误。

当跨越线程边界时,一定要使用信号和槽。

如果您要从该线程外部访问线程类的成员,请务必使用线程同步实践,例如在对这些成员的所有访问之前使用QMutexLocker locker(m_mutex); .

http://qt-project.org/doc/qt-5/threads.html

正如标题“GUI线程”所暗示的那样,它是唯一允许执行某些操作的线程,例如绘制QPixmap和访问QWidget的某些部分>s.

希望有帮助。

关于c++ - 使用多线程时 Qt Creator 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26195828/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com