Пытаюсь изменить значение текстового поля из другого потока, но почему-то не работает:
Есть 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
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
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
Суть проблемы: 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);
}
Всем спасибо)
Комментариев нет:
Отправить комментарий