fitz 29.11.2012 19:27

PythonСовместное использование QtDesigner и PyQt4

Сдуваю пыль с Python-блога своим первым постом.

В этой небольшой заметке речь пойдет о том, как максимально быстро просто прицепить GUI форму, которую вы намышекликали QtDesigner'e, к приложению на Python.


В процессе изучения Питона начал читать книгу Марка Саммерфилда "Rapid GUI programming with Python and Qt" аж 2007 года редакции. С Qt знаком давно и крайне ему симпатизирую. В главе об использовании QtDesigner приводится следующая инструкция:

Для того, чтобы скомпилировать .ui файл из QtDesigner'а в класс на python используется команда:
1
pyuic(или pyuic4) test.ui -o test_ui.py


В итоге импортим полученный класс и цепляем нашу форму:
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python
# coding=utf-8
import sys
from PyQt4 import QtGui
from test_ui import Ui_Dialog

class TestForm(QtGui.QDialog):
def __init__(self, parent=None):
# Запускаем родительский конструктор
super(TestForm, self).__init__(parent)
# Подцепляем форму
self.ui = Ui_Dialog()
self.ui.setupUi(self)

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = TestForm()
myapp.show()
sys.exit(app.exec_())


Если вы пользователь Эклипса, то упростить данную процедуру можно с помощью следующего костылика:

1. Идем Run -> External Tools -> External Tools Configurations ...
2. В появившемся диалоги жмем 'New' слева сверху
3. В графе 'Name' вводим 'PyUIC'
4. В графе 'Location' вводим путь, например, "C:\Python26\Python.exe"
5. В графе 'Arguments' вводим '"C:\Python26\Lib\site-packages\PyQt4\uic\pyuic4.py" "${resource_loc}"' или другой путь к установленному PyQt4 (не забудьте, что двойные кавычки нужны)
6. Переходим на вкладку 'Common', отмечаем 'File', а в разделе 'Standard Input/Output' вводим '${resource_loc}.py'
7. Переходим на вкладку 'Build', снимаем галку с 'Build before launch'
8. Переходим на вкладку 'Refresh', отмечаем 'Refresh resources upon completion'
9. Жмем 'Apply' потом 'Run'

Использование:

1. Выбираем .ui файл в 'PyDev Package Explorer' в левой части окна Эклипса
2. Жмем 'Run PyUIC' в тулбаре
3. Новый файл с окончанием .ui.py появится в соответствующей папке

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


Однако ни Марк, ни анонимный источник отчего-то не пишут о возможности PyQt4 загружать .ui итерфейс через модуль uic, чтобы не генерировать каждый раз новый код через pyuic/pyuic4.
Что ж, уличив самого Саммерфилда в ...ммм ретроградстве, теперь делаем все это просто и компактно:
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
# coding=utf-8
import sys
from PyQt4 import QtGui, uic

class TestForm(QtGui.QDialog):

def __init__(self, parent=None):
# Запускаем родительский конструктор
super(TestForm, self).__init__(parent)
# Загружаем форму "на лету"
self.ui = uic.loadUi("test.ui", self)

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = TestForm()
myapp.show()
sys.exit(app.exec_())



Таким образом отпадает необходимость каждый раз при изменении формы в QtDesigner'e перекомпилировать ее в класс Python. Стоит ли говорить, что сама .ui форма отделена не только от платформы, но и от языка, а это, на мой взгляд, очень элегантное и эффективное решение.


Тэги: PyQt4 python QtDesigner
+ 5 -
Похожие Поделиться

DbIHbKA 29.11.2012 20:14 #
Спасибо за статью. Раньше как то всегда опасался pyqt, но сейчас думаю могу смелее посмотреть в его сторону.
cppmm 29.11.2012 20:51 #
А вот такое же, но про perl там есть что-нибудь?
dront78 30.11.2012 10:54 #
прикрутите все счастье к parrot и коммунизм настанет. нет - я серьезно. у меня даже что-то запускалось )
cppmm 30.11.2012 14:55 #
у меня даже что-то запускалос

Обнадёживающе. :)

Но хотелось бы именно нативно. Я когда-то давно с tk работал на perl'е, но вот по поводу qt не сильно искал, честно говоря, но так как давно уже на кеды перелез, было бы интересно почитать для общего образования, а то мало ли, понадобится гуёвину какую сварганить по-быстрому.
kstep 02.12.2012 01:25 #
Сходу нашёл http://perlqt.sourceforge.net/
kstep 02.12.2012 01:26 #
Или посвежее http://code.google.com/p/perlqt4/
pztrn 11.12.2012 12:33 #
super() необязателен. И без него все отлично работает. Или хочется вместо self.ui использовать просто self?
derfenix 12.12.2012 11:33 #
За идею не вызывать инициализацию родительского класса из переопределённого инита - по рукам бить надо. Даже если тот инит ничего не делает.
Sokoloff 15.01.2013 10:33 #
Кусочек Makefile (http://code.google.com/p/flacon/source/browse/Makefile) относящийся к формам. Возможно будет полезен.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
FORMS       = $(shell ls *.ui encoders/*.ui)
PYUIC = pyuic4
UI_PY_FILES = $(FORMS:.ui=_ui.py)
#***********************************************************

all: ... $(UI_PY_FILES) ...


%_ui.py: %.ui
@which $(PYUIC)
$(PYUIC) $< | \
sed -e "s/\(\.setProperty(.*, \)\(False\))/\1QtCore.QVariant(\2))/" | \
sed -e "s/\(\.setProperty(.*, \)\(True\))/\1QtCore.QVariant(\2))/" | \
sed -e "s/\(\.setProperty(.*, \)\([0-9][0-9]*\))/\1QtCore.QVariant(\2))/" > $@

Rodegast 19.05.2015 22:16 #
В статье ничего не сказано про подключение формы с множественным наследованием в стиле Qt3, а надо бы...

1
2
3
4
5
class TestForm(QtGui.QMainWindow, Ui_Dialog):
def __init__(self, init={}, parent=None):
QtGui.QMainWindow.__init__(self, parent)
Ui_Dialog.__init__(self, parent)
self.setupUi(self)