Qt GUI non responsive on Windows XP - multithreading

I have a Qt application which gets serial data and displays is in a dashboard type GUI. The basic structure of the program is as follows:
EDIT
SerialPort (Inherits from QIODevice) object get created and have their readyRead signals connected to a slot.
When new data comes in, it's interpreted and sent through the program via a message handler. Eventually the data makes its way to a GUI layer, where it is displayed to the user.
The program runs fine in windows 7, however when I run it on a Panasonic toughbook, running windows XP, the program starts off fine, but after a few moments the GUI stops updating. What I mean by this is that when new data comes in, the gui won't redraw until a user clicks a button or resizes. I'm wondering what are some possible reasons for this type of behavior. I thought it could be that the Main thread was getting overwhelmed by all the serial data coming in, but I think that the GUI runs in a separate thread anyways. Am I wrong? Does anyone have any ideas as to what could be happening?

If SerialPortIO isn't in its own thread, then it might be blocking when it is waiting for new data. I haven't used that particular Serial class, but in general a stream of data probably should be in its own thread.
You can force the program to update the GUI more, by calling qApp->processEvents() periodically, and the GUI should update.
Also, put some qDebug statements in your code, especially at the top of your functions that you suspect that are getting called too frequently or not enough.
Use the following line, and it makes it really easy to follow what is happening in a multithreaded application:
qDebug() << Q_FUNC_INFO;
Hope that helps.

Related

I want to use pyQt5 to design an interactive GUI

Discretion: I would like a general guidance for an approach to a project I am working on, so the question is very broad.
I am currently trying to build a GUI to make serial communication with an arduino, a usb camera (the camera has its own python library for controls), and handle real-time data in .dat format that gets updated as this GUI is running.
Right now, I am using threading on python in order to do all of these simultaneously, and I only interact with the script by using input function on python. Once threads start running, I cannot really interact with this script.
I have 3 separate threads running: 1. thread that saves images from the camera 2. thread that sends signals to arduino in every given random timing. 3. thread that waits for an input to terminate the main thread.
Everything works as I desire, but I wish to add GUI to make things more straight forward for others to use the program.
I realized that Qt actually offers all the capabilities that I wish to implement as a part of this program. Yet, I cannot fully understand the scope of Qt library functions I will need to implement everything.
My understanding is that I could use a combination of QWidgets, QTimer and QThreads to try something, but I would like to have some guidance on a more conventional approach to designing such GUI interface to do multitasking. I would like to also display real-time data on graphs including images from the camera and recording voltage data from the data files that gets updated through another program (data gets written to another folder). The program requires tracking of time from finish to end, and I know that threading can be very confusing when it comes to tracking these times. Any reference will be greatly appreciated.
Thanks you all.

Why does CFileDialog::DoModal() Hang?

I have developed a fairly large C++ program in VS 6.0 on a Win XP platform, and have now migrated to a new machine running Win 7 (still running VS 6.0). The code includes a function to instantiate and run a CFileDialog object to find and open an ASCII file with a specific extension from a specific initial directory. But now, the program hangs on the line
if (t1.DoModal()==IDOK)
...where t1 is the CFileDialog instance.
To investigate why the standard CfileDialog class stopped working, I created a separate test project in VS 6.0 with a simple dialog with one button, containing this code:
void CFileDialogTestDlg::OnOpenFileDialogButton()
{
CFileDialog t1(true);
if(t1.DoModal()==IDOK)
{
CString s3=t1.GetPathName();
MessageBox(s3);
}
}
This test works fine and displays a useable file dialog. I can also duplicate what I want in my large project in terms of initial directory,etc by modifying the m_ofn members of t1.
But putting this code into my large project (ie modifying the relevant button in it) still hangs on the DoModal() line. It seems unproductive trying to trace into a standard MS class, the internals are impossible to understand in a reasonable timeframe.
When I increased stackspace for my test project to match my large project (400MB), I reproduced the hanging behaviour identical to the large project.
Can anyone explain why increasing stackspace should affect file dialog execution in this way, and is there a way around the problem, bearing in mind I need the large stackspace to avoid completely rewriting my project?
I'm not sure the stack is your problem. It's been a while but I seem to recall common modals hanging if you access them from the wrong thread.
Use PostMessage() API to send commands from any thread to the thread that owns the modal dialog. It needs to be the owning (and blocking) thread that ultimately receives the command to accept/cancel the dialog so that it returns from its message pump routine.
If you install the Windows debug symbols, you can see the full call stack of your blocking thread in a debugger.

Provide updates to Qt GUI from sub thread

I know very similar questions have been asked before, but I am unable to find an answer for my specific problem. I have a main (GUI) thread which upon button press initializes a worker thread to perform some analysis. I am using signals and slots to communicate between my worker thread and my GUI thread (i.e. when the thread starts and when it finishes), but I need to go deeper than that. My worker thread actually calls another class in a separate implementation file which then iterates through a series of calculations which are sent to std::cout for each iteration (as the code used to be a console application for which I am now writing a GUI). I am trying to feed those outputs for each iteration back into my GUI thread so that my text browser is updated in real time as my code iterates. The problem is, when I emit a signal from the class my worker thread calls, it is not picked up by the GUI thread. I do not get any errors. Does anyone have any suggestions on how to transmit a signal to the GUI from a class that my worker thread is calling? I can post code as required, but I'm not sure what would be most helpful to see and my code is quite extensive (it's an aircraft performance application). Any help would be greatly appreciated. Thank you kindly!
1) Make sure the connect() call for connecting you signal returns true. If it does not, qdebug output usually tells you what is wrong
2) You should use the QueuedConnection type (the default (Auto) should work also)

Keeping main thread (Qt Application) responsive while some other thread is processing (POSIX)

System / software Details :
Qt Version 4.7.4
Linux
Kernel : 2.6.31 (Custom kernel built for IMX25)
Peripherals :
Graphic LCD (64x128)
Quectel (M 12) GPRS module
Thermal printer
Database : Sqlite3
I am a beginner don't have much experience either in Qt or programming with Linux. I have developed an application where user enter some data manually and that data gets saved in sqlite database. So what I am trying to do is that after certain time lets say 90 seconds data from database should get transferred to the server using the GPRS.
So I am using the Qt's signal and slots mechanism to do the timed data transfer. I have created a slot which gets fired every 90 seconds and as the slot gets fired I am creating/launching a POSIX thread which is suppose to transfer the data to the server.
So what that thread does is it launches the "pppd" and once the "pppd" is up it queries the database for the data and sends the data to the server. And once the data transfer is done I kill the "pppd". The functionality works fine.
But the problem is that the "pppd" takes time to launch so I had to introduce some delay. i.e sleep of 12 seconds is there in order to let the pppd launch successfully. But as the sleep is blocking it makes the main program/thread non responsive until the "pppd" is launched (i.e. it halts/stops all the activities like printing etc.). And as the "pppd" is launched the main thread becomes responsive again.
So please suggest me some solution in order to keep the main thread responsive when "pppd" is launching or please suggest me if there is any other alternative for the same. Also guide me if there's anything wrong with my approach..
Thanks in advance. And I am sorry if I have not followed your standards..
There are several options available to you. It looks like you're using a thread, but then calling sleep in the main thread, which is basically the same as not using thread to do your work at all! You need to leverage Qt processes as illustrated below:
You can use a QProcess in which you start() and use the signal finished() to notify the main thread that it is complete. This is probably what you want to use. All you have to do is:
QProcess *proc = new QProcess;
proc->start("theProcess", QStringList() << "the" << "arguments");
connect(proc, SIGNAL(finished()), this, SLOT(someSlotToUse()));
This sequence of code will start a new process with your arguments, and then call someSlotToUse() when the process is complete.
You can use a QThread along the same pattern.
Basically, what you're trying to do is do the work in another thread, keeping the GUI reactor free to process GUI events rather than long queries. This is a classic problem in Qt and there is a lot of literature out there.
Alternately, you can use a QProcess::concurrent() call, which allows you to run a function in another process, but I've never tested it.
Here are some references for you to look at: Qt Concurrent, QProcess, and QThread

Outputting console data from a process to gui in wxwidgets

I'm running a long process in the background. I've managed to output the console data to gui. But the problem is that, the data is returned only after the process is finished. But I need to display the data at realtime. ie, I need to display the data, every time it produces some output on the console. I'm running the process with in my gui from a seperate thread.
I mean, it would be like building a gui for the ping command, where output is displayed on console after each packet is send, ie at realtime. I just need to redirect that to gui, in realtime. I'm implementing the gui in wxwidgets. Any help would be greatly appreciated.
Thanking You..
Jvc
Is the output you wish to display generated in a separate process from the process running the GUI? Or in a separate thread in the same process?
I ask because most people, when they ask this question, mean a a separate thread. Since you have tagged your question with "process" I will assume that is what you mean.
You need some inter-process communication. There is a bewildering variety of techniques to do this. Personally, I always use sockets.
wxWidgets has simple, easy to use socket classes wxSocketClient and wxSocketServer.
The background process is probably not running wxWidgets, so you will need something else there. I reccomend boost::asio. I know it looks intimidating, but in fact the tutorial code can be used as is.
There is a lot more to be said, but I risk straying away from the point, since there are so few details in your question.
You can have an output queue protected by a wxMutex. The thread doing the computation writes to the queue, then signals the GUI thread using wxQueueEvent with a custom event to let it know that the thread is not empty. The GUI thread then reads the queue and outputs the data.

Resources