Application->Processmessages in QT? - c++

In Borland 6 I often use this to unstuck program action:
Application->Processmessages();
Now, with QT 4.8.1, I don't have found in this foreign (for me) documentation of QT.
Can anyone help me?

In Qt, you'd use the static function QApplication::processEvents().
Alas, your issue is that the design of your code is broken. You should never need to call processEvents simply to "unstuck" things. All of your GUI code should consist of run-to-completion methods that take a short time (on the order of single milliseconds: ~0.001s). If something takes longer, you must split it up into smaller sections and return control to the event loop after processing each section.
Here's an example:
class Worker: public QObject
{
Q_OBJECT
int longWorkCounter;
QTimer workTimer;
public:
Worker() : ... longWorkCounter(0) ... {
connect(workTimer, SIGNAL(timeout()), SLOT(longWork());
}
public slots:
void startLongWork() {
if (! longWorkCounter) {
workTimer.start(0);
}
}
private slots:
void longWork() {
if (longWorkCounter++ < longWorkCount) {
// do a piece of work
} else {
longWorkCounter = 0;
workTimer.stop();
}
}
};
A zero-duration timer is one way of getting your code called each time the event queue is empty.
If you're calling third party blocking library code, then the only (unfortunate) fix is to put those operations into slots in a QObject, and move that QObject to a worker thread.

Related

Qt create a dialog that waits for a network event

I am writing the client for a client/server application. The clients are supposed to login using a login window. If the login is successful, a "waiting" window appears (this is just a window that contains a label). On the server side there is a barrier that waits for n clients to be logged in; when this happens, a message is broadcasted, the waiting window is supposed to close and a new window appears for every client.
The networking interface is implemented by me, using low-level functions, not the functionality provided by Qt.
The actual waiting loop is something like this:
char buffer[256];
while (strcmp(buffer, "proceed"))
read(sockfd, buffer, 256);
The problem is that if I start this loop in the main thread, the application blocks, for obvious reasons.
How can I make this loop run and not block the application, and close the dialog when it ends?
Later edit: I did also attempt to use QThreads, but, for reasons which I don't fully understand yet, the application still crashes:
class WaitLoop : public QThread {
public:
WaitLoop(NetworkHandler &network) : network(network) {}
private :
NetworkHandler &network;
void run() {
this->network.waitForGameStart();
}
};
In the wait dialog constructor:
WaitLoop *waitLoop = new WaitLoop(network);
connect(waitLoop, SIGNAL(finished()), this, SLOT(gameStartSlot()));
waitLoop->start();
The application still crashes using this approach.
The sanest way to approach this would not be using low-level functions, because you aren't writing in C. Use at least QAbstractSocket to wrap a sockfd. The setSocketDescriptor method lets you do it.
Your code then becomes non-blocking and asynchronous:
class Controller : public QObject {
Q_OBJECT
QStateMachine m_sm;
QState s_init{&m_sm}, s_proceeding{&m_sm};
QAbstractSocket m_socket;
Q_SIGNAL void proceed();
Q_SLOT void onData() {
auto data = m_socket.readAll();
if (data.contains("proceed")) proceed();
}
public:
Controller(QObject * parent = 0) : QObject(parent) {
connect(&m_socket, &QIODevice::readyRead, this, &Controller::onData);
s_init.addTransition(this, &Controller::proceed, &s_proceeding);
m_sm.setInitialState(&s_init);
m_sm.start();
}
bool setup(quintptr fd) {
return m_socket.setSocketDescriptor(fd);
}
};
Through the use of a state machine, it's easy to add more states, react to their transitions (see QState::onEntry signal, etc.), and ensure that the behavior is correct. Fleshing out a UML statechart forces you to think about handling corner cases, etc. See this answer for a full example.

Call Qt object method from another std::thread

I have simple Qt form which represents main window of my app. It has method:
void gui_popup::on_pushButton_clicked()
{
QString text = ui->MainText->toPlainText();
text = "1\n" + text;
ui->MainText->setText(text);
}
Also I have some code, running in another thread, created like this:
std:thread* core_thread = new thread(&Init); //void Init()...
Then, at some moment or condition code from std::thread need to call gui_popup::on_pushButton_clicked(). I'm trying to do it like this:
void test_callback(void* object_ptr)
{
auto this_object = (gui_popup*)object_ptr;
this_object->on_pushButton_clicked();
}
In std::thread code I'm saving test_callback pointer and gui_popup object pointer. But when it starts calling on_pushButton_clicked() program halts with segmentation fault error. This code works fine with some other simple classes, but not with QtObject. What am I doing wrong?
UPDATE:
I've solved it this way:
void test_callback(void* object_ptr)
{
QMetaObject qtmo;
qtmo.invokeMethod((gui_popup*)object_ptr, "on_pushButton_clicked");
}
it is, of course, much more complex than using QThread, emitting signals and all other suggested solutions. However thank you everyone for trying to help.
I usually solve it like this:
class Foo : public QObject
{
Q_OBJECT
Foo()
{
// connect to own signal to own slot and hence "translate" it
connect(this, SIGNAL(some_signal(QString)),
this, SLOT(some_slot(QString)));
}
signals:
void some_signal(QString s);
protected slots:
void some_slot(QString s)
{
// do something with your gui
}
public:
void callback_proxy(std::string s)
{
emit some_signal(QString::fromUtf8(m_string.c_str()));
}
};
and then the tread does not need to know about QT:
void thread_run_function(Foo* foo)
{
foo->callback_proxy("Hello from Thread!");
}
As far as I understood this is save because the connect (signal,slot) does have a additional default parameter (Qt::ConnectionType type which defaults to Qt::AutoConnection). This tells QT to dispach signals into the qt main event loop if they originate from a foreign thread. Note that using this connection type essentialy makes qt decide on runtime whether to dispatch the signal or call the slot immediately.
HtH Martin
Edits: Some more info on default parameter and this link as reference:
See http://doc.qt.io/qt-5/qt.html#ConnectionType-enum

How can I provide feedback from a non-Qt C++ library class to a Qt GUI?

I am developing a C++ class library for some computing-intensive tasks (machine vision).
// I am a part of a Qt-agnostic library
class Cruncher
{
/* ... */
public:
void doStuff();
};
Then there's a Qt GUI using that library. I'm creating a worker thread to call the heavy-lifting routines from the library:
// I am a part of a Qt-based GUI which utilizes the library
class Worker : public QThread
{
/* ... */
protected:
virtual void run()
{
/* ... */
Cruncher c;
for (int i = 0; i < count; ++i)
c.doStuff(); // takes some time, and while it's working
// it should communicate status changes which should
// become visible in the GUI
}
};
Now inside doStuff() a lot happens and I want to provide some feedback to the user on what is going on without waiting for doStuff() to return. For one, maybe some finer progress reporting than just increasing the meter by one step after a each call to doStuff(). Also, doStuff() may encounter non-critical failures which let it continue a part of the work, but I'd like a message to appear in the GUI when this happens as Cruncher is working (and Worker is currently busy with a call to doStuff()).
I want the library to remain Qt-independent so I'm not willing to add signals and slots to Cruncher. Any other way to enable it to provide feedback to the GUI to report on its work when it's not a Qt class?
I was considering creating a QTimer which would poll some "status" and "errorMsg" members of Cruncher at fixed intervals while Worker is running, but this seems highly sub-optimal.
I am posting my own answer because though I took #Nim's advice, I'd like the answer to be a little more verbose and hence more useful if someone should have the same problem.
I created the skeleton of a message dispatcher in the library:
// doesn't need to know about Qt
class MessagePort
{
public:
virtual void message(std::string msg) = 0;
};
Next, I added a handle to this object to Cruncher and spiced doStuff() with occasional calls to message():
// now with Super Cow powers!
class Cruncher
{
protected:
MessagePort *msgPort_;
public:
Cruncher(MessagePort *msgPort) : msgPort_(msgPort) {}
void doStuff()
{
while(...)
{
/*...*/
msgPort_->message("Foo caused an overload in Bar!");
}
}
};
Finally, I crafted an implementation of MessagePort inside the GUI using all necessary Qt goodness:
class CruncherMsgCallback : public QObject, public MessagePort
{
Q_OBJECT
public:
CruncherMsgCallback() : QObject(), MessagePort()
{
connect(this, SIGNAL(messageSignal(const QString &)),
GUI, SLOT(messageShow(const QString &)),
Qt::QueuedConnection);
}
virtual void message(std::string msg)
{
emit messageSignal(QString::fromStdString(msg));
}
signals:
void messageSignal(const QString &msg);
};
Finally when the Worker creates an instance of Cruncher, it also gives it a pointer to a working MessagePort:
class Worker
{
protected:
virtual void run()
{
CruncherMsgCallback msgC;
Cruncher c(&msgC); // &msgC works as a pointer to a
// generic MessagePort by upcasting
c.doStuff(); // Cruncher can send messages to the GUI
// from inside doStuff()
}
};
Use a callback function (class) etc, and pass that in during construction. Things you need to report, report via that callback.
You can safely emit signals from the run() method, I think that's the best way to pass information from worker thread to the main thread. Just add the signals to your QThread subclass (avoid adding slots, if you're at all unsure how QThread threading works).
Better make the connections from these signals explicitly queued, to avoid problems. Though the default, automatic connection type should also work and do Queued signal emit, but I think it's better to be explicit in cases like this. Actually also direct signals should work as such, but then you have to take care of thread safety yourself instead of letting Qt handle it for you, and you can't connect to slots which use any of the QtGui classes which only work in the main thread, so it's better to stick to queued connections.
To pass simple information to the run() method, and if immediate reaction is not needed, maybe use a few shared QAtomicInt variables or something like that as flags, which the worker thread checks when convenient. Slightly more complex method, still requiring polling, is to have shared data structure which you protect with mutex. More complex way of communicating to that direction would involve some kind of message queue (just like Qt uses in the event loop of the main thread, when you emit signal to that direction).

crash. QObject::connect in a constructor of a static object instance

I'm trying to find out why my app crashes for the whole day. A picture worth thousands of words, so take a look at this code. Header:
class SandboxedAppStat : public QObject
{
Q_OBJECT
private slots:
void pidsTimerTimeout();
public:
QTimer m_PidsTimer;
SandboxedAppStat(QObject *parent = NULL);
};
class SandboxedApp : public QObject
{
Q_OBJECT
private:
static SandboxedAppStat SandboxedAppStat1;
};
Implementation:
void SandboxedAppStat::pidsTimerTimeout()
{
qDebug() << "whatever";
}
SandboxedAppStat::SandboxedAppStat(QObject *parent)
: QObject(parent)
{
bool b = QObject::connect(&m_PidsTimer, SIGNAL(timeout()),
this, SLOT(pidsTimerTimeout()));
m_PidsTimer.start(500);
}
SandboxedAppStat SandboxedApp::SandboxedAppStat1;
Actually what I'm trying to do, is to simulate static constructor behavior in C++. I want
QObject::connect(&m_PidsTimer, SIGNAL(timeout()),
this, SLOT(pidsTimerTimeout()));
m_PidsTimer.start(500);
to be called as soon as the static member SandboxedAppStat1 initializes. That's why the code shown above is in the constructor of SandboxedAppStat.
However, my problem is that when I run the program, it crashes as soon as it reaches the line connect(&m_PidsTimer, SIGNAL(timeout()), this, SLOT(pidsTimerTimeout()));
with error code c0000005 (access violation I guess).
here's the screenshot http://dl.dropbox.com/u/3055964/Untitled.gif
If I declare SandboxedAppStat as a non static variable, then there is no crash and no errors. everything works fine.
First I thought that crash reason could be the fact that, static members are initialized too early for QObject::connect to be able to be called, that's why I updated SandboxedAppStat constructor with the following code:
auto *t = this;
QtConcurrent::run([&] () {
Sleep(3000);
bool b = QObject::connect(&(t->m_PidsTimer),
SIGNAL(timeout()), t, SLOT(pidsTimerTimeout()));
t->m_PidsTimer.start(500);
});
As you can see, QObject::connect executes after 3 seconds when static SanboxedAppStat is initialized, but this didn't help either, the program crashes after 3 seconds.
I'm really confused, I don't understand what can be the cause of this problem. Can't we use signal/slots in a static object instances?
I'm using Qt 4.8.0 with MSVC 2010. Thanks
UPDATE
Here's a simple project, consisting of only one header and one source file (as HostileFork suggested) to reproduce the crash. http://dl.dropbox.com/u/3055964/untitled1.zip
Are you looking for periodic calling of your pidsTimerTimeout slot or just once during construction?
If you're looking to just receive a signal once your class has been constructed try using QTimer::singleShot or QMetaObject::invokeMethod if you don't require continuous time outs. Like all signals the single shot will only be acted upon once the window system's event queue have been processed which can have a small delay on the execution of your slot.
MyClass::MyClass()
{
// Using a zero singles shot.
QTimer::singleShot( 0, this, SLOT( initialized() ) );
// or using invoke method.
QMetaObject::invokeMethod( this, "initialized", Qt::QueuedConnection );
}
Pretty sure we use this code in the office and we have success with static objects.

Is it possible to implement polling with QThread without subclassing it?

I have a class, which is an abstraction of some device.
class Device
{
public:
...
void Start();
void Stop();
void MsgLoop();
signals:
void sMsgArrived();
}
Start() and Stop() are called from GUI thread. Start() begins new thread, which runs MsgLoop(). It looks like this:
void MsgLoop()
{
forever {
if(SUCCESS == ReadMsg()) //synchronous, non-blocking
{
ProcessMsg(); //quite fast
emit sMsgArrived(); //this signal is connected with a slot in GUI thread
}
}
}
When Stop() is called, program should return from MsgLoop() and stop the thread. How can I implement this with QThread without subclassing it?
Generally you have to decide who will be responsible for managing the thread. Is it the Device or the main window? Or possibly some device manager. In your case the Device should probably manage its own thread, so if you don't want to subclass it, use composition:
class Device : QObject
{
Q_OBJECT
public:
Device(QObject * parent = NULL);
void Start();
void Stop();
private slots:
void MsgLoop();
signals:
void sMsgArrived();
private:
QThread thread;
bool stopThread;
};
Device::Device(QObject * parent) : QObject(parent)
{
moveToThread(&thread);
connect(&thread, SIGNAL(started()), this, SLOT(MsgLoop()));
}
void Device::Start()
{
stopThread = false;
thread.start();
}
void Device::Stop()
{
stopThread = true;
thread.wait(); // if you want synchronous stop
}
void Device::MsgLoop()
{
// your loop
while(!stopThread)
if(SUCCESS == ReadMsg())
{
ProcessMsg();
emit sMsgArrived();
}
QThread::currentThread->quit();
}
NOTE: the thread stopping will only work if ReadMsg really is non-blocking. If you later decide to switch to blocking read (and that would probably be appropriate for most cases), you will have to figure out another way how to stop your thread.
If you look at this link you can see that it is possible to run a method in a separate thread without subclassing a QThread.
However what you are asking is running a message loop forever.
If you follow the given example you can run your loop without subclassing but the QThread object will never enter into its own message loop cause it will never return from your slot. So here is an example but I think it would be a bad design
class Device : public QObject
{
Q_OBJECT
public:
Device(QObject* parent = 0);
~Device();
public Q_SLOTS:
void MsgLoop();
};
QThread* thread = new QThread;
Device* device = new Device;
void Widget::onBtnStartClicked()
{
device->moveToThread(thread);
//This will call start method of Device
connect(thread, SIGNAL(started()), device, SLOT(MsgLoop()));
//This will start the event loop of thread
thread->start();
}
void Widget::onBtnStopClicked()
{
//Tells the thread to exit
thread->exit(0);
}
I am afraid you have to subclass a QThread if you want to run a forever loop.
IMHO you shouldn't. Polling requires being in a forever loop. You must do this in QThread's run function so there is no way to re-implement a function without sub-classing first. Even if you were to try and workaround it with a single shot timer I don't recommend it. You are better off(this is how i like to do it) sub-classing QThread, calling moveToThread(), not call exec() and put a forever loop in run. For an example of this look at the Fortune Blocking Client example from qt. If you don't call moveToThread() on QThread then the QThread object still resides in the GUI main thread and they both share the same event loop (which is bad when using polling functions). Calling moveToThread(QThread) without calling exec() means the QThread will not have an event loop(which is good in your case). Calling exec() would start it's own event loop but is not used for polling schemes and you would leave the run function.