Я пытаюсь сделать Collaborative Editor (я должен использовать сетевые библиотеки Linux для всех сетевых вещей), у меня есть основной виджет (пользовательский класс, который наследует QWidget) со всеми компонентами. В конструкторе я создаю все виджеты на этом главном виджете и в конце пытаюсь создать новый поток, используя QFuture (вместо QThread я использую QFuture, потому что он позволяет мне легко вызывать функции с параметрами любого типа, такими как QTextEdit, QTextCursor ...) но это дает мне эту ошибку при компиляции:
"QObject: Невозможно создать дочерние элементы для родителя, который находится в другом потоке.
(Родитель - QTextDocument (0x1b064b0), родительский поток - QThread (0x1985750), текущий поток - QThread (0x1ae7610) ".
Как решить ошибку?
Вот мой код:
mainwindow.h:
...//includes
using namespace QtConcurrent;
...
namespace Ui {
class Widget;
class TextEdit;
}
class TextEdit;
class Widget;
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
...
QFuture<void> thread;
}
class TextEdit : public QTextEdit {
Q_OBJECT
...
}
static void receiveKeyPress(TextEdit *textedit, QTextCursor *secondUserCursor) {
unsigned long long int Number = NULL;
QMessageBox::information(textedit->parentWidget(), "UI Component", "This makes the thread to throw the error");
while(1) if(connected == 1) {
read(recvFileDescriptor, &Number, sizeof(unsigned long long int));
if( Number != NULL)
if( Number == Qt::Key_Home )
secondUserCursor->movePosition(QTextCursor::StartOfLine);
...
else {
QTextCharFormat backgroundFormat = textedit->textCursor().charFormat();
backgroundFormat.setBackground(QColor("lightGreen"));
//If I don't use QMessageBox up there, it breaks here on the next command
secondUserCursor->setCharFormat(backgroundFormat);
secondUserCursor->setPosition(textedit->textCursor().position());
secondUserCursor->insertText(QString::number(Number));
} //else
}//while
}//the function
И mainwindow.cpp:
#include "mainwindow.h"
Widget::Widget(QWidget *parent) {
...
thread = run(receiveKeyPress, this->edit1, this->edit1->secondUserCursor); //run is from QtConcurrent namespace
}
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget window;
...
window.show();
return a.exec();
}
Я читал здесь о стековерсии, как другие используют QObject (который я никогда не использовал, и я не понимаю его) и QThread (единственная комбинация), но я уже пытался использовать QThread и не смог передать QTextEdit и QTextCursor к нему.
Заранее спасибо
Edit:
mainwindow.h
class TextEdit : public QTextEdit {
Q_OBJECT
...
public slots:
void receiveKeyPress(qulonglong);
...
};
mainwindow.cpp
void TextEdit::receiveKeyPress(qulonglong Number) {
if( Number == Qt::Key_Home )
...
}
recv-thread.h - создано по этой ссылке http://developer.qt.nokia.com/doc/qt-4.8/thread-basics.html#example-3-clock
#include <QThread>
#include "mainwindow.h" //To get TextEdit in here
class RecvThread : public QThread {
Q_OBJECT
signals:
void transferDataToSlot(qulonglong Data);
protected:
void run();
};
RECV-thread.cpp
#include "recv-thread.h"
void RecvThread::run() {
unsigned long long int Number = NULL;
while(1) if(connected == 1) {
read(recvFileDescriptor, &Number, sizeof(unsigned long long int));
if( Number != NULL) {
emit transferDataToSlot(Number);
}
}
}
main.cpp
...
#include "recv-thread.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget window;
RecvThread recvThread;
...
QObject::connect(&recvThread, SIGNAL(transferDataToSlot(qulonglong)), window.edit1, SLOT(receiveKeyPress(qulonglong)), Qt::QueuedConnection); //line 38
recvThread.start();
//Displaying the window
window.show();
a.exec();
recvThread.quit();
recvThread.wait();
return 0;
}
Я правильно делаю?