PyQt Tips and Tricks
(→Qt and Threads) |
(→import threading) |
||
Line 43: | Line 43: | ||
=== import threading === | === import threading === | ||
+ | |||
+ | It appears QThread initializes some TLS for data essential for thread safe signals and slots. Also when creating cross-thread signals it queues the signal emission rather than doing it immediately. These present problems when wanting to use the native Python Threading in a Qt application.[http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg16062.html][http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg16082.html] | ||
+ | |||
+ | If the Python thread would not interact directly with Qt then using Python threads is fine without any consideration. | ||
+ | |||
+ | Sometimes you must use Python threads with Qt like when porting applications. One solution to his is to pump messages into a queue and have an QTimer poll the queue periodically for tasks to process in the UI thread.[http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg16062.html] | ||
=== QTimer === | === QTimer === |
Revision as of 13:58, 17 June 2010
With Meego there is a lot of interest in developing applications in Qt rather than GTK. This page spawned from a discussion thread.
Contents |
Tips and Tricks
Identifying the Sender of a Signal
There are two main approaches for this. The first is to wrap the slot with a lambda to pass in any additional arguments
def notifyMe(foo) print foo f = QPushButton("Click me!") x = lambda: notifyMe("they call him tim") self.connect(f, SIGNAL("clicked()"), x)
The second and more general solution is to use the QSignalMapper[2]
Learning to use Qt CSS
Much like web development, CSS is also available within Qt. There's a list of examples that can be tried out just using Qt Designer. If you're using custom CSS, using palette() in your CSS definitions will allow you to use colors that the theme already knows about. As an example, this is an easy way to get the default blue color on your buttons when you want that color.
Depending on your needs, there's a number of built-in icons that are available for use.[3]
Style sheets and the native QMaemo5Style do not mix very well, since Maemo 5 lays out and draws some widgets very differently (e.g. QRadioButton). We recommend using local style sheets on specific widgets only, instead of setting one via QApplication::setStyleSheet().[4]
QString and Python
I've had some unicode-relate issues when moving strings between python datatypes and Qt datatypes. Somehow, the unicode stuff would get lost. So, it's likely easiest (At least when you're new to python and Qt) to use QString and QStringList than their pure python counterparts.
If you're not bringing in data from anywhere else, this isn't that big of a deal, but if you're interacting with data from any other source, unicode is a pretty likely scenario these days.[5]
Just to note that, in my experience, locales fail to work with PyQt - QTextCodec.codecForLocale() does not return the correct codec, which also means QString's toLocal8Bit() and fromLocal8Bit() fail.
The python locale stuff works fine, but then you have the joy of converting between QString and python strings (which works perfectly when it does it implicitly, but an explicit conversion seems to go via ASCII unless you specifically tell it to use utf-8 instead). [6]
Qt and Threads
There are multiple options for preemptive threading and cooperative threading. The big question is QThread or threading.Thread. This has been discussed on the PyQt mailing list and SO
QThread
import threading
It appears QThread initializes some TLS for data essential for thread safe signals and slots. Also when creating cross-thread signals it queues the signal emission rather than doing it immediately. These present problems when wanting to use the native Python Threading in a Qt application.[7][8]
If the Python thread would not interact directly with Qt then using Python threads is fine without any consideration.
Sometimes you must use Python threads with Qt like when porting applications. One solution to his is to pump messages into a queue and have an QTimer poll the queue periodically for tasks to process in the UI thread.[9]
QTimer
Spread the work across multiple callbacks to allow the UI to remain responsive. See multiple QTimer types
Stacked Windows
class showWindowQtGui.QMainWindow): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_main_window() self.ui.setupUi(self) try: self.setAttribute(Qt.WA_Maemo5StackedWindow) except: pass
Example Applications
- ncalc
- nclock
- maesynth
- Uses QGraphicsView
- maelophone
- healthcheck
- qlister
- Gonvert (1.0+)
- WifiEye
- MaeGirls
- pyPianobar
- Threading and Qt
- pyRadio
- Threading and Qt
Web Resources
- Maemo Version of the QT Documentation
- Maemo-specific platform notes
- PyQt4 Demo's and Documentation Packages