PyQt Tips and Tricks

(QThread)
(wikify slightly)
Line 1: Line 1:
With Meego there is a lot of interest in developing applications in Qt rather than GTK.  This page spawned from a [http://talk.maemo.org/showthread.php?t=56171 discussion thread].
With Meego there is a lot of interest in developing applications in Qt rather than GTK.  This page spawned from a [http://talk.maemo.org/showthread.php?t=56171 discussion thread].
-
= Tips and Tricks =
+
== Tips and Tricks ==
-
== Identifying the Sender of a Signal ==
+
=== 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
+
There are two main approaches for this.  The first is to wrap the slot with a lambda to pass in any additional arguments:
<source lang="python">
<source lang="python">
def notifyMe(foo)
def notifyMe(foo)
Line 18: Line 18:
The second and more general solution is to use the [http://pysnippet.blogspot.com/2010/06/qsignalmapper-at-your-service.html QSignalMapper][http://talk.maemo.org/showpost.php?p=714752&postcount=8]
The second and more general solution is to use the [http://pysnippet.blogspot.com/2010/06/qsignalmapper-at-your-service.html QSignalMapper][http://talk.maemo.org/showpost.php?p=714752&postcount=8]
-
== Learning to use Qt CSS ==
+
=== Learning to use Qt CSS ===
Much like web development, [http://doc.qt.nokia.com/4.6/stylesheet.html CSS is also available within Qt]. [http://doc.qt.nokia.com/4.6/stylesheet-examples.html There's a list of examples] that can be tried out just using Qt Designer. If you're using custom CSS, using [http://agateau.wordpress.com/2008/01/15/qt-stylesheets-and-qpalette/ 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.
Much like web development, [http://doc.qt.nokia.com/4.6/stylesheet.html CSS is also available within Qt]. [http://doc.qt.nokia.com/4.6/stylesheet-examples.html There's a list of examples] that can be tried out just using Qt Designer. If you're using custom CSS, using [http://agateau.wordpress.com/2008/01/15/qt-stylesheets-and-qpalette/ 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.
Line 24: Line 24:
Depending on your needs, there's a number of [http://doc.trolltech.com/4.4/stylesheet-reference.html#list-of-icons built-in icons] that are available for use.[http://talk.maemo.org/showpost.php?p=714507&postcount=1]
Depending on your needs, there's a number of [http://doc.trolltech.com/4.4/stylesheet-reference.html#list-of-icons built-in icons] that are available for use.[http://talk.maemo.org/showpost.php?p=714507&postcount=1]
-
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().[http://talk.maemo.org/showpost.php?p=714544&postcount=4]
+
Style sheets and the native <code>QMaemo5Style</code> do not mix very well, since Maemo 5 lays out and draws some widgets very differently (e.g. <code>QRadioButton</code>). We recommend using local style sheets on specific widgets only, instead of setting one via <code>QApplication::setStyleSheet()</code>.[http://talk.maemo.org/showpost.php?p=714544&postcount=4]
-
== QString and Python ==
+
=== 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.
+
I've had some Unicode-related 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 <code>QString</code> and <code>QStringList</code> 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.[http://talk.maemo.org/showpost.php?p=717579&postcount=11]
+
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.[http://talk.maemo.org/showpost.php?p=717579&postcount=11]
-
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.
+
Just to note that, in my experience, locales fail to work with PyQt - <code>QTextCodec.codecForLocale()</code> does not return the correct codec, which also means <code>QString</code>'s <code>toLocal8Bit()</code> and <code>fromLocal8Bit()</code> 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). [http://talk.maemo.org/showpost.php?p=717585&postcount=12]
+
The Python locale stuff works fine, but then you have the joy of converting between <code>QString</code> 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). [http://talk.maemo.org/showpost.php?p=717585&postcount=12]
-
== Qt and Threads ==
+
=== 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 [http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg16050.html PyQt mailing list] and [http://stackoverflow.com/questions/1595649/threading-in-a-pyqt-application-use-qt-threads-or-python-threads SO]
+
There are multiple options for preemptive threading and cooperative threading.  The big question is <code>QThread</code> or <code>threading.Thread</code>.  This has been discussed on the [http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg16050.html PyQt mailing list] and [http://stackoverflow.com/questions/1595649/threading-in-a-pyqt-application-use-qt-threads-or-python-threads SO]
-
=== QThread ===
+
==== QThread ====
-
It is discouraged to inherit from QThread and to use moveToThread on the QThread.[http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong].  A C++ example of how to use these is shown in a producer/consumer style application can be found on the [http://labs.trolltech.com/blogs/2006/12/04/threading-without-the-headache/ trolltech blog].
+
It is discouraged to inherit from <code>QThread</code> and to use <code>moveToThread</code> on the <code>QThread</code>.[http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong].  A C++ example of how to use these is shown in a producer/consumer style application can be found on the [http://labs.trolltech.com/blogs/2006/12/04/threading-without-the-headache/ trolltech blog].
-
=== 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]
+
It appears <code>QThread</code> 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.
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]
+
Sometimes you must use Python threads with Qt like when porting applications.  One solution to this is to pump messages into a queue and have an <code>QTimer</code> poll the queue periodically for tasks to process in the UI thread.[http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg16062.html]
-
=== QTimer ===
+
==== QTimer ====
-
Spread the work across multiple callbacks to allow the UI to remain responsive. See multiple [http://www.rkblog.rk.edu.pl/w/p/qtimer-making-timers-pyqt4/ QTimer types]. If you're not relying on third parties (anything that will block the interpreter - whether it be waiting on hardware or a call via XMLRPC) QTimers are probably a good choice.
+
Spread the work across multiple callbacks to allow the UI to remain responsive. See multiple [http://www.rkblog.rk.edu.pl/w/p/qtimer-making-timers-pyqt4/ QTimer types]. If you're not relying on third parties (anything that will block the interpreter - whether it be waiting on hardware or a call via XMLRPC) <code>QTimer</code>s are probably a good choice.
-
As an example, I wrote an app that would play a series of .jpg images as a movie in a player. While using a thread would work, using a QTimer worked great as well, since there was no waiting for hardware.
+
As an example, I wrote an app that would play a series of .jpg images as a movie in a player. While using a thread would work, using a <code>QTimer</code> worked great as well, since there was no waiting for hardware.
-
== Stacked Windows ==
+
=== Stacked Windows ===
<source lang="python">
<source lang="python">
Line 74: Line 74:
[http://talk.maemo.org/showpost.php?p=714507&postcount=1]
[http://talk.maemo.org/showpost.php?p=714507&postcount=1]
-
= Example Applications =
+
== Example Applications ==
 +
 
This is an overview of some of the PyQt applications available for Maemo. For some of the apps, there's a brief outline of unique functions they might have that you might want for your app.
This is an overview of some of the PyQt applications available for Maemo. For some of the apps, there's a brief outline of unique functions they might have that you might want for your app.
-
The official [http://www.riverbankcomputing.co.uk/software/pyqt/download PyQt] bindings come with python-based examples for many things. There's also examples for [http://maemo.org/packages/view/python2.5-qt4-doc/ PyQt on Maemo5] with python examples, as well.  
+
The official [http://www.riverbankcomputing.co.uk/software/pyqt/download PyQt] bindings come with Python-based examples for many things. There's also examples for [http://maemo.org/packages/view/python2.5-qt4-doc/ PyQt on Maemo 5] with Python examples, as well.  
If you want to learn to become better in Python and Qt, reading code is one of the better ways to do it.
If you want to learn to become better in Python and Qt, reading code is one of the better ways to do it.
Line 88: Line 89:
* [http://maemo.org/packages/view/maelophone/ maelophone]
* [http://maemo.org/packages/view/maelophone/ maelophone]
* [http://maemo.org/packages/view/healthcheck/ healthcheck]
* [http://maemo.org/packages/view/healthcheck/ healthcheck]
-
** Gives examples of interacting with much of the hardware on the n900
+
** Gives examples of interacting with much of the hardware on the N900
* [http://maemo.org/packages/view/qlister/ qlister]
* [http://maemo.org/packages/view/qlister/ qlister]
* Gonvert (1.0+)
* Gonvert (1.0+)
Line 98: Line 99:
** Threading and Qt
** Threading and Qt
-
= Web Resources =
+
== Web Resources ==
-
* [http://doc.qt.nokia.com/qt-maemo-4.6/index.html Maemo Version of the QT Documentation]
+
* [http://doc.qt.nokia.com/qt-maemo-4.6/index.html Maemo Version of the Qt Documentation]
* [http://doc.qt.nokia.com/qt-maemo-4.6/platform-notes-maemo5.html Maemo-specific platform notes]
* [http://doc.qt.nokia.com/qt-maemo-4.6/platform-notes-maemo5.html Maemo-specific platform notes]
* [http://talk.maemo.org/showthread.php?t=42754 PyQt4 Demo's and Documentation Packages]
* [http://talk.maemo.org/showthread.php?t=42754 PyQt4 Demo's and Documentation Packages]
Line 106: Line 107:
[[Category:Qt]]
[[Category:Qt]]
[[Category:Python]]
[[Category:Python]]
 +
[[Category:Development]]

Revision as of 08:19, 18 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)

[1]

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-related 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

It is discouraged to inherit from QThread and to use moveToThread on the QThread.[7]. A C++ example of how to use these is shown in a producer/consumer style application can be found on the trolltech blog.

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.[8][9]

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 this is to pump messages into a queue and have an QTimer poll the queue periodically for tasks to process in the UI thread.[10]

QTimer

Spread the work across multiple callbacks to allow the UI to remain responsive. See multiple QTimer types. If you're not relying on third parties (anything that will block the interpreter - whether it be waiting on hardware or a call via XMLRPC) QTimers are probably a good choice.

As an example, I wrote an app that would play a series of .jpg images as a movie in a player. While using a thread would work, using a QTimer worked great as well, since there was no waiting for hardware.

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

[11]

Example Applications

This is an overview of some of the PyQt applications available for Maemo. For some of the apps, there's a brief outline of unique functions they might have that you might want for your app.

The official PyQt bindings come with Python-based examples for many things. There's also examples for PyQt on Maemo 5 with Python examples, as well.

If you want to learn to become better in Python and Qt, reading code is one of the better ways to do it.

Web Resources