2010-10-02 83 views
1

我有一个Qt应用程序,它有两个线程:处理GUI的主线程和管理网络连接的第二个线程。下面是线程代码:为什么从主线程调用槽?

void thread::run() 
{ 
    QTcpServer server; 

    server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect())); 

    //... 
} 

当我把一个断点在OnConnect()开始和调试应用程序,它宣布OnConnect()正在从主线程调用!

我该如何让OnConnect()QTcpServer在同一个线程中运行?

回答

4

为了给出更彻底的答案,请深入探讨信号时隙连接和线程上下文如何相互作用。基本上,对于更多的连接(自动连接),如果发射器和接收器都在相同的线程环境中,则直接调用该插槽,否则将是排队连接,并且插槽将在线程上下文中运行包含插槽的对象。在这种情况下,它必须排队,这意味着你的线程是主应用程序线程上下文的一部分,而不是它自己的线程上下文。这得到了the documentation的强化Qt提供了对其线程的概述,其中指出QThread实例由创建它的线程上下文“拥有”,而不是它所表示的线程上下文。这意味着您有三个主要选择:

  1. 您可以使用moveToThread()将线程移动到其自己的上下文中。请注意,删除线程时可能会导致问题,除非将其移回到将被销毁的上下文中,并且这只能在源线程上下文中完成,因此必须在退出运行函数之前完成。
  2. 您可以将QThread实例视为线程的句柄,而不是将其作为线程本身的一部分。如果您需要在新线程的上下文中完成某些工作,请创建一个不同的对象来处理这些对象,并在新线程的上下文(运行函数内)中对其进行实例化。这是我会推荐的。
  3. 强制直接连接。这意味着您需要确保在插槽中运行的代码是线程安全的,而忽略Qt内置的使这些函数线程安全的方法。 This is what you have done
0

看来问题是我没有通过Qt::DirectConnection作为connect()的最后一个参数。

添加后,它工作。

相关问题