Pull to refresh

Написание приложений, основаных на Qt, на языке Python

Reading time5 min
Views120K
Original author: Sebastian Kügler
Доброе время суток.
Недавно решил изучить ещё один язык программирования. Выбор пал на python. Написал несколько маленьких скриптов. Но прежде всего я хотел писать приложения с графическим интерфейсом. В интернете наткнулся на этот небольшой туториал, прочтение которого вылилось в предлагаемый Вашему вниманию перевод. Надеюсь, что кому-нибудь он будет полезен.


Это руководство нацелено на получение представления о том как писать маленькие приложения на python, использующие библотеку Qt.


Для успешного выполнения всех заданий необходимо иметь базовые знания python, однако, Qt знать не обязательно. Я использую linux в этих примерах и я предполагаю, что вы уже имеете работающий Python и PyQt. Для того, чтобы проверить это, откройте оболочку python, просто набрав «python» в консоли в введите

import qt


Если не появилось сообщения об ошибке, вы уже готовы начать. Примеры в этом руководстве упрощены насколько это возможно, и показывают полезные способы чтобы писать и структурировать вашу программу. Важно, чтобы вы прочитали исходный код примеров, болшинство вещей объяснены там. Используйте примеры и попытайтесь изменить их, поиграйте с ними. Это лучший способ привыкнуть.

Hello, world!


Начнём с простого. Программа открывает окно и показывает что-нибудь. Приведённый дальше код показывает окно, в котором написано «Hello, world!». Очевидно.

#!/usr/bin/python
import sys
from qt import *
#создадим приложение и передадим аргументы
a = QApplication(sys.argv)
#создание виджета
#Первый аргумент – текст, который мы хотим увидеть.
#Воторой аргумент – родительский виджет, 
#т.к. Hello – единственный виджет, то у него нет родителя
hello = QLabel("Hello world!",None)
#делаем виджет главным
a.setMainWidget(hello)
#показать виджет
hello.show()
#запустить приложение
a.exec_loop()


Около 7 строк кода, и это настолько просто как только можно.
А вот так это выглядит:


Кнопка


Добавим немного нтерактивности! Мы заменим надпись «Hello, World!» кнопкой и назначим ей действие. Это назанчение называется «присоединением сигнала», событие, которое посылается слоту когда кнопка нажата, который является функцией. Эта функция запускается, когда возникает событие.

#!/usr/bin/python
# coding=utf-8
import sys
from qt import *
a = QApplication(sys.argv)
# Наша функция, которая будет вызвана пр нажатии на кнопку
def sayHello():
    print "Hello, World!"
#создание кнопки
hellobutton = QPushButton("Say 'Hello world!'",None)
#назначить обработчик клика кнопке
a.connect(hellobutton, SIGNAL("clicked()"), sayHello)
#назначить кнопку главным виджетом
a.setMainWidget(hellobutton)
#показать виждет
hellobutton.show()
#запустить приложение
a.exec_loop()




Это уже больше похоже на нормальное приложение


Вы можете вообразить, что программирование таким образом не расширяемо и не заходите продолжать. Чтож давайте сделаем это по-питоновски, добавив структуру и использовав объектно-ориентированный подход. Мы создадим наш собственный класс, наследованный от QApplication и поместим необходимые нам вещи в его методы: один метод для того чтобы создать виджеты и слот, который сожержит код, запускаемый при приходе сигнала.

#!/usr/bin/python
# coding=UTF-8
import sys
from qt import *
#класс наследуем от QApplication
class HelloApplication(QApplication):
    def __init__(self, args):
        """
            В конструкторе мы делаем всё, что необходимо для запуска нашего приложения, которое
            создаёт QApplication в __init__ методе, затем добваляет наши виджеты и, наконец,
            запускает exec_loop
        """
        QApplication.__init__(self, args)
        self.addWidgets()
        self.exec_loop()        
    def addWidgets(self):
        """ В этом методе мы добавляем виджеты и присоединяем обработчики сигналов.
            Обработчик сигнала для виджета так же называется "слотом"
        """
        self.hellobutton = QPushButton("Say 'Hello, World!'",None)
        self.connect(self.hellobutton, SIGNAL("clicked()"), self.slotSayHello)
        self.setMainWidget(self.hellobutton)
        self.hellobutton.show()
    def slotSayHello(self):
        """
            Это пример слота - метода, который вызывается, когда приходит сигнал.
        """
        print "Hello, World!"
# Этот скрипт должен выполняться только отдельно, так что мы должны проверить это,
# но мы также должны иметь возможность подключать эту программу без запуска какого-либо кода
if __name__ == "__main__":
    app = HelloApplication(sys.argv)


Кодирование интерфейсов – отстой



Так что мы хотим использовать Qt3 Designer для создания GUI. На картинке вы можете видеть простой интерфейс. Зелёным цветом написаны имена виджетов. Всё что нам надо сделать
  1. Скомпилировать .ui файл из Qt designer'а в класс на python
  2. Написать подкласс и использовать его как mainWidget

Таким образом, мы сможем изменять нтерфейс в Qt designer'е, не копаясь в коде

Команда
pyuic testapp_ui.ui -o testapp_ui.py


сделает класс на python, с которым мы сможем работать.

Работу нашей программы можно описать следующим образом:
  1. Мы заполняем lineedit
  2. К нажатию на кнопку добавления мы присоединим метод, который читает текст из lineedit и добавляет его в listview
  3. Нажатие на кнопку удаления удалит выбранный элемент из listview.

Вот код с комментариями:
#!/usr/bin/python
# coding=utf-8
from testapp_ui import TestAppUI
from qt import *
import sys
class HelloApplication(QApplication):
    def __init__(self, args):
        """
            В конструкторе мы делаем всё, что необходимо для запска нашего приложения, которое
            создаёт QApplication в __init__ методе, затем добваляет наши виджеты и, наконец,
            запускает exec_loop
        """
        QApplication.__init__(self,args)
        # Мы передаём None т.к. этот виджет верхнего уровня
        self.maindialog = TestApp(None)
        self.setMainWidget(self.maindialog)
        self.maindialog.show()
        self.exec_loop()
class TestApp(TestAppUI):
    def __init__(self,parent):
        # Запускаем родительский конструктор и присоединяем слоты к методам
        TestAppUI.__init__(self,parent)
        self._connectSlots()
        # Изначально список пуст, так что кнопка удаления не должна работать
        # Сделаем её неактивной
        self.deletebutton.setEnabled(False)
    def _connectSlots(self):
        # Устанавливаем обработчики сингналов на кнопки
self.connect(self.addbutton,SIGNAL("clicked()"),self._slotAddClicked)
self.connect(self.lineedit,SIGNAL("returnPressed()"),self._slotAddClicked)
self.connect(self.deletebutton,SIGNAL("clicked()"),self._slotDeleteClicked)
    def _slotAddClicked(self):
        # Читаем тескт из lineedit,
        text = self.lineedit.text()
        # если lineedit не пуст,
        if len(text):
            # вставим новый элемент в список ...
            lvi = QListViewItem(self.listview)
            # с текстом из lineedit ...
            lvi.setText(0,text)
            # и очистим lineedit.
            self.lineedit.clear()
            # Кнопка удаления м.б. выключена, так что включим её.
            self.deletebutton.setEnabled(True)
    def _slotDeleteClicked(self):
        # Удаляем выбранный элемент из списка
        self.listview.takeItem(self.listview.currentItem())
        # Check if the list is empty - if yes, disable the deletebutton.
        # Если список после этого оказался пустым, то сделаем кнопку удаления неактивной
        if self.listview.childCount() == 0:
            self.deletebutton.setEnabled(False)
if __name__ == "__main__":
    app = HelloApplication(sys.argv)


И вот результат трудов:

Полезно знать


Создание интерфейса в Qt designer'е не только делает проще создание GUI, но это также хороший инструмент для изучения Qt. Вы можете протестировать как виджет выглядит, увидеть что доступно в Qt и посмотреть свойства, которые вы можете захотеть использовать.

Документация API для C++ также очень полезна (читайте необходима), когда работаете с PyQt. API переведён очень просто, так что попрактиковавшись, вы поймёте, что документация API для разработчиков, один из действительно нужных вам инструментов. Во врема работы в KDE вы можете ввести qt:[widgetname] в конквероре. Т.о. qt:qbutton откроет вам документацию прямо на описании qbutton. Сайт Trolltech содержит гораздо больше документации, которая может оказаться вам полезной.

Примеры в этом руководстве созданы с использованием Qt 3.3. Я быть может обновлю руководство когда появится пригодная к использованию версия pyQt для Qt 4.
Tags:
Hubs:
+52
Comments34

Articles