--- category: '' date: 2004/03/28 15:52 description: '' link: '' priority: '' slug: '27' tags: kde, programming, python title: Custom widgets using PyQt type: text updated: 2004/03/28 15:52 url_type: '' --- .. raw:: html
Revision: | 1.0 |
---|---|
Date: | March 27, 2004 |
Everyone who has programmed applications knows that sometimes you create a gadget that can be reused in other situations, and that code reuse is good.
In the specific case of GUI applications, often what you would want to reuse is a widget.
For example, you took one of the toolkit's widgets and extended its functionality in a way you think has wide application, and you intend to reuse it on future work.
So, what we will try to do is figure out how we can create easy-to-reuse custom widgets using PyQt.
Our example custom widget will be a RestructuredText editor. Why? Because I need one ;-)
We can use Qt's desiger to draw the layout of our widget, if it needs more than one component.
In this case, I will create a tabbed widget containing a editing (QTextEdit) and a viewing (QTextBrowser) widgets.
A Qt Widget has a number of slots, which is how the code accesses its functionality.
While the real QRestEditor is a rather complex widget, I will explain just a small part of it, so you can see how the general case is. Repeat as needed ;-)
You can create the slots from designer, by right-clicking on the form and choosing Slots.
Well, create all the slots you need. I only created one, called render(), which will use the docutils module to render the text in the editor into HTML on the viewer.
While the look of the widget is already done, it needs to be fleshed by adding code to it.
My preferred way to do it is creating a subclass of QRestEditorBase, called QRestEditor, and implement there the desired functionality.
pyuic -p0 -x qresteditorbase.ui > qresteditorbase.py
This will generate a qresteditorbase.py file which implements the QRestEditorBase class.
You can see if it works by doing
python qresteditorbase.py
Now here's how the QRestEditor class looks like:
As you can see, it simply reimplements the render() slot.
Now you can just use the widget at will. Of course what we did so far is nothing unusual :-)
Designer is a nice tool. That's why we used it in Step I, after all. Now, we'll see how we can make it so our new widget can be used in designer, too!
Now, suppose we want to create a dialog containing the custom widget we created, for demostration purposes.
Open designer
Tell it you want to create a dialog
Tools->Custom->QRestEditor
Click anywhere so it gets created.
Now, you need to tell designer something, so that the generated code will import the right Python module to create a QRestEditor widget.
Right click on the form, and choose Form Settings
In the Comments field, add this:
Python:#Import the qresteditor module Python:from qresteditor import *
Notice that there is no space after Python: because this will be inserted in the python code!
Add a QPushButton somewhere in the dialog.
Now, something that doesn't quite work yet:
pyuic -x -p0 testdialog.ui > testdialog.py python testdialog.py
Sadly, on PyQt 3.10, the connections are not generated correctly, so this will not work right. :-P
On testdialog.py, you will need to change the line
self.connect(self.pushButton1,SIGNAL("clicked()"),self.restEditor1,SLOT("render()"))
to
self.connect(self.pushButton1,SIGNAL("clicked()"),self.restEditor1.render)
This means this is not yet perfect. But hopefully it ill get fixed soon, if possible :-)
However, if you handle all the connections to the custom widget by hand in a subclass of testdialog, it is entirely possible to use this already. That means you can't use designer 100%, but it's close.
There's really no need to package these things. You could just put them in a subfolder of your own project, and use them.
However, if you want to have a system-wide version of the custom widget, a simple distutils-based setup.py can do the work, and is left as exercise for the reader (post it as a comment, you get your grade later ;-)
Of course to make a good Restructured Text editor widget, it needs lots more fleshing out than what you see here. In fact, I wrote this article in a more advanced version of the same thing ;-) The purpose was simply to show how you can create widgets maximizing the chance of reuse.
If any magazine or site editor reads this, feels this article has adequate quality, and wants to publish something I write... feel free to contact me and we'll talk about it. I'm not expensive, I have several ideas, and I write quickly ;-)