2010-12-02 55 views
1

我正在开发一个项目,我需要从我的系统与某些RS485串行设备进行通信。连接本身起作用,并且处于与QT GUI线程不同的线程中。慢速串行连接冻结QT GUI线程

我试图使用信号/插槽来连接GUI线程到主要工作的串行线程,但每当外部设备需要一点响应我的GUI仍然锁定,直到端口完成,我没有'我无法弄清楚如何解决它。

我开始我的main.cpp的串行线是这样的:

int main(int argc, char* argv[]) 
{ 
    QApplication app(argc, argv); 

    QFile f(":/TS-Controls.qss"); 
    if (f.open(QIODevice::ReadOnly)) { 
     app.setStyleSheet(f.readAll()); 
     f.close(); 
    } 

    for (int i = 0; i < argc; ++i) { 
     if (QString(argv[i]) == QString("-h") || 
      QString(argv[i]) == QString("--help") || 
      QString(argv[i]) == QString("-help")) { 

      qDebug() << "Usage:"; 
      qDebug() << " -embedded : show in fullscreen mode"; 
      qDebug() << " -no-embedded : show in desktop mode"; 
      qDebug() << " -white : Set every background to white for screenshots. "; 

      return 0; 
     } 
    } 
    MainWindow* mainWindow = new MainWindow(); 
    ModbusThread * thread = new ModbusThread("/dev/ttyAM1"); 
    app.connect(thread->m_conn, SIGNAL(transactionComplete(ModbusTransaction)), mainWindow->ref1, SLOT(receiveTransaction(ModbusTransaction)), Qt::DirectConnection); 
    app.connect(thread->m_conn, SIGNAL(busAvailable(bool)), mainWindow->TxQueue, SLOT(busAvailable(bool)), Qt::DirectConnection); 
    app.connect(mainWindow->TxQueue, SIGNAL(elementUnloaded(ModbusTransaction)), thread->m_conn, SLOT(loadTransaction(ModbusTransaction)), Qt::DirectConnection); 

    thread->start(); 

    mainWindow->show(); 
    return app.exec(); 
} 

正如你所看到的,线程对象的类型是ModbusThread是的QThread的子类。你也可能注意到我正在使用Qt :: DirectConnect。我尝试使用默认的自动连接,它应该排队,因为串行的东西正在另一个线程中进行,但是就这个问题而言,它似乎没有任何区别。这里是我ModbusThread类:

#include <QThread> 
#include <modbusconn.h> 
#include <modbustransaction.h> 

#ifndef MODBUSTHREAD_H 
#define MODBUSTHREAD_H 

class ModbusThread : public QThread 
{ 
public: 
    ModbusThread(char * port); 
    ModbusConn * m_conn; 
}; 

#endif // MODBUSTHREAD_H 

#include "modbusthread.h" 

ModbusThread::ModbusThread(char * port) : QThread() 
{ 
    this->m_conn = new ModbusConn(this, port);  
} 

现在你可能想知道什么TxQueue正在做(这是在main.cpp中的信号/槽连接上市,如果你错过了一个对象)。这是ModbusTransaction数据类型的队列类。我的想法是,因为我知道实际的modbus连接可能在给定时间很忙,所以我可以使用这个队列作为保持缓冲区。 UI小部件基本上会在队列中加载一个事务请求。如果modbus连接空闲,TxQueue会将它作为信号传递给连接,否则它只会将其添加到队列中。连接信号TxQueue可用于通过总线可用信号处理另一个事务。

不知何故,似乎TxQueue无法接受要添加到队列的事务,直到连接对象完成。

我已经通过谷歌做了一些侦探,发现一个页面,建议您在QThread的子类的构造做到这一点:

QObject::moveToThread(this); 

我给一个镜头,但是当我运行的我的程序无由于程序没有与设备进行通信,因此信号/插槽似乎被触发。

看着它,也许我应该摆脱我的Qthread子类,创建一个普通的Qthread,然后将连接对象移动到它?

我对C++和QT相当新,所以我确信有一些关于我的方法是有点关闭的。我会很感激你们可以提供的任何建议。

+0

直接连接看起来不正确,当向另一个线程发送信号时需要QueuedConnection。 moveToThread(this)不起作用,只能推,不拉,所有权:thread-> moveToThread(thread)应该是正确的。 – 2010-12-02 08:48:02

回答

0

为了扩展线程行为,QThread应该进行子类化。我想你应该在尝试使用moveToThread函数之前阅读以下文章:http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

+0

我读了你链接的页面,它似乎在说我需要使用一个普通的QThread,然后将我的ModbusConn类移动到它。但是,当我尝试这样做时,我实际上似乎没有与设备进行通信。 – Smcrook 2010-12-02 16:17:26