- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有两个线程继承自 QThread。该场景是 thread2 的对象发出信号,而 thread1 的对象有一个要执行的槽。我希望插槽在 thread2 中执行,但它在主线程中执行!!!。这是我的示例代码来表明:
头文件.h
class Thread1 : public QThread{
Q_OBJECT
public:
Thread1(){}
protected:
void run(){
qDebug() << "run in thread " << this->currentThreadId();
exec();
}
private slots:
void slot1(){
qDebug() << "slot in " << this->currentThreadId();
}
signals:
void sig1();
};
class Thread2 : public QThread{
Q_OBJECT
protected:
void run(){
msleep(100);
qDebug() << "emit sig2 in: " << this->currentThreadId();
emit sig2();
}
signals:
void sig2();
};
class obj1 : public QObject {
Q_OBJECT
public:
obj1(){
connect(&t2, SIGNAL(sig2()), &t1, SLOT(slot1()));
connect(this, SIGNAL(sigObj()), &t1, SLOT(slot1()));
t1.start();
t2.start();
}
public:
void fcn(){
QThread::msleep(1000);
emit sigObj();
qDebug() << "emit sigObj in " << QThread::currentThreadId();
}
private:
Thread1 t1;
Thread2 t2;
signals:
void sigObj();
};
main.cpp
QCoreApplication a(argc, argv);
obj1 o1;
o1.fcn();
return a.exec();
我对这段代码的期望是 slot1() 始终在线程 1 中从发出的信号 sig2() 和 sigObj() 中执行。但是无论我们在哪个线程中发出信号,slot1 都在主线程中执行。顺便说一句,这是我的输出:
run in thread 0x7ffff6169700 (thread1)
emit sig2 in: 0x7ffff5968700 (thread2)
slot in 0x7ffff7fce740 (main thread)
emit sigObj in 0x7ffff7fce740 (main thread)
slot in 0x7ffff7fce740 (main thread)
是出了什么问题还是总是这样?还有如果我想在自己的线程中执行槽怎么办?
最佳答案
QThread
没有什么特别之处。它只是一个 QObject
,碰巧 也是平台本地线程的句柄。但是 QThread
派生对象的插槽就像您有一个普通的 QObject
一样工作。它们将在对象的线程中执行——这将是您执行对象构造函数的线程,或者在您的情况下是主线程。这就是令人困惑的地方:您的任何一个线程对象的 thread()
仍然是主线程,这就是槽将运行的地方。仅仅因为您的 QObject
被称为 QThread
并不会使它有任何不同。
修复很简单:不要覆盖QThread
的“运行”,也不要向QThread
添加功能。相反,明确地将您的对象移动到您希望它们完成工作的线程。在 QThread
上显式调用 moveToThread
是一种反模式,因此不要将其作为“快速破解”。
在这种情况下,派生自 QThread
的唯一原因是通过添加 quit(); 将其转换为适当的 RAII 类; wait();
到它的析构函数。
这是您的代码的外观,已修复:
// https://github.com/KubaO/stackoverflown/tree/master/questions/thread-sigslot-37325348
#include <QtCore>
class Worker1 : public QObject {
Q_OBJECT
public:
Q_SIGNAL void sig1();
Q_SLOT void slot1() {
qDebug() << "slot in" << thread();
}
};
class Worker2 : public QObject {
Q_OBJECT
public:
Worker2() {
QTimer::singleShot(100, this, [this]{
qDebug() << "emit sig2 in" << thread();
emit sig2();
});
}
Q_SIGNAL void sig2();
};
class Object : public QObject {
Q_OBJECT
Worker1 w1;
Worker2 w2;
QThread t1, t2;
Q_SIGNAL void sig();
public:
Object() {
t1.setObjectName("t1");
t2.setObjectName("t2");
connect(&w2, &Worker2::sig2, &w1, &Worker1::slot1);
connect(this, &Object::sig, &w1, &Worker1::slot1);
w1.moveToThread(&t1);
w2.moveToThread(&t2);
t1.start();
t2.start();
QTimer::singleShot(1000, this, [this]{
qDebug() << "emit sig in" << thread();
emit sig();
});
}
~Object() { t1.quit(); t2.quit(); t1.wait(); t2.wait(); }
};
int main(int argc, char ** argv) {
QCoreApplication app{argc, argv};
app.thread()->setObjectName("main_thread");
Object obj;
QTimer::singleShot(2000, &app, [&]{ app.quit(); });
return app.exec();
}
#include "main.moc"
输出:
emit sig2 in QThread(0x7fff4fd98bd0, name = "t2")
slot in QThread(0x7fff4fd98bc0, name = "t1")
emit sig in QThread(0x7fe3dac0aed0, name = "main_thread")
slot in QThread(0x7fff4fd98bc0, name = "t1")
关于c++ - 多线程应用程序中的槽执行策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37325348/
我在QPushButton的最后一列中插入了QTableview。使用该按钮,我将使用按钮释放信号和插槽handlebutton(int)删除该特定行。 cpp代码: MainWindow::Main
它编译正常,但这是我运行程序时的错误消息: QObject::connect: Cannot queue arguments of type 'QVector' (Make sure 'QVector
我在 PyQt 中使用 for 循环 连接多个信号/槽。代码如下: # Connect Scan Callbacks for button in ['phase', 'etalon', 'mirror
我正在使用 Qt 创建一个 UI,有两个元素可能存在也可能不存在。此外,他们的 parent 也是不同的元素。但是,一个会影响另一个。 我应该如何以最佳方式构造信号/槽(或者我什至不应该使用该模式)?
我正在为这事兜圈子。就是无法理解信号和插槽。 只是在寻找某种机制,当我的 C++ 中出现信号时可以自动更新我的 UI。 示例: 我在 Qml 中有两个带有文本的标签:返回值的 _app.method。
我有两条路线呈现相同的组件,但来自 API 的数据不同。 该组件有一个名为 的子组件有一个 v-if检查特定插槽是否有内容的指令(因为如果它没有内容,我不希望该插槽显示)。 但是,在同一个父组件上可
我只是问当我的 html 位于 java-script 变量而不是 DOM 本身时如何使用 .each。 如果我有这样的 html: deze this dies 我能做到
基本上,想象一个宽度为 9(从 0 开始)的基于位置的区域 ╔════╦════╦════╦════╦════╦════╦════╦════╦════╗ ║ 0 ║ 1 ║ 2 ║ 3 ║
我想做一些非常简单的事情。单击切换按钮并在 QT 中获取消息框。 cpp: _show_hide_password = new QPushButton( "abc" ); _show_hide_pas
我有一个关于信号和槽的问题。在我的应用程序中,我想将来自一个对象的信号连接到 textEdit在对话框窗口中。我的信号发出 QString ;如果我违反封装(通过将 UI 公开而不是私有(privat
你好我来自java阵营,正在尝试做一个c++程序 我有一个名为 Manifest 的数组,它接收乘客对象 for (int i = 0; i Manifest . 例如 #include #incl
似乎为 Signal 类和插槽中调用的内容提供安全跨线程信号的唯一实现是 QT。 (也许我错了?)。 但是我不能在我做的项目中使用QT。那么我怎样才能从不同的线程(例如使用 Boost::signal
我将直接从示例开始: 在游戏中,有一个袋子供玩家用来存放他们的元素(元素的大小不一),袋子的大小也是可变的。 在一个 8x15 插槽的袋子中,我需要插入一个占用 2x2 插槽的元素,我可以搜索空间来实
PyQt 按钮事件可以以正常方式连接到函数,以便函数接收默认信号参数(在本例中为按钮选中状态): def connections(self): my_button.clicked.connec
访问类槽时,而不是写入 (defmethod get-name ((somebody person) (slot-value somebody 'name)) 是否可以使用点符号(又名 C++),即
我正在使用 vee-validate v3.0 进行验证并且设置很顺利,但现在我正在尝试设置我的元素的样式,但我似乎无法让它工作。我遵循了关于样式的非常简短的文档并编辑了 vee-validate 配
我尝试使用来自 https://wiki.qt.io/QThreads_general_usage 的方法与 moveToThread。一切安好。但是,如果我尝试将参数添加到完成的信号中,则会出现以下
我刚刚使用 iAds 和 adMob 在我的应用程序中实现了 adWhirl。一切都编译正确,adMob 工作完美,但我的 iAd 大小不正确。广告看起来尺寸合适,但实际上似乎被剪掉了。大约 1/4
我正在使用 python 和 PySide 开发 GUI 应用程序。我需要在单独的线程中运行长时间的背景任务。对于线程,我决定根据“正确”的方法使用 QThread,而不是从 if 进行子类化(参见
在用于编写 GUI 代码的 Qt 的 QML 语言中,QML 元素(如果我理解正确的话)在它们变得可见之前不会被实际创建。 (编辑: 听起来这些元素是在 QML 引擎加载它们时创建的,但看起来信号/槽
我是一名优秀的程序员,十分优秀!