How to change tab while progress bar is being updated in QT - qt

I have a Qwidget with a few tabs. In one of the tabs, after clicking a button, a function starts processing data and updates a progress bar.
I'd like to be able to change tabs while this process is running, currently it does'nt let me do so. Any idea?

(1) You must use a modeless progressdialog insteal of modal one. Practically, the main event loop must get the control to allow user interaction.
http://www.bogotobogo.com/Qt/Qt5_QProgressDialog_Modal_Modeless_QTimer.php
(2) You should put your data processing function to worker thread and invoke a progress dialog update to main UI thread from that. That way your task would not block UI, so you could interact with the window (like changing tab) meanwhile.
Qt also provides means to implement this, you might want to refer to:
QFuture, QtConcurrent::run(): run a task in separate thread.
QFutureWatcher: help monitor the progress of a task running in worker thread.
Example:
http://doc.qt.io/qt-5/qtconcurrent-progressdialog-example.html

Below logic may help you.
You can achieve this by using QThread.
Move the process to a separate thread(assume as worker thread)
So now there will be two thread (1. main thread & 2.worker thread)
Execute the process from worker thread
Use signal & slot mechanism to communicate between the main thread(1) & worker thread(2) (to update GUI and or to do some process)
This logic will stop the application from getting hanged.
Refer this link to know in detail.
You can get the sample application here, which follow the above said logic
Application screen shot :
Start Progress(Thread) : Start the thread and do process
Stop Process (Thread) : Stop the thread

Related

QTcpSocket readyRead() signal emits multiple times

I'm new to Qt and currently learning to code with QTcpServer and QTcpSocket.
My code to process data is like
Myclass()
{
connect(&socket, &QTcpSocket::readyRead, this, &MyClass::processData);
}
void MyClass::processData()
{
/* Process the data which may be time-consuming */
}
Is it the correct way to use the signal like that? As I'm reading the documentation that in the same thread the slot is invoked immediately, which means if my processing work hasn't finished and new data comes, Qt will pause on the current work and enter the processData() again. That is not exactly what I want to do, So should I QueueConnection in the signal/slot connection?
Or could you please provide some good methods that I should adopt in this case?
Qt will not pause your current work when data comes in, it will call processData() only when the event loop is free and waiting for new events.
so, when your application is busy executing your code, the application will appear to be unresponsive, because it can't respond to external events, so processData() won't get called if some data is received on the socket until the current function (that may contain your heavy code) returns, and the control is back in the event loop, that has to process the queued events (these events may contain the received data on the socket, or the user clicks on some QPushButton, etc) .
in short, that's why you always have to make your code as short and optimized as possible, in order not to block the event loop for a long time.
With the event delivery stuck, widgets won't update themselves (QPaintEvent objects will sit in the queue), no further interaction with widgets is possible (for the same reason), timers won't fire and networking communications will slow down and stop. Moreover, many window managers will detect that your application is not handling events any more and tell the user that your application isn't responding. That's why is so important to quickly react to events and return to the event loop as soon as possible!
see https://wiki.qt.io/Threads_Events_QObjects

Qt to update (repaint) textbox while processing

My Qt 4 application can only update the log box area (actually the whole GUI) until a function finishes execution. Is there any way to update the GUI/log box during the execution? Like adding something like QWidget::repaint() or QWidget::update() in the for loop, so the user can see that the GUI is processing, rather than wait until the function finishes and print out the log at once.
You need to occasionally call QCoreApplication::processEvents() during the execution of your function. This will keep the GUI alive and responsive by letting the event loop run.
An alternative is to execute your function in a separate thread. More information on threads in Qt can be found here: http://qt-project.org/doc/qt-4.8/threads.html.

How to update a GUI component in Qt?

I am loading a set of 100 images to a QTableWidget. Since it takes about 4 seconds loading, I want to show a progress bar (customised one) with activity indicators or spinner etc. How could I update the GUI and the progress bar simultaneously, by signals & slots, and after loading the images?
Your event loop is busy with your main task, so it can't process your request. All slots will be called after event loop is free. Your options are:
Move slow processing to another thread. That may be not an option here because you can't interact with Qt's widgets in non-main thread.
Call QApplication::processEvents() each time when you want your GUI changes to apply. This is a common and simple solution. This function will execute your slots (if any calls are sheduled), updates GUI and returns execution flow to you.
A better way to load your images would be using a QThread that emits a signal as it processes the images, and connect that signal to a slot in your main widget, here you'll find a couple of examples

Servlet getParameter

I have a servlet program for counting numbers, I want to control it through an html interface.
by pressing the start button the program must start running and by pressing pause button the servlet program must be paused and by clicking on the restart button it must restart again. by the way i used thread. My problem is that each time I should click one button and send its value to the servlet, and when I'm getting the buttons values inside the servlet a NullPointerException is occur... any help ??
I wouldn't use a Thread for that purpose and in general is not usually a good idea to create threads in servlets.
Say we count one number per millisecond meaning: it will give me the time between one click and another in milliseconds.
One work around could be:
Click on start = save the start time in the session.
click on stop = to get the count we do currentTime-StartTime (saved in session)
Now if you really must use Threads be sure then to create it using another class.
One suggestion might be create a ThreadManager class and store it in the session (use a listener for this) and then start it in that session object.
Even better store the ThreadManager inside the servletContext and have a way to create your thread per session.
To create Threads favor the Executor classes instead of the Thread classes.
Also make sure you stop your threads since having threads created by us inside a web container may prevent it from stoping entirely.
If you provide some code I can help you further.
Good luck, have fun.

QT progress dialog cancel button not highlighted

I have an application which makes use of 20 different classes. The program execution starts in mainwindow. I start a progress dialog. I will make use of different classes for different purposes. After each function call which the execution goes to the particular class and does the required and come back to the mainwindow class, I will update the progress dialog. Now, the issue is the progress dialog freezes when the execution goes away from the mainwindow class. The cancel button is unable to accessed and so, the execution could not be stopped at the required time.
mainclass::mainclass()
{
ProgressDialog->exec();
x->add();
updateProgressDialog();
y->do();
updateProgressDialog();
zz->bring();
updateProgressDialog();
}
// x, y, z are three different classes.
This is how the execution goes. As soon as I enter the function in the main class, I will start the progress dialog. and call functions from different classes. The functions take considerable amount of time. I have invoked a thread to do the execution part, but I am unable to cancel the progress diaolog. I want the program execution to be stopped as and when the cancel button is pressed on the proggress dialog.
Please let me know how to get away with this issue. Hope I am clear here.
Without knowing exactly what calculations are being preformed in your threads its hard to isolate the problem. Maybe this can help: Keeping the GUI Responsive
Excerpt from: Performing Long Operations (by: Witold Wysota)
During long calculations (regardless of any usage of signals and slots) all event processing gets halted. As a result, the GUI is not refreshed, user input is not processed, network activity stops and timers don't fireā€”the application looks like it's frozen and, in fact, the part of it not related to the time-intensive task is frozen.
The functions you are calling are not processing the Qt events loop. You are using a modal progress bar, since you are calling exec(). This means that Qt only gets control at the times where you update the dialog.
The only way that I know of to work around this is to code the dialog as modeless, but you will also have to provide an opportunity for the events loop to process.
This is explained in a fair amount of detail in the Qt docs: QProgressDialog

Resources