How to work with QEvent ??

I tried to transfer information (QString) from the main stream to the next thread through a class inherited from QEvent.

He began to do the example in the book of Max Schlee (Qt5.3), But there I did not even understand the design

public: enum {ProgressType = User + 1}; ProgressEvent() : QEvent((Type)ProgressType) { } 

And when I created the same for myself, she gathered, but did not pass the string,; _; sad

mainwindow.h

 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QCheckBox> #include <QHBoxLayout> #include <QDebug> #include <QThread> #include <QEvent> #include <QCoreApplication> #include <iostream> #include <vector> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT int glob_i ; int glob_flow; int vector_schet; // Π΄Π°Ρ‚Ρ‡ΠΈΠΊ счёта public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void start_sending(bool); // ΠΏΡ€ΠΈΠ½Π°ΠΆΠ°Ρ‚ΠΈΠΈ Π½Π° чСкбокс Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒΡΡ этот слот (ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСний) private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; QThread *thread = new QThread(); QVector<QThread*> vector_thread; QList<QCheckBox*> test_checkbox; // Π²ΠΎΡ‚ Π²Π΅ΠΊΡ‚ΠΎΡ€ QCheckBox *checkBox = new QCheckBox(); // Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π² сСбС чСкбокс QWidget *checkBoxWidget = new QWidget(); // создаём слой с привязкой ΠΊ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Ρƒ QHBoxLayout *layoutCheckBox = new QHBoxLayout(checkBoxWidget); }; class NewsThread: public QThread { Q_OBJECT public slots: void run_NEW(); // ΠΊΠΎΠ΄ выполняСмый Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅ signals: void otprawka (int); }; class StrokaEvent: public QEvent{ public: enum {qwert = User + 1}; StrokaEvent() : QEvent((Type)qwert) { } QString stroka; QString NewStroka(); void setStroka(QString); }; 

mainwindow.cpp

 #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { glob_i=0; glob_flow =0; vector_schet =0; ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { glob_i++; //-- добавляСм Ρ‡Π΅ΠΊ бокс Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ checkBoxWidget = new QWidget(); // создаём Π½ΠΎΠ²Ρ‹ΠΉ qwidget() checkBox = new QCheckBox(); // объявляСм ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ чСкбокс layoutCheckBox = new QHBoxLayout(checkBoxWidget); // создаём слой с привязкой ΠΊ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Ρƒ test_checkbox.append(checkBox); int i =0; connect(checkBox, SIGNAL(toggled(bool)),this, SLOT(start_sending(bool))); // соСдинСниС всСх Ρ‡Π΅ΠΊΠ΅Ρ‚ΠΎΠ² с "дСйствиСм" start_sending checkBox->setText(QString::number(glob_i)); layoutCheckBox->addWidget(checkBox); // УстанавливаСм чСкбокс Π² слой layoutCheckBox->setAlignment(Qt::AlignCenter); // ΠžΡ‚Ρ†Π΅Π½Ρ‚Ρ€ΠΎΠ²Ρ‹Π²Π°Π΅ΠΌ чСкбокс layoutCheckBox->setContentsMargins(0,0,0,0); // УстанавливаСм Π½ΡƒΠ»Π΅Π²Ρ‹Π΅ отступы ui->tW_test->insertRow(ui->tW_test->rowCount());//Π²Π²ΠΎΠ΄ΠΈΠΌ ΠΊΠΎΠ»ΠΈΡ‡ строк (Π²ΠΎΠ·Π²Ρ€Π°Ρ‰ ΠΊΠΎΠ»ΠΈΡ‡ строк) ui->tW_test->setCellWidget(ui->tW_test->rowCount()-1, 1, checkBoxWidget); // добавляСм элСмСнт Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ (строка, столбСц, добавляСмый элСмСнт) } void MainWindow::start_sending(bool Value) { // ΠΊΠΎΠ³Π΄Π° Π½Π°ΠΆΠ°Ρ‚Π° ΠΎΡ‚Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚, ΠΎΡ‚ΠΆΠ°Ρ‚Π° Ρ‚ΠΎ Π½Π΅ ΠΎΡ‚Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ if (Value == true) { NewsThread *two_cl = new NewsThread(); // ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Ρ‚ΠΎΡ€ΠΎΠΉ класс for (int i =0;i < test_checkbox.length();i++ ) { if(test_checkbox[i]->isChecked() ==Value) { glob_flow++; QString strok = "dimasik :3"; StrokaEvent *S_E = new StrokaEvent; S_E->setStroka(strok); connect(test_checkbox[i], SIGNAL(stateChanged(int)), two_cl , SLOT(run_NEW()));// ΠΎΡ‚ ΠΊΠΎΠ³ΠΎ, "рСакция", ΠΊΠΎΠΌΡƒ, "Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅" thread = new QThread(); vector_thread.append(thread); vector_schet++; qDebug() << "vector_schet : " << vector_schet ; two_cl->moveToThread(vector_thread[vector_schet-1]); // отправляСм Π² ΠΏΠΎΡ‚ΠΎΠΊ vector_thread[vector_schet-1]->start(); // Ρ†ΠΈΠΊΠ» ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сообщСния Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅ (Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ) } } } else { qDebug() << "chekbocks:" << " False"; glob_flow--; qDebug() << "vector_schet : " << vector_schet ; vector_thread[vector_schet-1]->exit(); } } void NewsThread::run_NEW() { StrokaEvent *S_E = new StrokaEvent; qDebug() << "run_NEW()"; for(;;){ // Π²Π΅Ρ‡Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» for (int i=0; i<500; i++){ qDebug()<< "Число :" << i <<"Π½ΠΎΠΌΠ΅Ρ€ \"ΠΏΠΎΡ‚ΠΎΠΊΠ°\" :" << S_E->NewStroka(); usleep(100000); } } } QString StrokaEvent::NewStroka() { return stroka; } void StrokaEvent::setStroka(QString str) { stroka = str; } 

    2 answers 2

    To create a new type of QEvent :: Type it is better to use the static method QEvent :: registerEventType (), so that there are no repetitions.

    StrokaEvent needs to be caught in the overridden virtual QObject :: event method.

    You create a new instance and wonder why it is empty:

     void NewsThread::run_NEW() { StrokaEvent *S_E = new StrokaEvent; ... S_E->NewStroka() } 

    I do not know what Schlee wrote there, maybe you misunderstood him? Here is an example of using QEvent to send messages between threads:

    stringEvent.h

     #ifndef STRINGEVENT_H #define STRINGEVENT_H #include <QEvent> #include <QString> class StringEvent : public QEvent { public: StringEvent(const QString &_text); static QEvent::Type type(); const QString &getText() const; private: const QString text; static QEvent::Type m_eventType; }; #endif // STRINGEVENT_H 

    stringEvent.cpp

     #include "stringevent.h" QEvent::Type StringEvent::m_eventType = QEvent::None; StringEvent::StringEvent(const QString &_text): QEvent(StringEvent::type()), text(_text) { } QEvent::Type StringEvent::type() { if (m_eventType == QEvent::None) { int generatedType = QEvent::registerEventType(); m_eventType = static_cast<QEvent::Type>(generatedType); } return m_eventType; } const QString &StringEvent::getText() const { return text; } 

    threadedclass.h

     #ifndef THREADEDCLASS_H #define THREADEDCLASS_H #include <QThread> #include <QDebug> #include "stringevent.h" class ThreadedClass : public QObject { Q_OBJECT public: ThreadedClass(QObject *_parent = nullptr): QObject(_parent) { } public: virtual bool event(QEvent *event) override { if(event->type() == StringEvent::type()) { StringEvent *strEvent = static_cast<StringEvent*>(event); qDebug() << "Handle string | " << strEvent->getText() << " | from thread < " << QThread::currentThread(); } return QObject::event(event); } }; #endif // THREADEDCLASS_H 

    MainWindow.h

     #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "threadedclass.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; ThreadedClass *m_thread; QThread *m_th1; }; #endif // MAINWINDOW_H 

    MainWindow.cpp

     #include "mainwindow.h" #include "ui_mainwindow.h" #include "stringevent.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); m_thread = new ThreadedClass(); m_th1 = new QThread(); m_th1->start(); m_thread->moveToThread(m_th1); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { const QString text = ui->lineEdit->text(); qDebug() << "Try send text string from thread < " << QThread::currentThread(); qApp->postEvent(m_thread, new StringEvent(text)); } 

    After starting the program, entering text into lineEdit and pressing a button, we get the output:

     Try send text string from thread < QThread(0x36db80) Handle string | "test1" | from thread < QThread(0x370938) 

    You have not done the main thing, the transfer of the message. In Qt, this is done in two ways:

    1. synchronously, using the QCoreApplication::sendEvent() function, the message will be processed by the recipient in the body sendEvent() ; in this case, if the recipient is in a different stream, the flow of the sender will be suspended.
    2. Asynchronously, using the QCoreApplication::postEvent() function, the message will only be added to the queue to the recipient, the threads will not pause.