В общем столкнулся с проблемой, если внешний вид программы сделал в дизайнере qt creator-a, то не получаться сделать несколько потоков и взаимодействовать с GUI интерфейсом. Если внешний вид программы написать "руками" в виде кода, без использования дизайнера qt creator-a то получаеться сделать несколько потоков и взаимодействовать с GUI интерфейсом ))). Но так как у меня проделана большая работа в в дизайнере qt creator-a, то я бы не хотел бы перерисовать все с нуля.
По этому я сделал простейший пример, как я делаю. Хотелось бы услышать конструктивную критику и реальный код как надо делать.
Простейшая программа которая выводит на QspinBox постоянно число из бесконечного цикла.
SimpleGUItwoflow.pro
QT += core gui serialbus widgets concurrent
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = SimpleGUItwoflow
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QThread>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void update_m(int);
public slots:
void RepaintReceivedMessage(int i);
void Receiving_a_Message();
private:
Ui::MainWindow *ui;
};
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// поток приёма данных
QThread *thread = new QThread(); // инициализ класс потока
MyThread_priem *mythread_priem = new MyThread_priem(); // инициализируем второй класс
connect(thread, SIGNAL(started()), this, SLOT(Receiving_a_Message())); // наследуем thread а не от MyMainWindows-a
connect(this,SIGNAL(update_m(int)),this,SLOT(RepaintReceivedMessage(int))); // соединение источника данных с приемником
this->moveToThread(thread); // отправляем в поток
thread->start(); // цикл обработки сообщения в потоке0
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Receiving_a_Message()
{
qDebug() << "Receiving_a_Message()";
while (true) {
for (int i =0; i<1000000;i++){
qDebug() << "i: " << i;
emit update_m(i);
}
}
}
void MainWindow::RepaintReceivedMessage(int i)
{
////
qDebug() << "RepaintReceivedMessage()";
ui->spinBox->setValue(i);
}
mainwindow.ui
А вот и результат :
Программа работает но GUI не отвечает. При этом программа не падает.
Исправил код .h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QThread>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
public slots:
void RepaintReceivedMessage(int);
private:
Ui::MainWindow *ui;
};
class MyThread_priem: public QObject{
Q_OBJECT
public:
void Clear_Struct();
private:
signals:
void update_m(int);
public slots:
void Receiving_a_Message();
};
#endif // MAINWINDOW_H
.срр #include "mainwindow.h" #include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// поток приёма данных
QThread *thread = new QThread();
MyThread_priem *mythread_priem = new MyThread_priem();
connect(thread, SIGNAL(started()), mythread_priem, SLOT(Receiving_a_Message()));
connect(mythread_priem, SIGNAL(update_m()), this, SLOT(RepaintReceivedMessage()));
mythread_priem->moveToThread(thread);
thread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MyThread_priem::Receiving_a_Message()
{
qDebug() << "Receiving_a_Message()";
while (true) {
for (int i =0; i<1000000;i++){
qDebug() << "i: " << i;
emit update_m(i);
}
}
}
void MainWindow::RepaintReceivedMessage(int i)
{
////
qDebug() << "RepaintReceivedMessage()";
ui->spinBox->setValue(i);
}
Отправил в отдельный поток, но всё равно он не меняет значения spinBox-а
У Вас не код, а кошмар. Начнём с того, что вот это this->moveToThread(thread);
является рассадником проблем, поэтому this
не надо никогда перемещать в другой поток. Читайте статьи по правильному использованию QThread
, начать можно с You’re doing it wrong….
Ну а конкретная проблема в Вашем коде в том, что у Вас MainWindow
живёт вне UI потока (Вы его сами переместили), и в коде этого окна вызывается ui->spinBox->setValue(i);
, что запрещено делать вне потока UI.
Вот код, всё работает.
.pro не менялся
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QThread>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
public slots:
void RepaintReceivedMessage(int);
private:
Ui::MainWindow *ui;
};
class MyThread_priem: public QObject{
Q_OBJECT
public:
void Clear_Struct();
private:
signals:
void update_m(int);
public slots:
void Receiving_a_Message();
};
#endif // MAINWINDOW_H
.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCheckBox>
#include <QHBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QThread *thread = new QThread();
MyThread_priem *mythread_priem = new MyThread_priem();
connect(thread, SIGNAL(started()), mythread_priem, SLOT(Receiving_a_Message()));
connect(mythread_priem, SIGNAL(update_m(int)), this, SLOT(RepaintReceivedMessage(int)));
mythread_priem->moveToThread(thread); // отправляем в поток
thread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MyThread_priem::Receiving_a_Message()
{
qDebug() << "Receiving_a_Message()";
while (true) {
for (int i =0; i<100000;i++){
qDebug() << "i: " << i;
emit update_m(i);
}
}
}
void MainWindow::RepaintReceivedMessage(int i)
{
qDebug() << "RepaintReceivedMessage()";
ui->spinBox->setValue(i);
}
.ui не менялся
main.cpp не менялся
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Нужна помощь с реализацией задачи на С++, как пишется она на паскале я понял, а вот перевести ее на С++ затрудняюсь, суть программыДан массив...
iconv всегда выдает ошибку EILSEQ с указанием на последний символ, что не так?
Представим что есть интерфейс к БД: