I couldn't find a simple tutorial on how to make a dialog box with decrementing timer. I don't need the timer to be accurate or actually reflect my program's inner timer.
Ended using SetTimer : http://msdn.microsoft.com/en-us/library/ms644906%28VS.85%29.aspx
Thanks!
This countdown timer tutorial doesn't help? Source code is included, and you probably can fit the code to "decrement" the timer, or show time info instead.
Related
I'm attempting to build a program which takes any text file and turns it into a typing test. It has a timer that will display to the screen.
However, I can't figure out how to display the timer while actually running my game instructions. The timer works and displays the elapsed time but displaying the timer is the only thing it will do.
Can anyone give me some pointers of things that might be helpful for solving this problem?
QTimer has a signal timeout() which will be emitted after your interval time is elapsed. A QTimer unless specified as a singleshot runs again and again.
Let's assume you wish to do something every second, you can start a timer with interval 1000 (in msec). You can then connect its timeout signal to a slot. There you can specify how to go about doing stuff.
It's fine to run multiple timers at the same time. Also, for your initial implementation (for displaying the timer); you might want to take a look at QElapsedTimer.
Edit:
I found this example. It might provide you something to look at.
QTimer emits timeout() signal in every time interval specified by you unless it's a 'single-shot' timer.
If you want to display the elapsed time, connect the timeout() signal of your timer object to your slot which will display the time elapsed. Your slot will contain your logic to display whatever you want.
I work in Visual Studio with C++, Windows Form App. I try to paint the button red, wait 3 seconds and then paint it blue.
button1->BackColor = System::Drawing::Color::DarkRed;
Sleep(3000);
button1->BackColor = System::Drawing::Color::CornflowerBlue;
However, Sleep() functions executes before first line (painting red). Program starts from waiting 3 seconds and after time it paints the button blue. It seems like painting red piece of code doesn't have time to execute. Individually, painting red works fine.
I've tried other delay solutions also. Example:
int wait = clock() + 2 * CLOCKS_PER_SEC;
while (clock() < wait) {}
It seems to be an issue in Visual Studio C++, because the Sleep() function have worked perfectly in Code::Blocks console script. Do you have any ideas of solution?
Since Button is also a Window you can Invalidate it before calling Sleep().
what is invalidate,update methods do in VC++
Setting component properties, eg 'button1->BackColor = System::Drawing::Color::DarkRed;' are not trivial assignments. The setter methods generate messages, or sequences of messages, that are posted to the Windows/thread that implement the GUI. Those messages must be handled before the requested property set actions can be considered completed.
If you set a window visual property in an event-handler, and then remove all execution from the thread that manages the window before leaving the event-handler, the messages will not get processed.
Do not wait in a GUI event handler. It's a state-machine for handling messages. Don't stop it.
Thank you for your contribution guys!
Advice about threads was helpful. I've solved this problem with the Refresh() function. It seems like parts of code are handled with different threads which work asynchronous. Refresh() function probably implements waiting for the threads to by synchronised.
In my project, I have a function running while a QProgressDialog shows the progress.
QProgressDialog progress("Saving savegame.dat...", "Abort Save", 0, 3016, this);
progress.setWindowModality(Qt::WindowModal);
//... some loops and other calculations run while I update the progress bar with:
progress.setValue(1000);
All is well until I start another process. (Open a cli program)
QProcess decomBR;
QStringList filePathListBR;
filePathListBR.append("-o");
filePathListBR.append("stuff\\compress.bms");
filePathListBR.append("stuff\\regions\\xbox_chunks\\br");
filePathListBR.append("stuff\\regions\\xbox_chunks\\br");
decomBR.start("stuff\\quickbms.exe", filePathListBR);
decomBR.waitForFinished();
As soon as a process like this is started, the progress bar dialog hides or something and the progress is no longer shown, but the processes still run fine.
Any way to prevent these processes from "closing" the QProgressDialog?
EDIT: So apparently, the dialog isn't closing, it's just the main window is taking priority and "covers" the dialog... if that makes sense. Is there any way to make the dialog maintain display priority?
Thanks for your time :)
I have not tried this, but setWindowFlags(Qt::WindowStaysOnTopHint); may help. Notice that it's a flag, so you'd want to write something like:
progress.setWindowsFlags( progress.getWindowsFlags() | Qt::WindowStaysOnTopHint );
Consider using an assertion to see if it's already set, if so then you can dismiss my answer definitively and add to human knowledge by negation!
I am new to Qt Programming, but I have basic on C++.
I want to update my GUI while it is processing, example:
while (....)
{
do some calculation...
if (condition fulfill)
change the color of label.
}
However, I realise that I failed to get the result I want (update the GUI while processing). The GUI will only update after the while loop.
Why is it so? Anyone can help?
In addition, I wish to "slower" the color change since the processing is too fast and I can't see the animation. Any idea to do it?
Thank you very much!
Clarification:
Actually I wish to update the GUI while I am processing...Meaning that, if I have 100 iteration, after each iteration I wish to update the GUI immediately.
Use a QTimer. This will allow you to control the speed of your animation and keep your UI responsive.
You have to place your processing code to another thread and update the gui, because like this GUI will be waiting for your process to end and will refresh after its end
read more here:
http://www.qtcentre.org/threads/41545-How-to-refresh-GUI-while-heavy-processing-is-ongoing
http://www.qtcentre.org/threads/32416-Update-GUI-from-another-thread
Forcing the Qt GUI to update
You don't necessarily need a thread.
Calling QApplication::processEvents() will process pending events, including any redraws you may have caused during your processing.
If you wish to animate the color to indicate that the system is currently working, you might want to use QApplication::setOverrideCursor to show a waitCursor, or a QProgressDialog instead.
I'm New to QT. I understand that you can force a display refresh, but I've pulled all my hair out trying to figure out how. Here is what I'm specifically trying to do.
I press a button (onClick signal event), which runs code that changes an image (QLabel) on the display, waits for input, and then proceeds by changing a new image (different QLabel). I've tried everything and the display doesn't refresh until the onclick signal event code is complete. Right now, I'm not waiting for user input, I'm using usleep(~500 ms) for testing purposes.
From what I read, QT is event driven meaning that I'm basically creating a bunch of events, that get put in a que, and executed when the (onClick signal event) returns to the (main loop)/(event handler). I don't want to wait until the function is complete, it's going to make programming extremely painful if I have to accomplish this routine entirely based on events.
How can I force the QLabel pixmap to refresh. I've tried everything. Below is all the code I have tried in my onClick signal event handler. (upButton is the name of the QLabel which is a pixmap)
update();
repaint();
ui->upButton->setUpdatesEnabled(TRUE);
update();
repaint();
QPaintEvent paintevent(ui->upButton->childrenRegion());
QPaintEvent * test = &paintevent;
paintEvent(test);
this->changeEvent(test);
ui->upButton->update();
ui->upButton->repaint();
ui->upButton->repaint(ui->upButton->childrenRegion());
repaint();
QApplication::sendPostedEvents();
this->parentWidget()->update();
usleep(100000);
As you can see, I'm just shooting in the dark at this point. I've tried to look at sample code and do all my homework, but I'm lost. Appreciate any help, advice, and or sample code.
I was using sleep to emulate a brief amount of time the computer was waiting for something to happen.
As I stated in my question, I didn't want to use events because it's a whole lot of unnecessary work to accomplish something extremely simply.
Also, the 'event' that needs to take place for the program to continue, is a USB event. Since I'm using an HID class device, there is no way to set an event to happen without a wait loop. USB HID classes don't permit setting interrupts, the OS claims the device.
I managed to get the above to work. I walked through the debugger and noticed the display would refresh before the sleep function. Running the program independently, I got random results with the display refreshing 1% of the time. I got rid of the sleep function, and added some other code in it's place to emulate a delay, and it was fine.
Just for everyone's knowledge, this is possible, it's not forbidden, and it's easy to do with the following:
qApp->processEvents();
qApp is a global external variable in the QApplication header.
Because this USB event is making my flow tricky, I stumbled upon the QWaitCondition Class. I was going to start a process waiting for the USB event. I would wait until the process releases the wait condition for my routine to continue.
But if anyone thinks this is a bad idea, please, speak out. I really do appreciate your feedback PiedPiper and Hostile Fork.
Thank you.
I noticed sometimes when you have multiple layered widgets, or widgets inside of widgets it helps to call their repaint() events.
For example
this->repaint();
this->parentWidget()->repaint();
this->parentWidget()->parentWidget()->repaint();
This is far easier then pushing out any processing to another Thread, or creating additional event handlers.
You shouldn't be waiting for input in your event handler. You need to rethink the logic of your program to use events the way they were intended. All the update() and repaint() calls in your code are unnecessary if you return to the event loop.
If i understood correctly, you have a slot and in this slot, you update the image shown in a QLabel. But you want this change to be displayed before the slot finishes.
If that is the case, issue an update() event, and call qApp->processEvents(). This method processes events that are waiting in the event queue and then returns, therefore this may be what you are after.
PS: an update() may not be necessary at all, i am not sure.