gpt4 book ai didi

user-interface - 跨线程的Qt信号,一个是GUI线程?

转载 作者:行者123 更新时间:2023-12-03 09:50:38 25 4
gpt4 key购买 nike

在 Qt 中使用 moveToThread 将对象从一个线程移动到另一个线程是什么意思?甚至在使用 moveToThread 之前,一切似乎都在工作,它将对象从一个线程(GUI 线程)移动到另一个线程(工作)并且 Qt:connect 调用对象上的适当插槽。

对象所在的位置、GUI 线程或工作线程有什么区别吗?

编辑:
我做了一个小程序,但我不明白 QThread 是如何与 Signal 和 slot 函数一起工作的,如果您能通过示例解释 moveToThread 的用途,我将不胜感激

#include <QtGui/QApplication>
#include <QPushButton>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QString>
#include "mythread.h"
//GUI calls a thread to do some job and sub update the text box once it is done
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QHBoxLayout * pH = new QHBoxLayout(&w);
QPushButton * pushButton = new QPushButton("asdad");
QLineEdit * lineEdit = new QLineEdit("AAA");
pH->addWidget(pushButton);
pH->addWidget(lineEdit);
w.setLayout(pH);
w.show();
MyThread thread;
qDebug("Thread id %d",(int)QThread::currentThreadId());
QObject::connect(pushButton,SIGNAL(clicked()),&thread,SLOT(callRun())) ;
QObject::connect(&thread,SIGNAL(signalGUI(QString)),lineEdit,SLOT(setText(QString)));
return a.exec();
}

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QMutex>

class MyThread : public QThread
{
Q_OBJECT
public:
MyThread();
public slots:
void callRun();
void run();
signals:
void signalGUI(QString);
private:
QMutex mutex;

};

#endif // MYTHREAD_H


#include "mythread.h"
#include <QDebug>
#include <QString>
#include <QMutexLocker>

MyThread::MyThread()
{
}
void MyThread::callRun()
{

qDebug("in thread");
if(!isRunning())
{
this->start(LowestPriority);
exec();
}
else
{
run();
}

}
void MyThread::run()
{
QMutexLocker fn_scope(&mutex);
static int a = 0;
++a;
qDebug("Thread id inside run %d",(int)QThread::currentThreadId());
this->sleep(3);
static QString number;
QString temp;
number += temp.setNum(a);
emit signalGUI(number);
}

最佳答案

看看Signals and slots across threads .如果您总是使用信号和槽来与工作线程通信,Qt 会在需要时为您处理 moveToThread 并且您使用了正确的连接。

编辑:我猜这篇文章的作者看到了他的问题,因为他在实际创建线程之前在构造函数中调用了 start 。换句话说,不要盲目相信第三方代码。

编辑:为了回应您的评论,请查看 Mandelbrot例如,在 MandelbrotWidget Class Implementation 下标题:

With queued connections, Qt must store a copy of the arguments that were passed to the signal so that it can pass them to the slot later on. Qt knows how to take of copy of many C++ and Qt types, but QImage isn't one of them. We must therefore call the template function qRegisterMetaType() before we can use QImage as parameter in queued connections.



我相信这有点过时了,这里是 valid meta types .由于跨线程的信号和槽使用排队连接,因此在大多数情况下您不必执行 moveToThread 调用。

编辑:
我将尝试用一个类似的例子来解释事情:

我的线程.h:
#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QMutex>

class MyThread : public QThread
{
Q_OBJECT

protected:
virtual void run();

signals:
void signalGUI(QString);
};

#endif // MYTHREAD_H

我的线程.cpp:
#include "mythread.h"
#include <QString>

void MyThread::run()
{
qDebug("Thread id inside run %d",(int)QThread::currentThreadId());
static int run = 0;
QString temp = QString("Run: %1").arg(run++);
qDebug("String address inside run %p", &temp);
emit signalGUI(temp);
}

mylineedit.h
#ifndef MYLINEEDIT_H
#define MYLINEEDIT_H

#include <QLineEdit>

class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit MyLineEdit(QWidget *parent = 0);

public slots:
void setText(const QString &string);

};

#endif // MYLINEEDIT_H

mylineedit.cpp
#include "mylineedit.h"
#include <QThread>

MyLineEdit::MyLineEdit(QWidget *parent) :
QLineEdit(parent)
{
}

void MyLineEdit::setText(const QString &string)
{
qDebug("Thread id inside setText %d",(int)QThread::currentThreadId());
qDebug("String address inside setText %p\n", &string);
QLineEdit::setText(string);
}

主.cpp:
#include <QApplication>
#include <QPushButton>
#include <QHBoxLayout>
#include "mythread.h"
#include "mylineedit.h"

//GUI calls a thread to do some job and sub update the text box once it is done
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QHBoxLayout * pH = new QHBoxLayout(&w);
QPushButton * pushButton = new QPushButton("Run Thread", &w);
MyLineEdit * lineEdit = new MyLineEdit(&w);

pH->addWidget(pushButton);
pH->addWidget(lineEdit);
w.show();

MyThread thread;
qDebug("Thread id %d",(int)QThread::currentThreadId());
QObject::connect(pushButton,SIGNAL(clicked()),&thread,SLOT(start())) ;
QObject::connect(&thread,SIGNAL(signalGUI(const QString&)),lineEdit,SLOT(setText(const QString&)));
return a.exec();
}

单击按钮后的示例输出:

线程 ID 1088110320
线程 id 内运行 1093176208
运行中的字符串地址 0x41288350
setText 内的线程 ID 1088110320
setText 0x974af58 内的字符串地址

如您所见,运行线程与主 GUI 线程不同。此外,即使您传递了对 QString 的 const 引用,由于它跨越了线程边界,因此它会复制它。
强烈鼓励您阅读 Threads and QObject .

关于user-interface - 跨线程的Qt信号,一个是GUI线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2086142/

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