带有线程类的Qt信号和插槽

时间:2012-06-10 02:52:25

标签: multithreading qt signals slot

我有一个QWidget TableView类,它显示表格,计算数据等......

在其costructor中,我启动了类的FortuneServer服务器:

FortuneServer::FortuneServer(QObject *parent)
    : QTcpServer(parent)
{
...

此类在FortuneServer :: incomingConnection上启动一个新线程,如下所示:

FortuneThread::FortuneThread(int socketDescriptor, const QString &fortune, QObject     *parent)
: QThread(parent), socketDescriptor(socketDescriptor), text(fortune)
{
}

void FortuneThread::run()
{
    QTcpSocket tcpSocket;
    if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket.error());
        cout<<"socket error"<<endl;
        return;
    }
    tcpSocket.waitForReadyRead(10000);
    // this where sockets opens and waits for incoming data...

我需要做以下事情:

  1. 我需要从客户端连接此线程中的字符串,并在TableView类中使用一些函数来计算另一个字符串并将其返回到此线程并将其发送到客户端。

    < / LI>
  2. 如果我在线程中使用emit,我该如何让线程等待结果?

  3. 这是如何正确完成的?

    TY

2 个答案:

答案 0 :(得分:3)

从网络上的源读取字节时,您可以:

1-使用固定长度的二进制消息。因此,您可以等待读取字节块并执行您需要执行的任何操作。 2-使用基于字符串的协议,该协议使用分隔符来分隔消息。当看到分隔符时,您需要提取新的收入消息。 3-使用内容长度等内容来了解​​已经有多少字节,你应该阅读。

在Qt中,您需要在已调用类中拥有slot。还有来电者类中的signal。当一个新字符串到达​​时(使用任何方法),您只需发出信号,然后通知被调用的类。您必须使用connect()方法将插槽连接到信号。我认为QIODeviceQTcpSocket的父级,它有一个名为readyRead()的信号,它可以在新数据可用时为您提供信号。

永远不要做可能在构造函数中抛出异常的操作。最好用不同的方法从构造函数中创建和启动服务器。

答案 1 :(得分:2)

我认为最好的方法是不启动单独的线程,而是将socketDescriptor int赋予QSocketNotifier对象(类型为QSocketNotifier :: Read)并将QSocketNotifier的activate(int)信号连接到插槽在您的GUI类中。然后,只要字节从网络准备好读取,您的插槽就会在主线程中调用,您可以读取它们并在那里处理它们,而无需处理线程间消息传递或信令或阻塞问题。这样更容易:)