Медленное последовательное соединение останавливает поток QT GUI - PullRequest
1 голос
/ 02 декабря 2010

Я работаю над проектом, в котором мне нужно общаться из моей системы с некоторыми последовательными устройствами RS485. Само соединение работает и находится в отдельном потоке, чем поток 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. Я попытался использовать AutoConnect по умолчанию, который должен быть поставлен в очередь, так как последовательное соединение происходит в другом потоке, но это, похоже, не имеет значения в любом случае с точки зрения этой проблемы. Вот мой класс 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 может быть занято в данный момент, я могу использовать эту очередь в качестве буфера хранения. В основном виджет пользовательского интерфейса будет загружать запрос транзакции в очереди. Если соединение Modbus бездействует, TxQueue передаст его как сигнал к соединению, в противном случае он просто добавит его в очередь. Соединение сообщает TxQueue, когда оно доступно для обработки другой транзакции через сигнал busAvailable.

Почему-то кажется, что TxQueue не может принимать транзакции, которые будут добавлены в очередь, до тех пор, пока объект подключения не завершится.

Я немного поработал с помощью Google и нашел страницу, которая рекомендует делать это в конструкторе вашего подкласса QThread:

QObject::moveToThread(this);

Я сделал это, но когда я запускаю свою программу, ни один из сигналов / слотов, похоже, не срабатывает, поскольку программа не связывается с устройством.

Глядя на это, возможно, мне следует избавиться от своего подкласса Qthread, создать простой Qthread, а затем переместить объект подключения к нему?

Я довольно новичок в C ++ и QT, поэтому я уверен, что в моем подходе есть что-то не совсем подходящее. Буду признателен за любые советы, которые вы, ребята, можете дать.

1 Ответ

0 голосов
/ 02 декабря 2010

QThread следует разделять на подклассы только для того, чтобы расширить поведение потоков.Я думаю, что вы должны прочитать следующую статью, прежде чем пытаться использовать функцию moveToThread: http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

...