I have my own application in QT.It has one main GUI thread which will handling the event from the inputs but i have created one thread that will applicable to change images every 10 seconds (just like slideshow or screen saver). but when i call function setPixmap from thread then it gives me warning that it's not safe to use Pixmap from thread.
what is the solution ?. why i don't use setPixmap from thread ?
Thanks,
Neel
The why, is because that function is not thread safe.
The solution, is to use a QTimer to run your function every 10 seconds. QTimer is integrated in the Qt Event Loop, so you don't need another thread to do it.
I don't have an actual answer to this but I know that setPixmap() should only be called from the main GUI thread. I found this mailing list post from a few years back that also points to trolltechs docs. Reading through the thing quickly leads me to think that it has something to do with how different platforms render stuff and so on.
http://lists.trolltech.com/qt-interest/2008-11/thread00534-0.html
http://doc.trolltech.com/4.4/threads.html#painting-in-threads
Instead of having your worker thread call setPixmap(), have it emit a signal (something like newImagesReady()).
Then, connect that signal to your widget's update() slot. (Or make your own slot if you want to do more than refresh the widget).
This technique lets you cross thread boundaries.
Related
I'm looking for a documentation about the things that happen after/while calling the quit() of a Qt application. The question stems from a problem that I had with handling return values of open QDialogs on quit(). I would like to clarify the following sequence:
QCoreApplication::quit() or QApplication::quit() is called
QWidget::closeEvent() is not called for QDialogs. It seems that all open dialogs are automatically closed by calling their reject() method. This is the most important part, is this behavior guaranteed?
The "event-loop-blocking" QDialog::exec() methods return which have to be carefully handled by the caller (access of members of already deleted objects,...).
The aboutToQuit signal is emitted
The destructor of the application is called
So the program flow is:
As long as a modal dialog is open the event loop of this dialog is running. When quit() is called QDialog::exec() (the event loop of the modal dialog) is returning which could mean that a lot of additional code is run and even signal/slots could be executed when they are in the same thread. Then the normal event loop is not processed anymore, just aboutToQuit() and the destructors are called.
Is this description correct? Can someone point me to a Qt documentation that explains the interaction of quit() and QDialog? And what happens when I call exec() of a QDialog after a exec() of QDialog returned due to the quit() call? Who is then closing this QDialog?
Thanks, I'm a bit confused about all those interactions.
Edit: It appears that calls to exec() of a QDialog are rejected if the quit() method was called before. So I guess that Qt internally knows that the application is about to quit so all further QDialogs return "rejected" immediately.
I am not sure what you mean with "closeEvent is not called for QDialogs" because that is where it calls reject(): QDialog::closeEvent() code
As for the interaction between various exec() and quit():
QDialog::exec() uses a nested QEventLoop: QDialog::exec() code
QCoreApplication::quit() loops through all nested event loops on tells them to exit: QCoreApplication::exec() code
If a nested event loop is started after the main event loop of the same thread, in the case of a dialog that would be the application's main thread, it will not try "exec" but return immediately. See the first return here: QEventLoop::exec() code
It seems logical to me that all open dialogs would have to be "rejected" before the main program can close. (This should be a comment but I don't have enough rep yet >.< ).
I have been doing an implementation of Conways game of life in PySide [source]. So far it works good until a point in which, under certain conditions I havent figured out yet, the QGraphicsView i use to display the grid (which consists of several QGraphicsRectItems on a QGraphicsScene) suddenly stops being painted continuously. The rest of the window remains responsive and the game thread keeps running and signaling for the ui to update the current generation number. It is only when the window gains focus that the graphicsView updates for about a second and then freezes again.
I find this behavior particularly strange given that i dont override paintEvent, nor call repaint/update methods at all, but what the game thread does is to update every RectItem's brush color according to the status it should have every generation.
Any ideas on what could be causing this?
btw this is on Kubuntu 14.04.3 / KWin 4.11.11 / Qt 4.8.6
Managed to solved it myself! In case someone runs into same issue, all that i needed to do was to schedule an update by calling the update method of the qgraphicsscene every generation (i.e. after operating on the graphicRects from the game thread).
I assume the strange behavior was probably the result of trying to save cpu load, since for the gui thread there was no work to be done!
I have the following algorithm (working):
Acquire image from webcam
Process image
Send image to GUI and show it
The GUI interface is programmed with Qt, and all image acquirement and processing is been doing with OpenCV. There are 3 classes involved, call them Acquire, Process and Gui.
Acquire (Inherits from QObject) grabs the image and calls to Process (Does not inherit from QObject) to make the image processing. Process returns the result to Acquire, who emits a signal caught by Gui (Inherits from QObject), who converts the image (in Mat format) to QImage and draws it.
I am introducing changes into the Process class and I would like to have a visual feedback. As everything is been executed into the Qt's loop I can not use the cv::namedWindow and cv::imshow functions (nothing appears).
The question is: There is any quick method to make visual debugging to know what is happening inside Process without make Process and Gui friends, or connecting them using the signal/slot mechanism or any other solution that involves big changes into the program structure?
You can create another class and put all code for debug output into it. Connect Process to this class to send debug information.
My scenario here is the following: I am using a pyqt widget to display a solid color fullscreen on a second display and observe this display with a camera that is continuously capturing images. I do some processing with the images and this is the data I am interested in. This works great when used interactively with ipython and matplotlib using the qt4agg backend like so
% ipython -pylab
# ... import PatternDisplay, starting camera
pd = PatternDisplay(); pd.show(); pd.showColor(r=255,g=255,b=255)
imshow(cam.current_image)
I need a similar behavior now in a console script though: it should display the PatternDisplay widget, capture an image, than change the color on the PatternDisplay and take a new image and so on.
The problem is now that the PatternDisplay is never updated/redrawn in my script, likely because PyQt never gets a chance to run it's event queue. I had no luck trying to move the linear worker part of my script into a QThread because I cannot communicate with the PatternDisplay Widget from another Thread any longer. I tried to replicate the implementation of ipython/matplotlib, but I didn't fully understand it, it is quite complicated - it avoids running the QApplication main loop via monkey patching and somehow moves QT into it's own thread. It then checks periodically using a QTimer if a new command was entered by the user.
Isn't there an easy way to achieve what I want to do? I am gladly providing more information if needed. Thanks for any help!
What you need is easier than IPython's job - IPython makes the Qt application and the command line interactive at the same time.
I think the way to do it in Qt is to use a timer which fires at regular intervals, and connect the signal to the 'slot' representing your function that gets the new image and puts it in the widget. So you're pulling it in from the event loop, rather than trying to push it.
I've not used Qt much, so I can't give specifics, but the more I think about it, the more I think that's the right way to do it.
I solved the same problem (i.e. interactive ipython console in terminal, and GUI thread running independently) in the following way with ipython 0.10 (code here)
1. Construct QApplication object, but don't enter its event loop explicitly
2. Run the embedded IPython instance
3. Run the UI code you need by instantiating your window and calling show() on it (like here with the yade.qt.Controller(), which I aliased to F12. (I did not find a way how to ask the embedded shell to run a command at the start of the session, as if the user had typed it)
(You can also show() your window first, then run the embedded ipython. It will provide event loop for Qt.)
(BTW I also tried running Qt4 from a background thread (using both python threads module, and Qt4.QThreads), but it refuses to run in such way stubbornly. Don't bother going that way.)
The disadvantage is that UI will be blocked while ipython is busy. I hope to finding something better for 0.11, which should have much better threading facilities (I asked on ipython-users about how to unblock the UI).
HTH, v.
I've got a Qt App that uses QPointers to bring up new UI Dialogs (Widgets). The main app can have numerous of the same widget loaded with different data. The problem I'm having is in deleting and freeing the memory for each widget. If I monitor the RAM usage of the program, each time I click the button to open one of these new widgets, it increases the ram and when I close the widget, it doesn't seem to be freeing the ram. I've tried using deleteLater and other solutions but keep getting crashes in the program.
Some example code is here:
QPointer<ListReservations> listResWindow = new ListReservations(resID);
listResWindow->setNum(numpeople);
listResWindow->show();
This will call the "ListReservations" widget which is declared as a QDialog (NOT modal). In that dialog I then have a button to close the window that calls the QWidget::close() slot.
I guess the question is how does my main program (that has the QPointer) know when the dialog is closed and then free the dialog and (if possible) delete the pointer to save even more memory...
I thought you might be able to do a QConnect() to the QPointer object, but I can't seem to find any signals or slots that would allow the passing of the pointer, much less send the signal once the dialog is indeed closed and ready for deletion.
Maybe I need some sort of function in the main program that takes a generic pointer object and then have the QDialog call that before calling it's own close slot? In that function it would pass itself to be destroyed? Just throwing out ideas that I've tried to implement but failed at....
I don't think I can reuse the same pointer elsewhere because in theory you could have multiple ListReservations windows open at the same time.
Make sure that you set the Qt::WA_DeleteOnClose attribute flag on your dialog using QWidget::setAttribute(). That should make sure that the dialog is properly destroyed when it is closed. See the Qt documentation for more details.
Assuming that memory is now properly freed, the pointer should invalidate itself, from the Qt documentation:
A guarded pointer, QPointer,
behaves like a normal C++ pointer T *,
except that it is automatically set to
0 when the referenced object is
destroyed (unlike normal C++ pointers,
which become "dangling pointers" in
such cases)