Содержание
- Python GUI’s with PyQt
- Python GUI: создаём простое приложение с PyQt и Qt Designer
- Что нам потребуется
- Дизайн
- Основы
- Макеты
- Последние штрихи
- Превращаем дизайн в код
- Пишем код
- Используем дизайн
- Добавляем функциональность в наше Python GUI приложение
Python GUI’s with PyQt
This tutorial covers the basics of how to create GUI’s in Python using PyQt5. I will demonstrate how to find the designer and basic usage, converting .ui to .py, running the output file and connecting events to methods.
Important First Note
Please understand this process is not the recommended method when using PyQt5 designed / pyuic; this is simply a demonstration of designing a UI using the PyQt5 designer tool, generating Python code and then partially understanding what comes out.
This tutorial is not obsolete however as it can help you get a basic grasp of how to use PyQt5.
The reason the method demonstrated below is not recommended is due to the fact if you use pyuic again to turn a .ui file into a .py file, it will overwrite all your changes to the file. I have a tutorial at How to Import a PyQt5 .ui File in a Python GUI which better explains how you should import the generated script so your changes will not be overwritten.
If you only intend on using the generated code as an initial layout and not re-generate the code (I do this a lot), you may find this method easier than importing as you can make changes to the layout a lot easier this way.
Setting up the Environment
For this tutorial, you will need a version of Python equal to or above 3.5. I do however recommend to get a more recent version than 3.5 as I had issues with 3.5.2; a simple upgrade to 3.6.6 fixed this. If you don’t know where to get Python, look here.
Now you will want to install pyqt5 and pyqt5-tools. To do this, we can use pip. Call the two commands python -m pip install pyqt5 and python -m pip install pyqt5-tools . After each command completes, make sure to verify that they installed properly by checking if it says they were installed successfully.
You should now be able to execute the following in Python with no errors:
If you have issues installing PyQt5 for some reason, you could try the installers at its sourceforge page.
Using the Designer
When you ran the pip install pyqt5-tools command, this installed tools that we can use to help with building GUIs.
First, we need to locate where they are now, to do this we can run the following code in Python:
This will print out a couple of paths, for me it prints: [‘C:\Python36’, ‘C:\Python36\lib\site-packages’] . Here we can see my Python distribution location and the site-packages folder. Open up a file explorer and navigate to the site-packages folder. In this folder, you then want to locate the pyqt5-tools folder and open it. In this folder, you should find a few files, one named designer.exe.
After recent updates to pyqt5-tools , designer.exe has been moved to the ‘Scripts’ folder in your Python distribution. To find this using the paths we found before, go to the first path returned (‘C:Python36’ in my case) and then go into the ‘Scripts’ folder; you should find designer.exe in here.
Using the Designer
designer.exe is the program that we will use to make designing GUIs a lot easier; remember the location of this or create a shortcut to it and then run it (double click if you wish). You will be welcomed with a selection window; select «Main Window» and then click «Create».
You will now be shown an empty window in the middle of the designer’s window with widget options on the left and some other windows to the right.
On the left, you can drag widgets from the drop-downs onto the MainWindow object in the centre. On the right, in the Object Inspector, you can see the current widgets in your window. Right below that is the Property Editor that allows you to modify the widget currently selected.
Creating a Simple Window
For this example, we will be just putting a button that prints «Hello World!» when pressed in the Window; soon we will work with a larger example when the basics are out of the way.
First, make your window a bit smaller by clicking and dragging the bottom right of the window (or any part on the edge) to change the size as you would do on any other window. Now find the «Push Button» widget under the Buttons section (on the left) and drag it into the window anywhere. You can double click on the button now to rename the text in it; set it to «Print Message».
You may now want to change the size of the button, to do this click on the button until there are blue squares on each of its corners and edges. Use these blue squares to re-size the button to a size you want.
When you are happy with what you have done (this is just a simple practice) then click File -> Save in the top left and save it somewhere where you will remember; I will save it as ‘printMessage.ui’ on my desktop.
Converting .ui to .py
Now that we have our .ui file, we can convert it into Python code so we can modify and run it.
To do this we need to locate pyuic5. pyuic5 converts .ui to .py in one simple command and is located in the ‘Scripts’ folder in your Python distribution. If you don’t know where this is, execute the following:
You will be provided with a path of where your python distribution is located; mine is at C:Python36 (we saw this before when looking for the designer). Now go to this directory and open the ‘Scripts’ folder in there.
In this folder you will see a few executables to make Python in the terminal easier, you should also be able to see a file named pyuic5.exe ; this is what we are going to use. Open cmd and then use the cd command to get to the directory; for example, I will execute cd C:Python36Scripts in cmd. Now if you type pyuic5 you should be provided with a small error message saying «Error: one input ui-file must be specified»; this is good, we are in the right place.
To convert we now need to pass in the .ui file we created before and decide on an output filename and location. My .ui file is on my desktop currently so I will put the created .py file on the desktop also to make it easier. Now we can convert using pyuic5 -x -o , for example I will use pyuic5 -x «C:UsersBrentDesktopprintMessage.ui» -o «C:UsersBrentDesktopprintMessage1.py» . This should take not very long at all and show no errors; the python script you declared after -o will now exist — for me, a file called printMessage1.py is now on my desktop.
Running the Output and Hooking up the Button
Now that you have the .py file containing the ui code, open it in IDLE or whatever IDE you use. Your code should look something like this:
Run the code and then wait for the GUI to appear; it currently won’t do anything when you press the button so we will set that up.
Go back into the code for this GUI and look in the setupUi definition. You should see a class variable called self.pushButton which later has its text set to «Print Message» in the retranslateUi definition below. This is the object of our button that we need to make do something.
First, we need to create our method, this method can be in the global scope or in the class scope, for simplicity I will put it in the class scope. After the retranslateUi definition, create a new class called printMessage that takes self as an argument since it is part of the class now. Inside this put what you want the script do to when you press the button, for this example, I will print «Hello World!».
Now that you have created the method to run, we can attach it to the button. Using the button variable we found before, we can call .clicked.connect() on it passing in the name of our method we just created (make sure to remember self. for class variables). Put this line at the bottom of the setupUi definition so it will be executed when the GUI is built.
Remember to not include () when passing the method here or it will not work.
Your script should now look something like this, don’t worry if it is a bit different.
Run the code again and now when you press the button you should see that the script runs the code that you defined in the method you attached to the button.
More Advanced Example
In this next example, I will show you how to put images in the GUI, add a selection dialog box and add data to a table.
Open the designer back up and create a new MainWindow. Now create and position the 5 widgets described below: — Label (in Display Widgets): This label will be the widget we use to show the image — PushButton (in Buttons): This button will allow us to select the image to show in the Label — ListWidget (in Item Widgets): This will hold and display entries we add to it — LineEdit (in Input Widgets): This will allow us to enter what we want into the table — PushButton (in Buttons): This will add the item in the LineEdit to the table
If you click on a widget, for example, the button that will be selecting the button, the Property Editor on the right will display all the options for that object. In there you can edit things like the exact size/position, borders (frames), tooltips and fonts.
First, we will want to edit the Label that is holding the image; click on the label to open it up in the Property Editor. Find «text» under the QLabel section and delete the text, this is the same as double-clicking and removing the text. Now go to the QFrame heading and change «frameShape» to box, this will but a border around the image.
Now click on the select image button and in the QWidget header go to «font». This has many options inside of this so play around to get a font you like (you can leave it if you want). Your GUI should now look something like this:
To help you later on, you can also change the «objectName» under QObject in the Property Editor for all widgets so you can identify them easier later. Here is what I named mine: — Select Image Button: selectImageBtn — Image Label: imageLbl — LineEdit: lineEdit — Add button: addBtn — ListWidget: listWidget
Like we did before, convert this .ui file (after saving it) to a .py file.
Connecting Events to Methods
Now we need to connect all the actions together. The select image button will need to be connected to a method that displays an image selection dialog which will then put an image in the label. Also, we will need to make the ‘add’ button add the text in the lineEdit object into the listWidget object.
Your converted .py code should currently look something like this: Code download: MainWindowAdvanced1.py
If you open your .py file in IDLE, you can see that the names we gave each widget have passed through to the names of the actual objects. I also recommend running the code now to make sure it works.
Linking the Image Button
First, you will want to create a class definition called setImage ; make sure this takes self as it is a class definition. In this method, we want to ask the user for an image (not just any file). If they provide a file, we then need to create a pixmap object and then set the pixmap object to the image label. Before we set it, it is ideal to scale the image to fit inside the label without stretching and aligning it to the centre. Your method will look like this:
In the QtWidgets.QFileDialog.getOpenFileName method call, you can see I have passed the string «Image Files (*.png *.jpg *jpeg *.bmp)» . This declares the type of files I will accept. If you want to accept any file, remove this string completely. If you want to make it so the user could switch it to all files themselves, set it to «Image Files (*.png *.jpg *jpeg *.bmp);;All Files (*)» ; play around with this to get the idea of what is going on, you can add more file extensions and selections if wanted.
Now we need to attach the button to the definition. This can simply be done using the connect method we used previously; make sure to put it at the bottom of the setupUi definition as we did before:
Run the script and make sure that your button works. Initially, the label will be clear but each time you select a file it should change to the selected file.
Linking the Add to List Button
We will now need to create another class definition called addItem like before. In this method, we need to get the value of the lineEdit object and then clear it. We can then simply add the value we just got to the listWidget. After you have done that, the method should look like this:
And then like before, we need to connect the button to the method just under the last one we did:
Running the script now you should be able to type in the text edit item and then press add for the item to go into the list.
Owner of PyTutorials and creator of auto-py-to-exe. I enjoy making quick tutorials for people new to particular topics in Python and tools that help fix small things.
Источник
Python GUI: создаём простое приложение с PyQt и Qt Designer
Эта статья предназначена для тех, кто только начинает своё знакомство с созданием приложений с графическим интерфейсом (GUI) на Python. В ней мы рассмотрим основы использования PyQt в связке с Qt Designer. Шаг за шагом мы создадим простое Python GUI приложение, которое будет отображать содержимое выбранной директории.
Что нам потребуется
Нам понадобятся PyQt и Qt Designer, ну и Python, само собой.
В этой статье используется PyQt5 с Python 3, но особых различий между PyQt и PySide или их версиями для Python 2 нет.
Windows: PyQt можно скачать здесь. В комплекте с ним идёт Qt Designer.
macOS: Вы можете установить PyQt с помощью Homebrew:
$ brew install pyqt5
Скачать пакет с большинством компонентов и инструментов Qt, который содержит Qt Designer, можно по этой ссылке.
Linux: Всё нужное, вероятно, есть в репозиториях вашего дистрибутива. Qt Designer можно установить из Центра Приложений, но PyQt придётся устанавливать через терминал. Установить всё, что нам понадобится, одной командой можно, например, так:
После того как вы закончили с приготовлениями, откройте командную строку/терминал и убедитесь, что вы можете использовать команду pyuic5 . Вы должны увидеть следующее:
Если вы видите сообщение, что такой команды нет или что-то в таком роде, попробуйте загуглить решение проблемы для вашей операционной системы и версии PyQt.
Если вы используете Windows, то, скорее всего, путь C:Python36Scripts (измените 36 на вашу версию Python) не прописан в вашем PATH . Загляните в этот тред на Stack Overflow, чтобы узнать, как решить проблему.
Дизайн
Основы
Теперь, когда у нас всё готово к работе, давайте начнём с простого дизайна.
Откройте Qt Designer, где вы увидите диалог новой формы, выберите Main Window и нажмите Create.
После этого у вас должна появиться форма — шаблон для окна, размер которого можно менять и куда можно вставлять объекты из окна виджетов и т.д. Ознакомьтесь с интерфейсом, он довольно простой.
Теперь давайте немного изменим размер нашего главного окна, т.к. нам не нужно, чтобы оно было таким большим. А ещё давайте уберём автоматически добавленное меню и строку состояния, поскольку в нашем приложении они не пригодятся.
Все элементы формы и их иерархия по умолчанию отображаются в правой части окна Qt Designer под названием Object Inspector. Вы с лёгкостью можете удалять объекты, кликая по ним правой кнопкой мыши в этом окне. Или же вы можете выбрать их в основной форме и нажать клавишу DEL на клавиатуре.
В итоге мы имеем почти пустую форму. Единственный оставшийся объект — centralwidget , но он нам понадобится, поэтому с ним мы ничего не будем делать.
Теперь перетащите куда-нибудь в основную форму List Widget (не List View) и Push Button из Widget Box.
Макеты
Вместо использования фиксированных позиций и размеров элементов в приложении лучше использовать макеты. Фиксированные позиции и размеры у вас будут выглядеть хорошо (пока вы не измените размер окна), но вы никогда не можете быть уверены, что всё будет точно так же на других машинах и/или операционных системах.
Макеты представляют собой контейнеры для виджетов, которые будут удерживать их на определённой позиции относительно других элементов. Поэтому при изменении размера окна размер виджетов тоже будет меняться.
Давайте создадим нашу первую форму без использования макетов. Перетащите список и кнопку в форме и измените их размер, чтобы вышло вот так:
Теперь в меню Qt Designer нажмите Form, затем выберите Preview и увидите что-то похожее на скриншот выше. Выглядит хорошо, не так ли? Но вот что случится, когда мы изменим размер окна:
Наши объекты остались на тех же местах и сохранили свои размеры, несмотря на то что размер основного окна изменился и кнопку почти не видно. Вот поэтому в большинстве случаев стоит использовать макеты. Конечно, бывают случаи, когда вам, например, нужна фиксированная или минимальная/максимальная ширина объекта. Но вообще при разработке приложения лучше использовать макеты.
Основное окно уже поддерживает макеты, поэтому нам ничего не нужно добавлять в нашу форму. Просто кликните правой кнопкой мыши по Main Window в Object Inspector и выберите Lay out → Lay out vertically. Также вы можете кликнуть правой кнопкой по пустой области в форме и выбрать те же опции:
Ваши элементы должны быть в том же порядке, что и до внесённых изменений, но если это не так, то просто перетащите их на нужное место.
Так как мы использовали вертикальное размещение, все элементы, которые мы добавим, будут располагаться вертикально. Можно комбинировать размещения для получения желаемого результата. Например, горизонтальное размещение двух кнопок в вертикальном будет выглядеть так:
Если у вас не получается переместить элемент в главном окне, вы можете сделать это в окне Object Inspector.
Последние штрихи
Теперь, благодаря вертикальному размещению, наши элементы выровнены правильно. Единственное, что осталось сделать (но не обязательно), — изменить имя элементов и их текст.
В простом приложении вроде этого с одним лишь списком и кнопкой изменение имён не обязательно, так как им в любом случае просто пользоваться. Тем не менее правильное именование элементов — то, к чему стоит привыкать с самого начала.
Свойства элементов можно изменить в разделе Property Editor.
Подсказка: вы можете менять размер, передвигать или добавлять часто используемые элементы в интерфейс Qt Designer для ускорения рабочего процесса. Вы можете добавлять скрытые/закрытые части интерфейса через пункт меню View.
Нажмите на кнопку, которую вы добавили в форму. Теперь в Property Editor вы должны видеть все свойства этого элемента. В данный момент нас интересуют objectName и text в разделе QAbstractButton . Вы можете сворачивать разделы в Property Editor нажатием по названию раздела.
Измените значение objectName на btnBrowse и text на Выберите папку.
Должно получиться так:
Именем объекта списка является listWidget , что вполне подходит в данном случае.
Сохраните дизайн как design.ui в папке проекта.
Превращаем дизайн в код
Конечно, можно использовать .ui -файлы напрямую из Python-кода, однако есть и другой путь, который может показаться легче. Можно конвертировать код .ui -файла в Python-файл, который мы потом сможем импортировать и использовать. Для этого мы используем команду pyuic5 из терминала/командной строки.
Чтобы конвертировать .ui -файл в Python-файл с названием design.py , используйте следующую команду:
Пишем код
Теперь у нас есть файл design.py с нужной частью дизайна нашего приложения и мы начинать работу над созданием его логики.
Создайте файл main.py в папке, где находится design.py .
Используем дизайн
Для Python GUI приложения понадобятся следующие модули:
Также нам нужен код дизайна, который мы создали ранее, поэтому его мы тоже импортируем:
Так как файл с дизайном будет полностью перезаписываться каждый раз при изменении дизайна, мы не будем изменять его. Вместо этого мы создадим новый класс ExampleApp , который объединим с кодом дизайна для использования всех его функций:
В этом классе мы будем взаимодействовать с элементами интерфейса, добавлять соединения и всё остальное, что нам потребуется. Но для начала нам нужно инициализировать класс при запуске кода. С этим мы разберёмся в функции main() :
И чтобы выполнить эту функцию, мы воспользуемся привычной конструкцией:
В итоге main.py выглядит таким образом:
Если запустить этот код: $ python3 main.py , то наше приложение запустится!
Но нажатие на кнопку ничего не даёт, поэтому нам придётся с этим разобраться.
Добавляем функциональность в наше Python GUI приложение
Примечание Весь дальнейший код пишется внутри класса ExampleApp .
Начнём с кнопки Выберите папку. Привязать к функции событие вроде нажатия на кнопку можно следующим образом:
Добавьте эту строку в метод __init__ класса ExampleApp , чтобы выполнить привязку при запуске приложения. А теперь взглянем на неё поближе:
- self.btnBrowse : здесь btnBrowse — имя объекта, который мы определили в Qt Designer. self говорит само за себя и означает принадлежность к текущему классу;
- clicked — событие, которое мы хотим привязать. У разных элементов разные события, например, у виджетов списка есть itemSelectionChanged и т.д.;
- connect() — метод, который привязывает событие к вызову переданной функции;
- self.browse_folder — просто функция (метод), которую мы описали в классе ExampleApp .
Для открытия диалога выбора папки мы можем использовать встроенный метод QtWidgets.QFileDialog.getExistingDirectory :
Если пользователь выберет директорию, переменной directory присвоится абсолютный путь к выбранной директории, в противном случае она будет равна None . Чтобы не выполнять код дальше, если пользователь закроет диалог, мы используем команду if directory: .
Для отображения содержимого директории нам нужно импортировать os :
И получить список содержимого следующим образом:
Для добавления элементов в listWidget мы используем метод addItem() , а для удаления всех элементов у нас есть self.listWidget.clear() .
В итоге функция browse_folder должна выглядеть так:
Теперь, если запустить приложение, нажать на кнопку и выбрать директорию, мы увидим:
Так выглядит весь код нашего Python GUI приложения:
Это были основы использования Qt Designer и PyQt для разработки Python GUI приложения. Теперь вы можете спокойно изменять дизайн приложения и использовать команду pyuic5 без страха потерять написанный код.
Источник
Эта статья предназначена для тех, кто только начинает своё знакомство с созданием приложений с графическим интерфейсом (GUI) на Python. В ней мы рассмотрим основы использования PyQt в связке с Qt Designer. Шаг за шагом мы создадим простое Python GUI приложение, которое будет отображать содержимое выбранной директории.
Что нам потребуется
Нам понадобятся PyQt и Qt Designer, ну и Python, само собой.
В этой статье используется PyQt5 с Python 3, но особых различий между PyQt и PySide или их версиями для Python 2 нет.
Windows: PyQt можно скачать здесь. В комплекте с ним идёт Qt Designer.
macOS: Вы можете установить PyQt с помощью Homebrew:
$ brew install pyqt5
Скачать пакет с большинством компонентов и инструментов Qt, который содержит Qt Designer, можно по этой ссылке.
Linux: Всё нужное, вероятно, есть в репозиториях вашего дистрибутива. Qt Designer можно установить из Центра Приложений, но PyQt придётся устанавливать через терминал. Установить всё, что нам понадобится, одной командой можно, например, так:
# для Fedora:
$ sudo dnf install python3-qt5 qt-creator
# для Debian/Ubuntu:
$ sudo apt install python3-qt5 pyqt5-dev-tools qtcreator
После того как вы закончили с приготовлениями, откройте командную строку/терминал и убедитесь, что вы можете использовать команду pyuic5
. Вы должны увидеть следующее:
$ pyuic5
Error: one input ui-file must be specified
Если вы видите сообщение, что такой команды нет или что-то в таком роде, попробуйте загуглить решение проблемы для вашей операционной системы и версии PyQt.
Если вы используете Windows, то, скорее всего, путь C:Python36Scripts
(измените 36
на вашу версию Python) не прописан в вашем PATH
. Загляните в этот тред на Stack Overflow, чтобы узнать, как решить проблему.
Дизайн
Основы
Теперь, когда у нас всё готово к работе, давайте начнём с простого дизайна.
Откройте Qt Designer, где вы увидите диалог новой формы, выберите Main Window и нажмите Create.
После этого у вас должна появиться форма — шаблон для окна, размер которого можно менять и куда можно вставлять объекты из окна виджетов и т.д. Ознакомьтесь с интерфейсом, он довольно простой.
Теперь давайте немного изменим размер нашего главного окна, т.к. нам не нужно, чтобы оно было таким большим. А ещё давайте уберём автоматически добавленное меню и строку состояния, поскольку в нашем приложении они не пригодятся.
Все элементы формы и их иерархия по умолчанию отображаются в правой части окна Qt Designer под названием Object Inspector. Вы с лёгкостью можете удалять объекты, кликая по ним правой кнопкой мыши в этом окне. Или же вы можете выбрать их в основной форме и нажать клавишу DEL на клавиатуре.
В итоге мы имеем почти пустую форму. Единственный оставшийся объект — centralwidget
, но он нам понадобится, поэтому с ним мы ничего не будем делать.
Теперь перетащите куда-нибудь в основную форму List Widget (не List View) и Push Button из Widget Box.
Макеты
Вместо использования фиксированных позиций и размеров элементов в приложении лучше использовать макеты. Фиксированные позиции и размеры у вас будут выглядеть хорошо (пока вы не измените размер окна), но вы никогда не можете быть уверены, что всё будет точно так же на других машинах и/или операционных системах.
Макеты представляют собой контейнеры для виджетов, которые будут удерживать их на определённой позиции относительно других элементов. Поэтому при изменении размера окна размер виджетов тоже будет меняться.
Давайте создадим нашу первую форму без использования макетов. Перетащите список и кнопку в форме и измените их размер, чтобы вышло вот так:
Теперь в меню Qt Designer нажмите Form, затем выберите Preview и увидите что-то похожее на скриншот выше. Выглядит хорошо, не так ли? Но вот что случится, когда мы изменим размер окна:
Наши объекты остались на тех же местах и сохранили свои размеры, несмотря на то что размер основного окна изменился и кнопку почти не видно. Вот поэтому в большинстве случаев стоит использовать макеты. Конечно, бывают случаи, когда вам, например, нужна фиксированная или минимальная/максимальная ширина объекта. Но вообще при разработке приложения лучше использовать макеты.
Основное окно уже поддерживает макеты, поэтому нам ничего не нужно добавлять в нашу форму. Просто кликните правой кнопкой мыши по Main Window в Object Inspector и выберите Lay out → Lay out vertically. Также вы можете кликнуть правой кнопкой по пустой области в форме и выбрать те же опции:
Ваши элементы должны быть в том же порядке, что и до внесённых изменений, но если это не так, то просто перетащите их на нужное место.
Так как мы использовали вертикальное размещение, все элементы, которые мы добавим, будут располагаться вертикально. Можно комбинировать размещения для получения желаемого результата. Например, горизонтальное размещение двух кнопок в вертикальном будет выглядеть так:
Если у вас не получается переместить элемент в главном окне, вы можете сделать это в окне Object Inspector.
Последние штрихи
Теперь, благодаря вертикальному размещению, наши элементы выровнены правильно. Единственное, что осталось сделать (но не обязательно), — изменить имя элементов и их текст.
В простом приложении вроде этого с одним лишь списком и кнопкой изменение имён не обязательно, так как им в любом случае просто пользоваться. Тем не менее правильное именование элементов — то, к чему стоит привыкать с самого начала.
Свойства элементов можно изменить в разделе Property Editor.
Подсказка: вы можете менять размер, передвигать или добавлять часто используемые элементы в интерфейс Qt Designer для ускорения рабочего процесса. Вы можете добавлять скрытые/закрытые части интерфейса через пункт меню View.
Нажмите на кнопку, которую вы добавили в форму. Теперь в Property Editor вы должны видеть все свойства этого элемента. В данный момент нас интересуют objectName
и text
в разделе QAbstractButton
. Вы можете сворачивать разделы в Property Editor нажатием по названию раздела.
Измените значение objectName
на btnBrowse
и text
на Выберите папку.
Должно получиться так:
Именем объекта списка является listWidget
, что вполне подходит в данном случае.
Сохраните дизайн как design.ui
в папке проекта.
Превращаем дизайн в код
Конечно, можно использовать .ui
-файлы напрямую из Python-кода, однако есть и другой путь, который может показаться легче. Можно конвертировать код .ui
-файла в Python-файл, который мы потом сможем импортировать и использовать. Для этого мы используем команду pyuic5
из терминала/командной строки.
Чтобы конвертировать .ui
-файл в Python-файл с названием design.py
, используйте следующую команду:
$ pyuic5 path/to/design.ui -o output/path/to/design.py
Пишем код
Теперь у нас есть файл design.py
с нужной частью дизайна нашего приложения и мы начинать работу над созданием его логики.
Создайте файл main.py
в папке, где находится design.py
.
Другие интересные статьи по Python.
Используем дизайн
Для Python GUI приложения понадобятся следующие модули:
import sys # sys нужен для передачи argv в QApplication
from PyQt5 import QtWidgets
Также нам нужен код дизайна, который мы создали ранее, поэтому его мы тоже импортируем:
import design # Это наш конвертированный файл дизайна
Так как файл с дизайном будет полностью перезаписываться каждый раз при изменении дизайна, мы не будем изменять его. Вместо этого мы создадим новый класс ExampleApp
, который объединим с кодом дизайна для использования всех его функций:
class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
def __init__(self):
# Это здесь нужно для доступа к переменным, методам
# и т.д. в файле design.py
super().__init__()
self.setupUi(self) # Это нужно для инициализации нашего дизайна
В этом классе мы будем взаимодействовать с элементами интерфейса, добавлять соединения и всё остальное, что нам потребуется. Но для начала нам нужно инициализировать класс при запуске кода. С этим мы разберёмся в функции main()
:
def main():
app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication
window = ExampleApp() # Создаём объект класса ExampleApp
window.show() # Показываем окно
app.exec_() # и запускаем приложение
И чтобы выполнить эту функцию, мы воспользуемся привычной конструкцией:
if __name__ == '__main__': # Если мы запускаем файл напрямую, а не импортируем
main() # то запускаем функцию main()
В итоге main.py
выглядит таким образом:
import sys # sys нужен для передачи argv в QApplication
from PyQt5 import QtWidgets
import design # Это наш конвертированный файл дизайна
class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
def __init__(self):
# Это здесь нужно для доступа к переменным, методам
# и т.д. в файле design.py
super().__init__()
self.setupUi(self) # Это нужно для инициализации нашего дизайна
def main():
app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication
window = ExampleApp() # Создаём объект класса ExampleApp
window.show() # Показываем окно
app.exec_() # и запускаем приложение
if __name__ == '__main__': # Если мы запускаем файл напрямую, а не импортируем
main() # то запускаем функцию main()
Если запустить этот код: $ python3 main.py
, то наше приложение запустится!
Но нажатие на кнопку ничего не даёт, поэтому нам придётся с этим разобраться.
Добавляем функциональность в наше Python GUI приложение
Примечание Весь дальнейший код пишется внутри класса ExampleApp
.
Начнём с кнопки Выберите папку. Привязать к функции событие вроде нажатия на кнопку можно следующим образом:
self.btnBrowse.clicked.connect(self.browse_folder)
Добавьте эту строку в метод __init__
класса ExampleApp
, чтобы выполнить привязку при запуске приложения. А теперь взглянем на неё поближе:
self.btnBrowse
: здесьbtnBrowse
— имя объекта, который мы определили в Qt Designer.self
говорит само за себя и означает принадлежность к текущему классу;clicked
— событие, которое мы хотим привязать. У разных элементов разные события, например, у виджетов списка естьitemSelectionChanged
и т.д.;connect()
— метод, который привязывает событие к вызову переданной функции;self.browse_folder
— просто функция (метод), которую мы описали в классеExampleApp
.
Для открытия диалога выбора папки мы можем использовать встроенный метод QtWidgets.QFileDialog.getExistingDirectory
:
directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку")
Если пользователь выберет директорию, переменной directory
присвоится абсолютный путь к выбранной директории, в противном случае она будет равна None
. Чтобы не выполнять код дальше, если пользователь закроет диалог, мы используем команду if directory:
.
Для отображения содержимого директории нам нужно импортировать os
:
import os
И получить список содержимого следующим образом:
os.listdir(path)
Для добавления элементов в listWidget
мы используем метод addItem()
, а для удаления всех элементов у нас есть self.listWidget.clear()
.
В итоге функция browse_folder
должна выглядеть так:
def browse_folder(self):
self.listWidget.clear() # На случай, если в списке уже есть элементы
directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку")
# открыть диалог выбора директории и установить значение переменной
# равной пути к выбранной директории
if directory: # не продолжать выполнение, если пользователь не выбрал директорию
for file_name in os.listdir(directory): # для каждого файла в директории
self.listWidget.addItem(file_name) # добавить файл в listWidget
Теперь, если запустить приложение, нажать на кнопку и выбрать директорию, мы увидим:
Так выглядит весь код нашего Python GUI приложения:
import sys # sys нужен для передачи argv в QApplication
import os # Отсюда нам понадобятся методы для отображения содержимого директорий
from PyQt5 import QtWidgets
import design # Это наш конвертированный файл дизайна
class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
def __init__(self):
# Это здесь нужно для доступа к переменным, методам
# и т.д. в файле design.py
super().__init__()
self.setupUi(self) # Это нужно для инициализации нашего дизайна
self.btnBrowse.clicked.connect(self.browse_folder) # Выполнить функцию browse_folder
# при нажатии кнопки
def browse_folder(self):
self.listWidget.clear() # На случай, если в списке уже есть элементы
directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку")
# открыть диалог выбора директории и установить значение переменной
# равной пути к выбранной директории
if directory: # не продолжать выполнение, если пользователь не выбрал директорию
for file_name in os.listdir(directory): # для каждого файла в директории
self.listWidget.addItem(file_name) # добавить файл в listWidget
def main():
app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication
window = ExampleApp() # Создаём объект класса ExampleApp
window.show() # Показываем окно
app.exec_() # и запускаем приложение
if __name__ == '__main__': # Если мы запускаем файл напрямую, а не импортируем
main() # то запускаем функцию main()
Это были основы использования Qt Designer и PyQt для разработки Python GUI приложения. Теперь вы можете спокойно изменять дизайн приложения и использовать команду pyuic5
без страха потерять написанный код.
Перевод статьи «PyQt: Getting started with PyQt and Qt Designer»
This tutorial covers the basics of how to create GUI’s in Python using PyQt5. I will demonstrate how to find the designer and basic usage, converting .ui to .py, running the output file and connecting events to methods.
- Important First Note
- Setting up the Environment
- Using the Designer
- Locating
- Using the Designer
- Creating a Simple Window
- Converting .ui to .py
- Running the Output and Hooking up the Button
- More Advanced Example
- Creating Interface
- Connecting Events to Methods
- Linking the Image Button
- Linking the Add to List Button
Important First Note
Please understand this process is not the recommended method when using PyQt5 designed / pyuic; this is simply a demonstration of designing a UI using the PyQt5 designer tool, generating Python code and then partially understanding what comes out.
This tutorial is not obsolete however as it can help you get a basic grasp of how to use PyQt5.
The reason the method demonstrated below is not recommended is due to the fact if you use pyuic again to turn a .ui file into a .py file, it will overwrite all your changes to the file. I have a tutorial at How to Import a PyQt5 .ui File in a Python GUI which better explains how you should import the generated script so your changes will not be overwritten.
If you only intend on using the generated code as an initial layout and not re-generate the code (I do this a lot), you may find this method easier than importing as you can make changes to the layout a lot easier this way.
Setting up the Environment
For this tutorial, you will need a version of Python equal to or above 3.5. I do however recommend to get a more recent version than 3.5 as I had issues with 3.5.2; a simple upgrade to 3.6.6 fixed this. If you don’t know where to get Python, look here.
Now you will want to install pyqt5 and pyqt5-tools. To do this, we can use pip. Call the two commands python -m pip install pyqt5
and python -m pip install pyqt5-tools
. After each command completes, make sure to verify that they installed properly by checking if it says they were installed successfully.
You should now be able to execute the following in Python with no errors:
If you have issues installing PyQt5 for some reason, you could try the installers at its sourceforge page.
Using the Designer
When you ran the pip install pyqt5-tools
command, this installed tools that we can use to help with building GUIs.
Locating
First, we need to locate where they are now, to do this we can run the following code in Python:
import site
print (site.getsitepackages())
This will print out a couple of paths, for me it prints: ['C:\Python36', 'C:\Python36\lib\site-packages']
. Here we can see my Python distribution location and the site-packages folder. Open up a file explorer and navigate to the site-packages folder. In this folder, you then want to locate the pyqt5-tools
folder and open it. In this folder, you should find a few files, one named designer.exe.
After recent updates to pyqt5-tools
, designer.exe has been moved to the ‘Scripts’ folder in your Python distribution. To find this using the paths we found before, go to the first path returned (‘C:Python36’ in my case) and then go into the ‘Scripts’ folder; you should find designer.exe in here.
Using the Designer
designer.exe is the program that we will use to make designing GUIs a lot easier; remember the location of this or create a shortcut to it and then run it (double click if you wish). You will be welcomed with a selection window; select «Main Window» and then click «Create».
You will now be shown an empty window in the middle of the designer’s window with widget options on the left and some other windows to the right.
On the left, you can drag widgets from the drop-downs onto the MainWindow object in the centre. On the right, in the Object Inspector, you can see the current widgets in your window. Right below that is the Property Editor that allows you to modify the widget currently selected.
Creating a Simple Window
For this example, we will be just putting a button that prints «Hello World!» when pressed in the Window; soon we will work with a larger example when the basics are out of the way.
First, make your window a bit smaller by clicking and dragging the bottom right of the window (or any part on the edge) to change the size as you would do on any other window. Now find the «Push Button» widget under the Buttons section (on the left) and drag it into the window anywhere. You can double click on the button now to rename the text in it; set it to «Print Message».
You may now want to change the size of the button, to do this click on the button until there are blue squares on each of its corners and edges. Use these blue squares to re-size the button to a size you want.
When you are happy with what you have done (this is just a simple practice) then click File -> Save in the top left and save it somewhere where you will remember; I will save it as ‘printMessage.ui’ on my desktop.
Code download: printMessage.ui
Converting .ui to .py
Now that we have our .ui file, we can convert it into Python code so we can modify and run it.
To do this we need to locate pyuic5. pyuic5 converts .ui to .py in one simple command and is located in the ‘Scripts’ folder in your Python distribution. If you don’t know where this is, execute the following:
import sys
import os
print (os.path.dirname(sys.executable))
You will be provided with a path of where your python distribution is located; mine is at C:Python36
(we saw this before when looking for the designer). Now go to this directory and open the ‘Scripts’ folder in there.
In this folder you will see a few executables to make Python in the terminal easier, you should also be able to see a file named pyuic5.exe
; this is what we are going to use. Open cmd and then use the cd command to get to the directory; for example, I will execute cd C:Python36Scripts
in cmd. Now if you type pyuic5
you should be provided with a small error message saying «Error: one input ui-file must be specified»; this is good, we are in the right place.
To convert we now need to pass in the .ui file we created before and decide on an output filename and location. My .ui file is on my desktop currently so I will put the created .py file on the desktop also to make it easier. Now we can convert using pyuic5 -x <.ui file> -o <output.py file>
, for example I will use pyuic5 -x "C:UsersBrentDesktopprintMessage.ui" -o "C:UsersBrentDesktopprintMessage1.py"
. This should take not very long at all and show no errors; the python script you declared after -o will now exist — for me, a file called printMessage1.py is now on my desktop.
Running the Output and Hooking up the Button
Now that you have the .py file containing the ui code, open it in IDLE or whatever IDE you use. Your code should look something like this:
Code download: printMessage1.py
Run the code and then wait for the GUI to appear; it currently won’t do anything when you press the button so we will set that up.
Go back into the code for this GUI and look in the setupUi definition. You should see a class variable called self.pushButton
which later has its text set to «Print Message» in the retranslateUi definition below. This is the object of our button that we need to make do something.
First, we need to create our method, this method can be in the global scope or in the class scope, for simplicity I will put it in the class scope. After the retranslateUi definition, create a new class called printMessage
that takes self as an argument since it is part of the class now. Inside this put what you want the script do to when you press the button, for this example, I will print «Hello World!».
def printMessage(self):
print ("Hello World!")
Now that you have created the method to run, we can attach it to the button. Using the button variable we found before, we can call .clicked.connect() on it passing in the name of our method we just created (make sure to remember self.
for class variables). Put this line at the bottom of the setupUi definition so it will be executed when the GUI is built.
self.pushButton.clicked.connect(self.printMessage)
Remember to not include () when passing the method here or it will not work.
Your script should now look something like this, don’t worry if it is a bit different.
Code download: printMessage2.py
Run the code again and now when you press the button you should see that the script runs the code that you defined in the method you attached to the button.
More Advanced Example
In this next example, I will show you how to put images in the GUI, add a selection dialog box and add data to a table.
Creating Interface
Open the designer back up and create a new MainWindow. Now create and position the 5 widgets described below:
— Label (in Display Widgets): This label will be the widget we use to show the image
— PushButton (in Buttons): This button will allow us to select the image to show in the Label
— ListWidget (in Item Widgets): This will hold and display entries we add to it
— LineEdit (in Input Widgets): This will allow us to enter what we want into the table
— PushButton (in Buttons): This will add the item in the LineEdit to the table
If you click on a widget, for example, the button that will be selecting the button, the Property Editor on the right will display all the options for that object. In there you can edit things like the exact size/position, borders (frames), tooltips and fonts.
First, we will want to edit the Label that is holding the image; click on the label to open it up in the Property Editor. Find «text» under the QLabel section and delete the text, this is the same as double-clicking and removing the text. Now go to the QFrame heading and change «frameShape» to box, this will but a border around the image.
Now click on the select image button and in the QWidget header go to «font». This has many options inside of this so play around to get a font you like (you can leave it if you want). Your GUI should now look something like this:
To help you later on, you can also change the «objectName» under QObject in the Property Editor for all widgets so you can identify them easier later. Here is what I named mine:
— Select Image Button: selectImageBtn
— Image Label: imageLbl
— LineEdit: lineEdit
— Add button: addBtn
— ListWidget: listWidget
Code download: MainWindowAdvanced.ui
Like we did before, convert this .ui file (after saving it) to a .py file.
Connecting Events to Methods
Now we need to connect all the actions together. The select image button will need to be connected to a method that displays an image selection dialog which will then put an image in the label. Also, we will need to make the ‘add’ button add the text in the lineEdit object into the listWidget object.
Your converted .py code should currently look something like this: Code download: MainWindowAdvanced1.py
If you open your .py file in IDLE, you can see that the names we gave each widget have passed through to the names of the actual objects. I also recommend running the code now to make sure it works.
Linking the Image Button
First, you will want to create a class definition called setImage
; make sure this takes self as it is a class definition. In this method, we want to ask the user for an image (not just any file). If they provide a file, we then need to create a pixmap object and then set the pixmap object to the image label. Before we set it, it is ideal to scale the image to fit inside the label without stretching and aligning it to the centre. Your method will look like this:
def setImage(self):
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)") # Ask for file
if fileName: # If the user gives a file
pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image
pixmap = pixmap.scaled(self.imageLbl.width(), self.imageLbl.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
self.imageLbl.setPixmap(pixmap) # Set the pixmap onto the label
self.imageLbl.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
In the QtWidgets.QFileDialog.getOpenFileName method call, you can see I have passed the string "Image Files (*.png *.jpg *jpeg *.bmp)"
. This declares the type of files I will accept. If you want to accept any file, remove this string completely. If you want to make it so the user could switch it to all files themselves, set it to "Image Files (*.png *.jpg *jpeg *.bmp);;All Files (*)"
; play around with this to get the idea of what is going on, you can add more file extensions and selections if wanted.
Now we need to attach the button to the definition. This can simply be done using the connect method we used previously; make sure to put it at the bottom of the setupUi definition as we did before:
self.selectImageBtn.clicked.connect(self.setImage)
Run the script and make sure that your button works. Initially, the label will be clear but each time you select a file it should change to the selected file.
Linking the Add to List Button
We will now need to create another class definition called addItem
like before. In this method, we need to get the value of the lineEdit object and then clear it. We can then simply add the value we just got to the listWidget. After you have done that, the method should look like this:
def addItem(self):
value = self.lineEdit.text() # Get the value of the lineEdit
self.lineEdit.clear() # Clear the text
self.listWidget.addItem(value) # Add the value we got to the list
And then like before, we need to connect the button to the method just under the last one we did:
self.addBtn.clicked.connect(self.addItem)
Running the script now you should be able to type in the text edit item and then press add for the item to go into the list.
Code download: MainWindowAdvanced2.py