ViGOur, спасибо за совет.
Проблема такая: немогу получить доступ к объекту TextEdit главного потока приложения
из дочернего потока.
В то время когда обращаешься к объекту, программа просто "убивается операционкой".
Выкладываю код. Он основан на примере из книги Бланшета, там в разделе 18 как раз разбирают, как использовать объект главного потока.
main.cpp
#include <QApplication>
#include "textwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
TextWindow textWin;
textWin.resize(300, 200);
textWin.show();
return app.exec();
}
textwindow.h
#ifndef TEXTWINDOW_H
#define TEXTWINDOW_H
#include <QMainWindow>
#include <QtGui>
#include "transactionthread.h"
class TextWindow : public QMainWindow
{
Q_OBJECT
public:
TextWindow();
protected:
private slots:
void setTextExample();
void allTransactionsDone();
private:
TransactionThread thread;
QTextEdit *textEdit;
QPushButton *pushButton;
};
#endif
textwindow.cpp
#include <QtGui>
#include "textwindow.h"
TextWindow::TextWindow()
{
textEdit = new QTextEdit;
pushButton = new QPushButton;
setCentralWidget(textEdit);
setMenuWidget(pushButton);
pushButton->setText("Start setText from child thread");
thread.setTextEdit(textEdit);
statusBar()->showMessage(tr("Ready"), 2000);
connect(&thread, SIGNAL(transactionStarted(const QString &)),
statusBar(), SLOT(showMessage(const QString &)));
connect(&thread, SIGNAL(finished()),
this, SLOT(allTransactionsDone()));
connect(pushButton,SIGNAL(clicked()),
this,SLOT(setTextExample()));
}
void TextWindow::setTextExample()
{
thread.addTransaction(new SetTextTransaction());
}
void TextWindow::allTransactionsDone()
{
textEdit->setPlainText(thread.textedit_f()->toPlainText());
statusBar()->showMessage(tr("Ready"), 2000);
}
transactionthread.h
#ifndef TRANSACTIONTHREAD_H
#define TRANSACTIONTHREAD_H
#include <QtGui>
#include <QMutex>
#include <QThread>
#include <QQueue>
class Transaction
{
public:
virtual ~Transaction() { }
virtual QTextEdit* applik(QTextEdit *textEdit_th)=0;
virtual QString message() = 0;
};
class SetTextTransaction : public Transaction
{
public:
SetTextTransaction();
QTextEdit* applik(QTextEdit *textEdit_th);
QString message();
};
class TransactionThread : public QThread
{
Q_OBJECT
public:
void addTransaction(Transaction *transact);
void setTextEdit(QTextEdit *textEdit_th_2);
QTextEdit* textedit_f();
signals:
void transactionStarted(const QString &message);
protected:
void run();
private:
QMutex mutex;
QTextEdit *currentTextEdit;
QQueue<Transaction *> transactions;
};
#endif
transactionthread.cpp
#include <QtGui>
#include "transactionthread.h"
using namespace std;
SetTextTransaction::SetTextTransaction()
{
}
QTextEdit* SetTextTransaction::applik(QTextEdit *textEdit_th)
{
textEdit_th->setPlainText("eto ThreadChild napisal");
return textEdit_th;
}
QString SetTextTransaction::message()
{
return QObject::tr("TredChild pishet v textedit...");
}
void TransactionThread::addTransaction(Transaction *transact)
{
QMutexLocker locker(&mutex);
transactions.enqueue(transact);
if (!isRunning())
start();
}
void TransactionThread::run()
{
Transaction *transact;
forever {
mutex.lock();
if (transactions.isEmpty()) {
mutex.unlock();
break;
}
QTextEdit *oldTextEdit = currentTextEdit;
transact = transactions.dequeue();
mutex.unlock();
emit transactionStarted(transact->message());
QTextEdit *newTextEdit = transact->applik(oldTextEdit);
delete transact;
mutex.lock();
currentTextEdit = newTextEdit;
mutex.unlock();
}
}
void TransactionThread::setTextEdit(QTextEdit *textEdit_th_2)
{
QMutexLocker locker(&mutex);
currentTextEdit = textEdit_th_2;
}
QTextEdit* TransactionThread::textedit_f(){
QMutexLocker locker(&mutex);
return currentTextEdit;
}