QtCreator C ++ создает поток в главном окне - PullRequest
0 голосов
/ 14 ноября 2018

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

Так что каким-то образом мне нужно определить поток и запустить его в начале создания UserInterface, и этот поток должен затем опросить функцию на предмет новых данных. Я исследовал вопрос о создании потока и подключении его к функции обратного вызова, но он всегда связан с созданием класса, который наследуется от QThread, что я не могу сделать для основного пользовательского интерфейса.

Как мне определить поток внутри основного интерфейса, который я могу затем использовать для опроса функции?

Редактировать: Как рекомендуется, поток здесь не нужен, но я не знаю, как вызвать функцию внутри класса без объекта. В классе mainWindow, где находятся все элементы пользовательского интерфейса, такие как метки и кнопки, я создал объект для последовательной связи. Внутри этого объекта прерывание вызывается при получении новых данных. Так, например, я могу поставить эти данные в очередь в этом последовательном объекте, но все же мне нужно как-то их переслать.

Edit2: Первый метод, который фактически работает, - реализовать таймер, который периодически вызывает функцию обновления. Но так как последовательный rx управляется прерыванием, должен быть способ обратного вызова, такой, что мне не нужно опрашивать его.

1 Ответ

0 голосов
/ 14 ноября 2018

Как обсуждалось в комментариях, в этом случае предпочтительнее не использовать многопоточность, а использовать цикл событий Qt и механизм слотов сигналов. Вот скелет классов MainWindow и SerialReciver, и как они соединены вместе в main.cpp. Для простоты класс SerialReceiver просто излучает сигнал каждую секунду с текущим временем, которое будет добавлено к содержимому поля редактирования в главном окне.

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPlainTextEdit>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void onSerialMessage(const QString &msg);
private:
    QPlainTextEdit mTextField;

};

mainwindow.cpp:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    mTextField.setReadOnly(true);
    setCentralWidget(&mTextField);
}

MainWindow::~MainWindow()
{

}
void
MainWindow::onSerialMessage(const QString &msg)
{
    mTextField.appendPlainText(msg);
}
#endif // MAINWINDOW_H

serialreceiver.h:

#ifndef SERIALRECEIVER_H
#define SERIALRECEIVER_H

#include <QObject>
#include <QTimer>

class SerialReceiver : public QObject
{
    Q_OBJECT
public:
    explicit SerialReceiver(QObject *parent = nullptr);

signals:
    void newMsg(const QString &msg);


public slots:
    void onSerialReceived();
private:
    QTimer mTimer;
};

#endif // SERIALRECEIVER_H

serialreceiver.cpp:

#include "serialreceiver.h"
#include <QDateTime>

SerialReceiver::SerialReceiver(QObject *parent) : QObject(parent)
{
    mTimer.setInterval(1000);
    mTimer.setSingleShot(false);
    connect(&mTimer, &QTimer::timeout,this,&SerialReceiver::onSerialReceived);
    mTimer.start();
}
void
SerialReceiver::onSerialReceived()
{
    QDateTime now = QDateTime::currentDateTime();
    emit newMsg(now.toString());
}

и main.cpp:

#include "mainwindow.h"
#include "serialreceiver.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    SerialReceiver receiver;
    MainWindow w;
    QObject::connect(&receiver, &SerialReceiver::newMsg,
            &w,&MainWindow::onSerialMessage);
    w.show();
    return a.exec();
}
...