Getting started with Python graphic interface program development using PyQt, pyqtpython

Source: Internet
Author: User
Tags qt designer

Getting started with Python graphic interface program development using PyQt, pyqtpython

In general, selecting a GUI toolbox for an application is tricky. Programmers using Python (the same for many languages) have a wide variety of GUI toolboxes, each of which has its own advantages and disadvantages. Some are faster and smaller than other toolboxes, some are easy to install, and some are more suitable for cross-platform use (for this purpose, you must also note that some support specific features that you need to meet ). Of course, various databases have various licenses.

For Python programmers, the default GUI option is Tk (bound through Tkinter)-The reason is obvious. Tkinter and idle IDE are compiled by the Python founder and appear as the default choice for most Python distributions. The standard Python document discusses Tkinter, but does not involve any other GUI bindings. This is intentional! At least so, if Tk and Tkinter are not so bad, programmers have no reason to look for alternatives. To induce a Python programmer to give up the default option, the toolbox must provide additional information. PyQt is such a toolbox.

PyQt has many advantages over Tkinter (it also has several disadvantages ). Qt and PyQt are fast. The design of Qt and PyQt is completely object-oriented. Qt provides a well-designed set of window components, which is much larger than that provided by Tk. In terms of its disadvantages, Qt licenses are limited by more than many toolboxes (at least on non-Linux platforms); correct installation of Qt and PyQt is often complicated; in addition, qt is a very large library. Users of the PyQt application will need to try to install Qt and PyQt, which makes distribution very difficult. (Read the Qt binding for other languages later in this article .)

PyQt strictly follows the licensing of Qt. In particular, it can be used for GPL on UNIX/X11 platforms and for Qt Palmtop Environment on Zaurus, there are also free (free-as-in-free-beer) Windows software packages for older Qt versions. PyQt commercial licenses can be used for Windows.

For this article, PyQt is better than many other toolboxes and deserves our special attention. Qt uses a mechanism called signals/slots to transmit events and messages between window components (and other objects. This mechanism is totally different from the callback mechanism used by most toolboxes, including Tkinter. It is much easier to control communication between objects using signal/slot in a flexible and maintenance manner than to use a fragile callback style. The larger the application, the more important this advantage of Qt.

Boudewijn Rempt, one of the authors of this article, has published a book on application development using PyQt. GUI Programming with Python: QT Edition (see references) shows how to design and develop a complete GUI application, including the entire process from initial conception to delivery.
Sample Application

To display the contrast between the signal/slot and the callback, we provide an application that is written and played, which uses Tkinter and PyQt. Although the PyQt version is not simple for this basic program, it has demonstrated the better controllability and maintainability of the PyQt application.

The application includes four window components:

  1. "Quit" button (used to communicate with the entire application)
  2. "Log Timestamp" button (used for messages between window components)
  3. Text area to display the time stamp list of the rolling logs
  4. Message window component that displays the time stamps of logged logs

In Tkinter, we can implement the application as follows:

Listing 1. Logger. py Tkinter Application

  #!/usr/bin/pythonimport sys, timefrom Tkinter import *class Logger(Frame):  def __init__(self):    Frame.__init__(self)    self.pack(expand=YES, fill=BOTH)    self.master.title("Timestamp logging application")    self.tslist = []    self.tsdisp = Text(height=6, width=25)    self.count = StringVar()    self.cntdisp = Message(font=('Sans',24),                textvariable=self.count)    self.log = Button(text="Log Timestamp",             command=self.log_timestamp)    self.quit = Button(text="Quit", command=sys.exit)    self.tsdisp.pack(side=LEFT)    self.cntdisp.pack()    self.log.pack(side=TOP, expand=YES, fill=BOTH)    self.quit.pack(side=BOTTOM, fill=BOTH)  def log_timestamp(self):    stamp = time.ctime()    self.tsdisp.insert(END, stamp+"\n")    self.tsdisp.see(END)    self.tslist.append(stamp)    self.count.set("% 3d" % len(self.tslist))if __name__=='__main__':  Logger().mainloop()

This Tk version uses the log_timestamp () method as the command = parameter of the button. In this method, all the window components to be affected must be operated independently. If we want to change the effect of the button press (for example, to record the time stamp), this style is very fragile. You can achieve this through inheritance:

Listing 2. StdOutLogger. py Tkinter Enhancement

    class StdOutLogger(Logger):  def log_timestamp(self):    Logger.log_timestamp(self)    print self.tslist[-1]

However, the author of this subclass needs to understand Logger very accurately. what has log_timestamp () done, and unless it is completely overwritten in the subclass. the log_timestamp () method does not call the parent method. Otherwise, the message cannot be removed.

A very basic PyQt application always has some sample code, which is the same everywhere, as does Tkinter code. However, when we further study the Code required to set up the application and display the code of the window component, the difference is displayed.

Listing 3. logger-qt.py PyQt Application

 

  #!/usr/bin/env pythonimport sys, timefrom qt import * # Generally advertised as safeclass Logger(QWidget):  def __init__(self, *args):    QWidget.__init__(self, *args)    self.setCaption("Timestamp logging application")    self.layout = QGridLayout(self, 3, 2, 5, 10)    self.tsdisp = QTextEdit(self)    self.tsdisp.setMinimumSize(250, 300)    self.tsdisp.setTextFormat(Qt.PlainText)    self.tscount = QLabel("", self)    self.tscount.setFont(QFont("Sans", 24))    self.log = QPushButton("&Log Timestamp", self)    self.quit = QPushButton("&Quit", self)    self.layout.addMultiCellWidget(self.tsdisp, 0, 2, 0, 0)    self.layout.addWidget(self.tscount, 0, 1)    self.layout.addWidget(self.log, 1, 1)    self.layout.addWidget(self.quit, 2, 1)    self.connect(self.log, SIGNAL("clicked()"),           self.log_timestamp)    self.connect(self.quit, SIGNAL("clicked()"),           self.close)  def log_timestamp(self):    stamp = time.ctime()    self.tsdisp.append(stamp)    self.tscount.setText(str(self.tsdisp.lines()))if __name__ == "__main__":  app = QApplication(sys.argv)  app.connect(app, SIGNAL('lastWindowClosed()'), app,         SLOT('quit()'))  logger = Logger()  logger.show()  app.setMainWidget(logger)  app.exec_loop()

By creating a layout manager, the Logger class starts to work. The layout manager is a complex topic in any GUI system, but the implementation of Qt makes it easy. In most cases, you will use Qt Designer to create a general GUI Design, which can then be used to generate Python or C ++ code. Then you can generate a subclass of the generated code to add functions.

However, in this example, we choose to manually create the layout manager. The window component is placed in each unit of the grid, or can be placed across multiple units. PyQt does not allow Tkinter to name parameters. This is a very important difference. It often makes people who work in two environments at a loss.

All Qt window components can work with the QString object naturally, but cannot work with the Python string or Unicode object. Fortunately, the conversion is automatic. If you use a string or Unicode parameter in the Qt method, it is automatically converted to a QString. Reverse conversion is not allowed: If you call a method to return QString, you obtain QString.

The most interesting part of the application is that we connect the clicked signal to the function location. One button connects to the log_timestamp method, and the other connects to the close method of the QWidget class.
Figure 1. logger-qt screen snapshot
Logger-qt screen snapshot

Now we want to add the log records to the standard output of this application. This is very easy. We can use the Logger class to generate sub-classes or create simple independent functions for Demonstration:

Listing 4. logger-qt.py PyQt Enhancement

  def logwrite():  print(time.ctime())if __name__ == "__main__":  app = QApplication(sys.argv)  app.connect(app, SIGNAL('lastWindowClosed()'), app,        SLOT('quit()'))  logger = Logger()  QObject.connect(logger.log, SIGNAL("clicked()"), logwrite)  logger.show()  app.setMainWidget(logger)  app.exec_loop()

From the code above, we can see that this is to connect the log QPushButton's clicked () signal to the new function. Note: signals can also transmit any data to the slots they connect to, even though this example is not shown here.

If you do not want to call the original method, you can use the slot disconnect signal. For example, add the following lines before the logger. show () line:

Listing 5. logger-qt.py PyQt Enhancement

          QObject.disconnect(logger.log, SIGNAL("clicked()"),          logger.log_timestamp)

The GUI will not be updated now.

Other GUI Bindings for Python

PyQt may not be very useful in a given instance, it may be a license status issue, or it may be a platform availability issue (or, it may be due to the difficulty of redistribution, for example, a large size ). For this reason (also for comparison), we would like to point out some other popular GUI toolboxes for Python.

Anygui
Anygui is not actually a GUI toolbox, but an abstract package that acts on a large number of toolboxes (even amazing toolboxes like curses and Java/Jython Swing. In terms of programming style, the use of Anygui is similar to the use of Tkinter, but you need to select this underlying toolbox, either automatically or configuration call. Anygui is useful because it allows applications to run on a very different platform without modification (but therefore it supports the "lowest level public feature" of the supported Toolbox ").
PyGTK
PyGTK is bound to the GTK toolbox used in GPL. It is the basis of the popular Gnome environment. GTK is basically the X Window toolbox, but it also has beta support for Win32 and alpha support for BeOS. In the general example, PyGTK uses callback for the window component. Binding exists between GTK and a large number of programming languages, not just Qt, or even Tk.
FXPy
Python-bound FXPy encapsulates the FOX toolbox. The FOX toolkit has been transplanted to most UNIX-like platforms and Win32. Similar to most toolboxes, both FOX and FXPy Use callback examples. FOX is licensed by LGPL.
WxPython
This binding wraps the wxWindows toolbox. Similar to FOX or GTK, wxWindows is transplanted to Win32 and UNIX-like platforms (but not to MacOS, OS/2, BeOS, or other "secondary" platforms-although its support for MacOSX is alpha-level ). In terms of examples, wxPython is close to the callback style. WxPython pays more attention to the inherited structure than most other toolboxes, and uses "events" instead of callback. But in essence, events are still connected to a single method, and then they may need to act on various window components.
Win32ui
Win32ui is a win32all software package that encapsulates the MFC class. Obviously, this toolbox is a Win32 library. MFC is not just a GUI toolbox, but also a mixture of various examples. For users who want to create a Windows application, win32ui will bring you closer to the essence than other toolboxes ".

Use Qt from other languages

Like Python, using the Qt toolkit from a large number of other programming languages is possible. If you have the freedom to choose, we will first choose Python, rather than other languages. External constraints such as company policies and connections to other code libraries can determine the choice of programming languages. The original Qt language is C ++, but it is also used for binding C, Java, Perl, and Ruby. In comparison with the Python example, let's discuss the applications that use Ruby and Java to write and play.

Ruby/Qt is very similar to PyQt in usage. These two languages have similar dynamics and conciseness, so apart from spelling differences, their code is similar:

Listing 6. HelloWorld. rb Qt2 Application

#!/usr/local/bin/rubyrequire 'qt2'include Qt2a = QApplication.new([$0] + ARGV)hello = QPushButton.new('Hello world!')hello.resize(100, 30)a.connect( hello, QSIGNAL('clicked()'), a, QSLOT('quit()'))a.setMainWidget(hello)hello.showa.exec

Java is always a little longer than the scripting language, but the basic parts are the same. The smallest qtjava application with the same functions is similar:

Listing 7. HelloWorld. java Qt2 Application

import org.kde.qt.*;public class HelloWorld { public static void main(String[] args) {  QApplication myapp = new QApplication(args);  QPushButton hello = new QPushButton("Hello World", null);  hello.resize(100,30);  myapp.connect(hello, SIGNAL("clicked"),         this, SLOT("quit()"));  myapp.setMainWidget(hello);  hello.show();  myapp.exec();  return; } static {  System.loadLibrary("qtjava");  try {    Class c = Class.forName("org.kde.qt.qtjava");  } catch (Exception e) {    System.out.println("Can't load qtjava class");  } }}

PyQt is an attractive and fast interface that integrates the Qt toolkit with the Python programming language. In addition to the wide variety of window components provided by the toolbox, the signal/slot programming style used by Qt is superior to the callback style used by most other GUI toolboxes in terms of production capability and maintainability.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.