Форум сайта python.su
Привет, python.su
Есть необходимость срочно начать писать ГУЁвые программки под линь. После недолгого лурканья был выбран python (благо Лутца я почитал, а два тома даже прикупил). Ещё после некоторого времени лурканья для, собсно, ГУЯ была выбрана PyQt (tkinter уныл, а питоновская обвязка для gtk повергла меня в первобытный ужас). И вот здесь я столкнулся с острым недостатком информации. Современная реальность такова, что наиболее предпочтительной для освоения является связка python3 + Qt5. В то же время, практически все гайды описывают Qt4. Но не суть, методом тыка научился читать гайд про Qt4 и писать ГУЙ на Qt5, отличия минимальны. Суть в другом: все гайды по PyQt повествуют о написании ГУЯ самостоятельно. Под всеми этими гайдами есть комментарии, в которых говориться что писать ГУЙ руками не модно. Мол, в комплекте с Qt идёт замечательный WYSIWYG редактор QtDesigner, формирующий .ui файл на выходе. Сам же .ui файл можно конвертировать в .py при помощи утилиты pyuic. И вот здесь у нуба возникает проблема: получаемый .py имеет совершенно отличную структуру от написанных руками примеров из гайдов. Прошу поделиться опытом гуру, использующих данные инструменты. Как вы организуете свои питоновские проекты?
Сам я пришёл вот к какой схеме:
Файлы в проекте располагаются так:
./Designs - папка, содержащая файлы .ui и сконвертированные из них .py
./Forms - см примечание*
./main.py - вызывает основное окно
./ - содержит также разные скрипты типа progname.desktop configure.py, install.sh и т.п. См**
*Сконвертированные .py не трогаю, ибо при перерисовке и переконвертации потеряется весь набранный руками код. Значит, для каждого сконвертированного .py нужен написанный руками .py, с классом-наследником, переопределяющим всё необходимое. Если моя схема имеет право на существование, наверно пихну их в папку ./Forms Пока же они лежат прямо в ./
** ./ - корневой каталок проекта.
Как реализую сами окошки
Сконвертированный .py содержит вот какой класс:
class Ui_MainWindow(object): def setupUi(self, MainWindow): #код, преобразующий переданное MainWindow def retranslateUi(self, MainWindow): #код, создающий русские надписи
#Разные важные import from Designes.form1 import Ui_MainWindow class mainForm(Ui_MainWindow): #Инициализация def __init__(self): Ui_MainWindow.__init__(self) self.window = QtWidgets.QMainWindow() #окно, которое должно быть передано self.setupUi(self.window) #этой функции и преображено ей self.sett.clicked.connect(self.sett_onClick) #назначаем свои обработчики событий элементам #.................. self.window.show() def sett_onClick(self): #код обработки события клика по кнопке "настройки" #................... if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) form = maneForm() sys.exit(app.exec_())
Отредактировано Metallikus (Ноя. 26, 2014 21:16:46)
Офлайн
Metallikus
Современная реальность такова, что наиболее предпочтительной для освоения является связка python3 + Qt5.
Metallikus
Суть в другом: все гайды по PyQt повествуют о написании ГУЯ самостоятельно. Под всеми этими гайдами есть комментарии, в которых говориться что писать ГУЙ руками не модно. Мол, в комплекте с Qt идёт замечательный WYSIWYG редактор QtDesigner, формирующий .ui файл на выходе. Сам же .ui файл можно конвертировать в .py при помощи утилиты pyuic. И вот здесь у нуба возникает проблема: получаемый .py имеет совершенно отличную структуру от написанных руками примеров из гайдов.
Metallikus
Как вы организуете свои питоновские проекты?
Отредактировано Alen (Ноя. 26, 2014 22:18:28)
Офлайн
Alen, спасибо за ответ. Я так понял, резюме можно вывести следующее:
1) python3 и Qt4 вполне можно использовать
2) QtDesigner неполноценен и предназначен для новичков
3) проект можно организовать как угодно
Вот какие мысли это вызывает у меня:
1) Это понятно, но при выборе инструментов для освоения, упор лучше делать на перспективность. Qt3 тоже некоторое время использовалась параллельно с Qt4, значит и Qt5 полностью заменит Qt4 в своё время.
2) Наслеlование от object и правда наибольшая проблема, в гайдах-то всё совершенно по-другому реализуют. Может и стоит плюнуть на QtDesigner, что сократит количество модулей в проекте практически вдвое?.. Мало ли что там в каментах на хабре пишут
3) Я имел в виду как получше организовать ГУИ и логику его контролов. То есть именно организацию модулей одного приложения, возможно и многооконного.
Отредактировано Metallikus (Ноя. 27, 2014 05:14:40)
Офлайн
Metallikus
Сконвертированный .py содержит вот какой класс:
MetallikusПервое, что бросается в глаза - это слово object там, где оно не нужно. Да, для третьего питона генерятся такие вот файлы. Зачем этот мусор в третьем питоне?class Ui_MainWindow(object):
MetallikusВот так должно быть.class Ui_MainWindow:
Отредактировано py.user.next (Ноя. 27, 2014 05:46:06)
Офлайн
Ок, всё понял. Настоящие профи пишут код для GUI руками. Вот почему про QtDesigner только каменты и есть, ни одного гайда.
py.user.nextЭ.. А у меня генериться примерно так:
Дальше связи сигналов со слотами - аналогично, используется стиль для Qt3. Оттуда длиннющие строки (а pep8 они - создатели конвертера - не соблюдают).
self.btnExit.clicked.connect(MainWindow.close)
Отредактировано Metallikus (Ноя. 27, 2014 10:30:50)
Офлайн
Metallikus
А у меня генериться примерно так:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>QMainWindow</string>
</property>
<property name="statusTip">
<string/>
</property>
<widget class="QWidget" name="centralwidget">
<property name="statusTip">
<string/>
</property>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="statusTip">
<string extracomment="0"/>
</property>
<property name="accessibleDescription">
<string/>
</property>
<property name="title">
<string>&File</string>
</property>
<addaction name="action_Exit"/>
</widget>
<addaction name="menuFile"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="action_Exit">
<property name="text">
<string>Exit</string>
</property>
<property name="statusTip">
<string>exit?</string>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>action_Exit</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
</connections>
</ui>
[guest@localhost mainwindow]$ pyuic4 mainwindow.ui
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainwindow.ui'
#
# Created: Thu Nov 27 20:00:20 2014
# by: PyQt4 UI code generator 4.10.2
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.setEnabled(True)
MainWindow.resize(800, 600)
MainWindow.setStatusTip(_fromUtf8(""))
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setStatusTip(_fromUtf8(""))
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
self.menuFile = QtGui.QMenu(self.menubar)
self.menuFile.setStatusTip(_fromUtf8(""))
self.menuFile.setAccessibleDescription(_fromUtf8(""))
self.menuFile.setObjectName(_fromUtf8("menuFile"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.action_Exit = QtGui.QAction(MainWindow)
self.action_Exit.setObjectName(_fromUtf8("action_Exit"))
self.menuFile.addAction(self.action_Exit)
self.menubar.addAction(self.menuFile.menuAction())
self.retranslateUi(MainWindow)
QtCore.QObject.connect(self.action_Exit, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.close)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "QMainWindow", None))
self.menuFile.setTitle(_translate("MainWindow", "&File", None))
self.action_Exit.setText(_translate("MainWindow", "Exit", None))
self.action_Exit.setStatusTip(_translate("MainWindow", "exit?", None))
[guest@localhost mainwindow]$
Отредактировано py.user.next (Ноя. 27, 2014 12:05:24)
Офлайн
QtCore.QObject.connect(self.action_Exit, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.close)
Офлайн
> Под всеми этими гайдами есть комментарии, в которых говориться что писать ГУЙ руками не модно.
Модно, не модно это всё аргументы для блондинок. При написании программ нужно руководствоваться эффективностью, так вот “писать ГУЙ руками” НЕ ЭФФЕКТИВНО!
> Современная реальность такова, что наиболее предпочтительной для освоения является связка python3 + Qt5.
Использовать Qt5 ещё рано, хотя бы потому что он есть не во всех дистрибутивах (в стабильном Debian-е его точно нет).
> Наслеlование от object и правда наибольшая проблема
Нет здесь никакой проблемы.
> Первое, что бросается в глаза - это слово object там, где оно не нужно. Да, для третьего питона генерятся такие вот файлы.
Эти файлы генерятся для второго питона.
> Дальше связи сигналов со слотами - аналогично, используется стиль для Qt3. Оттуда длиннющие строки (а pep8 они - создатели конвертера - не соблюдают).
Ну и что?
> Дальше никакие имена, оно и понятно, это всё потом надо менять.
Что значит “никакие имена”
> И, самое главное, все эти визивиги при любом изменении всё меняют обратно.
Зачем вам что-то менять руками?
Офлайн
RodegastИ что дальше? Применяется-то это в третьем. А зачем в третьем object?
Эти файлы генерятся для второго питона.
RodegastУстаревший стиль.
Ну и что?
RodegastНикакие - нечитаемые. То есть, если сделать побольше и подетальнее форму, то её даже понять будет невозможно.
Что значит “никакие имена”
RodegastВо-первых, чтобы красиво смотрелось; во-вторых, чтобы не было ничего лишнего.
Зачем вам что-то менять руками?
RodegastДа, проще скачать уже готовую программу. Визивиги всегда были фигнёй во всех областях. Они для блондинок, у которых знаний нет.
так вот “писать ГУЙ руками” НЕ ЭФФЕКТИВНО!
Отредактировано py.user.next (Ноя. 27, 2014 13:58:06)
Офлайн
RodegastПри чтении гайдов есть. См. выше.
Нет здесь никакой проблемы.
Офлайн