Archive for the ‘Qt/KDE’ Category

Time passes. I posted back in 2012 that I wished for better Qt/Windows support, and I’m working to make that happen. I still only code in my free time, but you can find QExt on GitHub.

Also: this is a horrid looking page. Web design never was for me.

I’ve been using PyQt for about two years now. Mark Summerfield’s books on Qt, PyQt, and Python are and have been a great help. If you program in any area he’s written on, I highly recommend checking his work out. His PyQt and first Qt book are a bit dated, but provides an awesome introduction. The new Advanced Qt Programming is great in the areas it covers, but it’s expensive and given the size of Qt, can’t cover everything. Nevertheless, it has some great work on threading and other areas that are useful. His other book on Qt using C++, C++ GUI Programming with Qt4, is definitely dated but a wonderful introduction to Qt. If you’re programming Python and PyQt, it’s still easy enough to follow conceptually and most of it translates to Python.

N.B.: The rest of this post discusses Python 3 or v3-style PyQt programming, which uses built-in Python classes to replace many Qt classes. The most prominent of this is replacing instances of QSting with Python’s str. It is my understanding that this is supported in Python 2.x, so it should still be applicable.

There are two areas of PyQt, however, where Python excels beyond that of the pace with which it can be developed. I discovered PyQt’s signal/slot model before keyword arguments, but they are both gems. PyQt handles Qt-style properties in a manner very similar to Python’s properties with only minor differences. Because of that, they didn’t make my Favorite Little-Known PyQt Features list. First up is what the PyQt documentation calls new-style signals and slots. It’s elegant, clean and simple.

With completely C++-like “old style”–as the documentation calls it–signals and slots, connecting a QToolButton to a slot would look like this:

QObject.connect(self.startButton, SIGNAL('clicked()'), self, SLOT('startDownload()'))

If we throw in a little Python, it looks like this:

QObject.connect(self.startButton, SIGNAL('clicked()'), self.startDownload)

That’s a little clearer, but it’s not “Pythonic” (I really don’t like that term, but it’s true here). Here’s how it looks using new-style signals and slots:


I’d call that a much cleaner way of doing things. We can take this a step further to support overloaded signals. Imagine a QComboBox with the currentIndexChanged() signal, which can have a QString (str in PyQt) or int parameter. Getting this to work is pretty simple, too: we index the parameter type. For example:


PyQt treats the currentIndexChanged() signal like a dict to pick which of the two signal signatures to connect, using the class type as a key.

Next up is using keyword arguments for Qt properties and signals during QObject construction. Consider how our imaginary startButton QToolButton would be constructed, C++ style:

self.startButton = QToolButton(QIcon(‘./images/start.png), ‘Start’, self)
self.startButton.setToolTip(‘Starts the download.’)

I threw in the signal connection for a reason, which I will explain in a moment. One thing that C++ features and Python lacks is method signature overloading, a necessary loss given Python’s dynamic nature and duck-typing. SIP transparently handles this for us, so PyQt still works nicely with Qt’s frequent function overloads. I mention this because of the first line, where I used the QToolButton(QIcon, QString, QObject) signature as opposed to QToolButton(QObject). It’s a small thing, but try implementing that in Python–it sucks. Consequently, some Python zealots would argue that it’s not very Pythonic. Anyway, let’s get fancy.

PyQt implements support for setting Qt properties during the Python __init__ call after creating the C++ object it wraps, and it does this via keyword arguments. To take advantage, we can just tail any property names as keywords during the constructor call. In fact, it’s even possible to completely exclude any non-keyword arguments, which I will do. Converting the above example to completely keyword argument-based __init__ call might look like this:

self.startButton = QToolButton(parent=self,
                               toolTip=’Starts the download’,
                               iconSize=QSize(32, 32),

Boom. Using this method has a number of advantages. First and most obviously, it’s faster to type. Secondly, it clusters things a little more neatly and list-like, which makes it easier to read (and modify). Also, note the signal connection on the end. I haven’t tried to use keyword arguments for overloaded signals (as in the QComboBox example) before, and I doubt it would work. I should mention a caveat I’ve run into regarding signal connection by keyword. I usually lump all of my signal and slot connections in a method I also usually call connectSignals()–I’m tricky with names like that. Doing this makes it easy to see exactly what signals/slots are connected, modify them, and selectively disable if necessary for debugging. Having an extraneous signal connected elsewhere–even if it’s for a QPushButton connected to QDialog.close()–is a little out of place. If you lump your signal connections in the same way, be aware that connecting signals by keyword argument can become an issue.

All right, that’s it for now. Happy New Year.

Qt 4.8 (and the equivalent PyQt release) came out just in time with multithreaded http support and some other functional improvements. I mention multithreaded http primarily because I’m working with QtNetwork right now, and threading a simple dialog-based application would be a pain. Thankfully, I hadn’t attempted that portion of the code writing process yet–althought I have had to design with threading in mind. I can forget about dealing with that aspect now, gratefully, and focus on getting this &@#$% to work. I redesigned a few aspects of the code, but it’s ugly enough on the internals that I’m going to need to rewrite a lot of things.

The ideas are churning, and that’s good.

I’m sitting at work (Starbucks) typing up a random blog entry to get back into the habit of the blogging phenomenon. I couldn’t tolerate the old four sidebar style, so I’ve changed the blog appearance. Development on KyUI is halted temporarily while I teach myself QtNetwork. I’ve got two new widgets to throw into the mix, one based on work from another PyQt programmer. I’ll talk about that once it’s presentable. There are other ideas churning, but I’d rather not get into them until I actually make…what’s the word?…progress.

Working with QNetworkAccessManager is interesting. I converted the PyQt-converted-from-Qt example for QHttp to QNetworkAccessManager, and the results were less than inspiring. QNAM (as I’ll abbreviate it) decided my Internet access was unavailable with a decidedly confusingly generic error message. I’m writing a tidbit of software that reads in HTML, grabs information out of it, and generates the appropriate link to a wallpaper JPEG without running through intermediary HTML. It’s teaching me QtNetwork and managing lots of signals and possible error conditions. I have to admit that–after some heavy cursing–QNetworkAccessManager is better than QHttp, particarly with the use of QNetworkReply as a QIODevice. The one feature of QHttp that I miss is using QNetworkAccessManager.get() to funnel a request directly into a QIODevice, specifically a file. Yes, QNetworkReply is an io buffer, but it would be nice if I could call get(QNetworkRequest, QFile) and wait for the finished() signal from the QNetworkReply it returns without waiting for the readyRead() signal and chunking data into the file. Just a thought.

Other thoughts: contentsMargins should be a QProperty for QWidget and QLayout. I use keyword arguments almost exclusively to set initial QObject subclass states, and not being able to set the contents margins this way is irritating.

I’m off now…into The Cloud.

From jriddel’s Developer Journal

Qt, even though it’s been available for noncommercial use for quite awhile on Linux as GPL, is completely relicencing to LGPL–which means it’s “Free as in Beer and Freedom Free” for all the Stallman-esque obsessives out there. Not that anyone paid for Qt, really. Use for KDE, then for Linux, has been non-commercial for ages, but Nokia’s ownership and oversight of Trolltech means profit for the toolkit is unimportant. The more Qt, the better. One of their first moves was a quick open-sourcing of Qt for Windows.

So another set of kudos for Nokia! If you’ve been holding out on using Qt for whatever, don’t. If you’ve been using Gnome, I’m sorry. If you want to rediscover goodness in programming, do so. It’s LGPL/GPL goodness all around.

Also, since Qt is being actively ported to everything, try out QtCreator. It’s goodness in a cup and runs on both Windows and Linux. Don’t ask me about OS X, since I no usey teh losey. I kid, I kid. But I think it’s available for OS X, too. The whole thing is beta, but I’ve heard good things.

Last but not least, KDE 4.2 Beta is out. =)