Страницы

Поиск по вопросам

вторник, 11 июня 2019 г.

Изменение текстового поля на форме из потока (2 окна) QML QT C++

Пытаюсь изменить значение текстового поля из другого потока, но почему-то не работает: Есть 2 окна, первое окно:
firstwindow.h:
#include "mythread.h" #include
class FirstWindow : public QObject { Q_OBJECT public: explicit FirstWindow(QObject *parent = nullptr); private: MyThread *myThread; public slots: void start(); };
firstwindow.cpp:
#include "firstwindow.h"
FirstWindow::FirstWindow(QObject *parent) : QObject(parent) {
}
void FirstWindow::start() { myThread = new MyThread(5); //передача значения в класс MyThread }
firstwindow.qml:
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import QtQuick.Window 2.0
import FirstWindowModule 1.0
ApplicationWindow { visible: true width: 380 height: 240 id: firstwindow
FirstWindow { id: obj; }
//создание и вызов второго окна, вызов функции start(), создающей объект класса MyThread Button { text: "Start" onClicked: {
var component = Qt.createComponent("main.qml"); console.log("Component Status:", component.status, component.errorString()); var window = component.createObject(firstwindow); window.show()
obj.start(); } } }
Второе окно:
mythread.h:
#include "newclass.h" #include #include
class MyThread : public QObject { Q_OBJECT Q_PROPERTY(QString firstNumber READ GetFirstNumber WRITE SetFirstNumber NOTIFY firstNumberChanged)
private: QThread *thread; NewClass *newClass; QString firstNumber; int counter;
private slots: void UpdateFirstValue (int i); public slots: void StartThread(int); public: explicit MyThread(int value, QObject *parent = nullptr); explicit MyThread(QObject *parent = nullptr); QString GetFirstNumber(); void SetFirstNumber(QString);
signals: void firstNumberChanged(); };
mythread.cpp:
#include "mythread.h"
MyThread::MyThread(QObject *parent) : QObject(parent) { }
MyThread::MyThread(int counter, QObject *parent) : QObject(parent) { this->counter = counter; StartThread(counter); //запуск функции создания и запуска потока }
QString MyThread::GetFirstNumber() { return firstNumber; }
void MyThread::SetFirstNumber(QString value) { firstNumber = value; }
void MyThread::StartThread(int counter) { thread = new QThread; newClass = new NewClass(counter); newClass->moveToThread(thread);
connect(newClass, SIGNAL(sendfirstvalue(int)), this, SLOT(UpdateFirstValue(int))); connect(thread, SIGNAL(started()), newClass, SLOT(Start())); thread->start(); }
void MyThread::UpdateFirstValue (int i) { firstNumber = QString::number(i); emit firstNumberChanged(); }
main.qml:
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import QtQuick.Window 2.0
import NameModule 1.0
ApplicationWindow { visible: true width: 380 height: 240
Rectangle { id: content
TypeName { id: obj }
ColumnLayout { height: parent.height anchors.horizontalCenter: content.horizontalCenter Rectangle { Layout.fillHeight: true Text { anchors.centerIn: parent id: firstNumber text: "f = " + obj.firstNumber font.bold: true
onTextChanged: { console.log("firstNumberChanged"); }
} } } } }
Класс NewClass, функция которого работает в потоке:
newclass.h:
#include
class NewClass : public QObject { Q_OBJECT
public: explicit NewClass(int value, QObject *parent = nullptr); signals: void sendfirstvalue(int); private slots: void Start(); private: int value; };
newclass.cpp:
#include "newclass.h" #include #include "QDebug"
NewClass::NewClass(int value, QObject *parent) : QObject(parent) { this->value = value; }
void NewClass::Start() { qDebug() << "value" << value; for(int i = 0; i < value; i++) { qDebug() << "i" << i; emit sendfirstvalue(i); Sleep(1000); // from windows.h } }
Связка классов FirstWindow и MyThread с соответствующими им qml:
qmlRegisterType("FirstWindowModule", 1, 0, "FirstWindow"); qmlRegisterType("NameModule", 1, 0, "TypeName");
Суть проблемы: 2 окна, в первом окне (FirstWindow) располагается кнопка, по которой открывается второе окно (MyThread), и сразу запускается вычислительный процесс в новом потоке (функция Start() в классе NewClass. Данная функция в цикле, каждую секунду отсылает целочисленное значение обратно во второе окно MyThread, и данное значение должно отображаться в данном окне. Установлено, что проблема скорее всего в создании этого второго окна, что либо поток запускается раньше, чем показывается окно, либо еще что-то. Спасибо.
UPDATE: заново переписал вопрос и залил проект на https://github.com/sawyerhard/test2, Проблема не решена


Ответ

Проблема решена) В общем вся проблема была в этих 2х строчках в файле firstwindow.qml:
var window = component.createObject(firstwindow);
и вызов функции
obj.start();
при котором происходило повторное!!! создание объекта myThread, так как основной объект создавался в строчке выше (так как окно связано с MyThread классом), из-за этого данные, которые хоть и приходили, но не отображались в окне.
Решение: 1. Убираем строчку из firstwindow.qml:
obj.start();
2. Добавляем метод onCompleted в файл main.qml, в котором запускаем выполнение потока:
Component.onCompleted: { obj.startThread(5); }
Всем спасибо)

Комментариев нет:

Отправить комментарий