如何在Qt中发出跨线程信号?

2023-11-27

Qt 文档指出信号和槽可以direct, queued and auto.

它还指出,如果拥有插槽的对象“生活”在与拥有信号的对象不同的线程中,则发出此类信号将像发布消息一样 - 信号发出将立即返回,并且将在目标线程的事件循环中调用插槽方法。

不幸的是,文档没有指定“lives”代表什么,也没有可用的示例。我尝试过以下代码:

main.h:

class CThread1 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        msleep( 200 );
        std::cout << "thread 1 started" << std::endl;
        MySignal();
        exec();
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

main.cpp:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & oThread2, SLOT( MySlot() ) );
    oThread1.start();
    oThread2.start();
    oThread1.wait();
    oThread2.wait();
    return a.exec();
}

输出是:

thread 2 started
thread 1 started

MySlot()从未被调用:(。我做错了什么?


您的代码存在很多问题:

  • 就像 Evan 所说的,emit 关键字丢失了
  • 您的所有对象都位于主线程中,只有 run 方法中的代码位于其他线程中,这意味着 MySlot 插槽将在主线程中调用,我不确定这是否是您想要的
  • 你的槽永远不会被调用,因为主事件循环永远不会启动:你对 wait() 的两次调用只会在很长一段时间后超时(并且你可能会在发生这种情况之前杀死你的应用程序),我不认为这也是你想要的,无论如何它们在你的代码中确实没有用。

这段代码很可能会工作(尽管我还没有测试过),并且我认为它可以实现您想要的功能:

class MyObject : public QObject
{
    Q_OBJECT
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

class CThread1 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 1 started" << std::endl;
        int i = 0;
        while(1)
        {
           msleep( 200 );
           i++;
           if(i==1000)
              emit MySignal();
        }
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    MyObject myObject;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & myObject, SLOT( MySlot() ) );
    oThread2.start();
    myObject.moveToThread(&oThread2)
    oThread1.start();
    return a.exec();
}

现在 MyObject 将存在于 thread2 中(感谢 moveToThread)。

MySignal 应该从 thread1 发送(我想我不确定这一点,它可能是从主线程发送的,这并不重要)。

thread1 中不需要事件循环,因为发出信号不需要事件循环。 thread2 中需要一个事件循环(由 exec() 启动)来接收信号。

MySlot 将在 thread2 中被调用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Qt中发出跨线程信号? 的相关文章

随机推荐

  • Chrome DevTools 和扩展程序中的内容脚本之间进行通信

    我已经读过this但它不起作用 我做了很多搜索和实验都无济于事 我正在编写一个 Chrome 扩展 大控制台 目标是为 Chrome 开发者工具构建更好的控制台选项卡 这意味着我想在页面上下文中执行用户输入代码 并访问页面上的 DOM 和其
  • 打开 O_CREAT | Linux 中 NFS 上的 O_EXCL?

    当在 Linux 2 6 内核和 NFSv3 中时open fname O CREAT O EXCL 生效了吗 目前的规范open 2 系统调用文档 http www kernel org doc man pages online page
  • Notepad ++ - 只保留数字

    我有一个包含数字和字符的文本文件 阿拉伯语 像这样 943894 964737 编号 1045051 10653 10653 to this 943894964737 1045051 10653 我想删除除数字之外的所有内容 我在这里查看了
  • 下拉列表中选项的粗体部分

    有没有办法仅将下拉列表选项中的部分文本加粗或者这是不可能的 我知道您可以使用 CSS 设置整个选项的样式 但这不是我想要的 并且选项标签内的 HTML 不会呈现 这是下拉列表项的示例 一些ID 身份证件说明 你不可以做这个 您会发现 那里
  • 从plist中检索数据

    我有一个 plist 里面有一个数组 然后是一组字典元素 如何将数据从 plist 检索到我的数组 如何在一个数组中获取类别名称 Objective C Read plist from bundle and get Root Diction
  • 在客户端定义传输类型

    我需要对 IE 使用 jsonp polling 对 Firefox 使用 xhr polling 所以我 尝试在客户端定义传输类型 如下所示 if Firefox s d d test navigator userAgent test f
  • 在 T 和 UnsafeCell 之间转换是否安全且定义的行为?

    A 最近的问题正在寻找构建自我参照结构的能力 在讨论该问题的可能答案时 一个可能的答案涉及使用UnsafeCell用于内部可变性 然后通过 丢弃 可变性transmute 这是这种想法的实际应用的一个小例子 我对这个例子本身并不很感兴趣 但
  • 查找字符串是否混合大小写的最有效方法

    假设我有很长的字符串 并且我想查看某列是 allLower allUpper 还是混合大小写 例如下面的列 text hello New items iTem12 3nXy 文本将是mixedCase 确定这一点的简单算法可能是 int i
  • WPF 应用程序中的图像显示比在外部查看器中查看时要小

    当我在 WPF 应用程序中显示 JPEG 使用以下代码 时 它显示的大小明显小于在 Windows 图片查看器中以实际大小打开 JPEG 的情况 我在运行时深入研究了 ImageSource 的属性 我的图像具有 DPI 为 219 高度为
  • 如何在 pyinstaller 中添加静态(html、css、js 等)文件以创建独立的 exe 文件?

    我在用着QtWebEngineWidgets QtWebChannel创建 PyQt5 应用程序 它使用 HTML CSS JavaScript 当我们以一般方式运行时 即运行正常 python main py 导入 HTML 如下 cur
  • 如何创建一个支持sql转换的方法?

    我想使用我在查询中创建的方法 因为我需要实现一种特殊类型的过滤器 return manager Clients SelectAll Where cli gt cli Name SatisfyFilter filter Name cli La
  • 录制的视频方向错误

    我在用着mCamera setDisplayOrientation 90 旋转相机 这成功地改变了相机预览 但没有改变实际的 相机 因此录制的视频仍然是横向的 他们有办法做到这一点吗 这可能对你有帮助 mMediaRecorder setO
  • 前向填充 python pandas 数据框中除最后一个值之外的所有值

    我在 pandas 中有一个数据框 其中有几列我想转发填充值 目前我正在做 columns a b c for column in columns df column fillna method ffill inplace True 但是由
  • Timepicker Updatesourcetrigger=propertychanged 不更改值

    我在 Windows 窗体中托管 WPF 用户控件 在 wpf 用户控件中 我使用 wpfToolkit extended 中的时间选择器 如果我使用向上或向下键或仅在文本字段中输入时间 则尽管我使用的是 Updatesourcetrigg
  • python - 增加数组大小并将新元素初始化为零

    我有一个大小为 2 x 2 的数组 我想将大小更改为 3 x 4 A 1 2 2 3 A new 1 2 0 0 2 3 0 0 0 0 0 0 我尝试了 3 个形状 但没有成功 并且追加只能追加行 不能追加列 我不想遍历每一行来添加列 有
  • 如何使用 asp.net 将 .docx 转换为 html?

    Word 2007 将其文档保存为 docx 格式 这实际上是一个 zip 文件 其中包含大量内容 包括带有文档的 xml 文件 我希望能够获取 docx 文件并将其放入我的 asp net Web 应用程序中的文件夹中 并让代码打开 do
  • 检测两个div是否重叠[重复]

    这个问题在这里已经有答案了 可能的重复 jquery如何检测两个div是否接触 我花了很多时间试图弄清楚如何检测两个 div 是否重叠 我尝试了 gamequery 插件并像这样使用它 checkform collision checkfo
  • Android 上运行时的重复视图

    我已经为活动创建了布局文件 在此布局中 我创建了一个带有文本视图和编辑文本的 LinearLayout 现在我想创建额外的 LinearLayout 其外观和包含与原始 LinearLayout 完全相同的视图 但具有不同的文本 我还想在运
  • 批量更新Mongodb中匹配子文档的数组

    我正在 Mongodb 3 6 上运行 以下是我的文档的结构 其中存储产品列表的月度费率信息 id 12345 class com example ProductRates rates productId NumberInt 1234 ra
  • 如何在Qt中发出跨线程信号?

    Qt 文档指出信号和槽可以direct queued and auto 它还指出 如果拥有插槽的对象 生活 在与拥有信号的对象不同的线程中 则发出此类信号将像发布消息一样 信号发出将立即返回 并且将在目标线程的事件循环中调用插槽方法 不幸的