开发者

Slow serial connection freezes QT GUI thread

开发者 https://www.devze.com 2023-01-27 17:51 出处:网络
I\'m working on a project where I need to communicate from my system to some RS485 serial devices. The connection itself works and is in a separate thread than the QT GUI thread.

I'm working on a project where I need to communicate from my system to some RS485 serial devices. The connection itself works and is in a separate thread than the QT GUI thread.

I am trying to use signals/slots to connect the GUI thread to the serial thread which is mostly working but whenever the external device takes a bit to respond my GUI is still locked up until the port is finished and I haven't been able to figure out how to fix it.

I'm starting my serial thread in main.cpp like this:

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();
}

As you can see, the thread object is of type ModbusThread which is a subclass of QThread. Also you may notice I'm using Qt::DirectConnect. I tried using the default AutoConnect which should be queued since the serial stuff is going on in another thread but it doesn't seem to make a difference either way in terms of this problem. Here is my ModbusThread class:

    #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);       
}

Now you may be wondering what TxQueue is doing (it is an object listed in the signal/slot connections in main.cpp if you missed it). That is a queue class for the ModbusTransaction datatype. The idea is that since I know that the actual modbus connection might be busy at a given time I can use this queue as a holding buffer. Basically a UI widget will load a transaction request in the queue. If the modbus connection is idle, TxQueue will pass it along as a signal to the connection otherwise it will just add it to the queue. The connection signals TxQueue when it is available to process another transaction via the busAvailable signal.

Somehow it seems like TxQueue is unable to accept transactions to be added to the queue until the connection object finishes.

I have done some sleuthing via google and found a page that recommended that you do this in the constructor of your QThread subclass:

QObject::moveToThread(this);

I gave that a shot but when I run my program开发者_如何学Go none of the signals/slots seem to be getting triggered since the program isn't communicating with the device.

Looking at it, perhaps I should get rid of my Qthread subclass, create a plain Qthread then move the connection object to it?

I'm fairly new with C++ and QT so I'm sure that there's something about my approach that is a bit off. I'd appreciate any advice you guys can offer.


QThread should be subclassed only to extend threading behavior. I think you should read the following article before trying to use the moveToThread function: http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

0

精彩评论

暂无评论...
验证码 换一张
取 消