From 99dd4898ac3b4215fe7d861e28582c025a2205fa Mon Sep 17 00:00:00 2001 From: Konrad Rosenbaum Date: Mon, 25 Feb 2013 20:29:24 +0100 Subject: [PATCH] poke thread --- LIESMICH.txt | 29 +++++++++++++++++++++++++++++ main/main.cpp | 12 +++++++++++- main/main.h | 5 +++++ main/thready.cpp | 16 +++++++++++++++- main/thready.h | 9 ++++++++- 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/LIESMICH.txt b/LIESMICH.txt index b2e262e..7bc4362 100644 --- a/LIESMICH.txt +++ b/LIESMICH.txt @@ -150,3 +150,32 @@ liegt in einer DLL/so. (Das mache ich zum Beispiel in einem Projekt auf Arbeit so.) Im Beispiel ist die Funktions-DLL in base und die Plugins in dylib*. + +Die getthingy Funktion in den Libs implementiert übrigens das "Factory-Pattern". +Ja, so einfach können Buzzwords aussehen... ;-) + +Thread und Proxy +----------------- + +Siehe main/thready.* + +Das Thread-Objekt ist so einfach wie möglich: nur eine Startroutine, die +alle nötigen Parameter übernimmt und ein run(), welches das eigentliche +Task-Objekt instantiiert. + +Die MyThread-Klasse ist dabei eine sog. Fasade oder ein Proxy. Die Arbeit +wird von MyTask gemacht. Damit lässt sich in diesem Fall auch garantieren +dass alle wichtigen Slots im richtigen Thread sind. + +Eine andere Variante den Thread zu implementieren, wäre den Konstruktor +public zu machen, noch 0-viele setter für weitere Parameter und dann +wird start()/run() aufgerufen... + +Wenn mit dem Thread kommuniziert werden muss dann benutzt man Signal-Slot- +Kaskaden, siehe disruptThread()... + +QPointer +-------- + +...ist sehr praktisch wenn man ein QObject nicht besitzt oder es sich +unvermittelt löschen kann. So wie unser Thread. \ No newline at end of file diff --git a/main/main.cpp b/main/main.cpp index f462e62..3417b22 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -33,6 +33,8 @@ MainWin::MainWin() vl->addSpacing(10); vl->addWidget(p=new QPushButton("Start Thread")); connect(p,SIGNAL(clicked(bool)),this,SLOT(startThread())); + vl->addWidget(p=new QPushButton("Poke Thread")); + connect(p,SIGNAL(clicked(bool)),this,SLOT(pokeThread())); } @@ -88,7 +90,15 @@ void MainWin::loadLib2() void MainWin::startThread() { //start a thread and let it update the label automatically - MyThread::startMe(mthingylabel,SLOT(setText(QString))); + mthread=MyThread::startMe(mthingylabel,SLOT(setText(QString))); +} + +void MainWin::pokeThread() +{ + if(mthread.isNull()) + mthingylabel->setText("Sorry, cannot poke a null thread"); + else + mthread->disruptThread(); } diff --git a/main/main.h b/main/main.h index fc52e19..8bec118 100644 --- a/main/main.h +++ b/main/main.h @@ -3,7 +3,9 @@ #include #include "../base/thingy.h" +#include +class MyThread; class QLabel; class QLibrary; @@ -23,6 +25,8 @@ class MainWin:public QDialog void unloadLib(); ///starts a thread to do stuff in the background void startThread(); + ///does funny things with the thread + void pokeThread(); ///call that thingy from one of those libraries void callThingy(); @@ -33,6 +37,7 @@ class MainWin:public QDialog QLibrary*mthinglib; //the thingy from that library Thingy*mthingy; + QPointermthread; }; #endif \ No newline at end of file diff --git a/main/thready.cpp b/main/thready.cpp index 0683aef..58beffb 100644 --- a/main/thready.cpp +++ b/main/thready.cpp @@ -1,12 +1,13 @@ #include "thready.h" #include -void MyThread::startMe(QObject* c, const char* s) +MyThread* MyThread::startMe(QObject* c, const char* s) { //create thread and remember connection to the outside world MyThread *m=new MyThread(c,s); //start it m->start(); + return m; } MyThread::MyThread(QObject* callee, const char* slot): QThread(callee) @@ -33,6 +34,8 @@ void MyThread::run() //make sure it deletes itself // Qt::AutoConnection effectively: Qt::DirectConnection - same object connect(this,SIGNAL(finished()),this,SLOT(deleteLater())); + //initiate cascade + connect(this,SIGNAL(disruptThreadSignal()), &task,SLOT(disruptThread()), Qt::QueuedConnection); //now loop for a while exec(); } @@ -42,3 +45,14 @@ void MyTask::gotime() //simply count up and tell everyone emit updateString(QString("Hello, I'm a thread and can count to %1").arg(ctr++)); } + +void MyThread::disruptThread() +{ + emit disruptThreadSignal(); +} + +void MyTask::disruptThread() +{ + ctr+=1000; + gotime(); +} diff --git a/main/thready.h b/main/thready.h index 5b20600..136dc28 100644 --- a/main/thready.h +++ b/main/thready.h @@ -4,6 +4,7 @@ ///It does not know much about what is done there. class MyThread:public QThread { + Q_OBJECT public: ///not needed, use startMe MyThread()=delete; @@ -11,7 +12,11 @@ class MyThread:public QThread ///start the thread ///\param callee the object that gets the updated information, also owner of the thread object ///\param slot the slot to call for updates, must be SLOT(foo(QString)) or SLOT(foo()) - static void startMe(QObject*callee,const char*slot); + static MyThread* startMe(QObject*callee,const char*slot); + public slots: + void disruptThread(); + signals: + void disruptThreadSignal(); protected: ///internal: creates the thread and remembers who to call MyThread(QObject* callee,const char*slot); @@ -34,6 +39,8 @@ class MyTask:public QObject private slots: ///called to update the thread status void gotime(); + ///called from cascade + void disruptThread(); signals: ///sent to the outside world when the thread has something to say void updateString(QString); -- 1.7.2.5