Как изменить текст qlineedit

Виджет QLineEdit - это однострочный текстовый редактор. Более...

QLineEdit Class

Виджет QLineEdit — это однострочный текстовый редактор. Более…

Header: #include <QLineEdit>
CMake: find_package(Qt6 COMPONENTS Widgets REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Widgets)
qmake: виджеты QT +=
Inherits: QWidget
  • Список всех членов,включая унаследованных членов

Public Types

enum ActionPosition { LeadingPosition, TrailingPosition }
enum EchoMode {Нормальный, NoEcho, Пароль, ПарольEchoOnEdit}

Properties

  • acceptInput : const bool
  • выравнивание : Qt::Выравнивание
  • clearButtonEnabled : логическое
  • курсорMoveStyle : Qt::CursorMoveStyle
  • Позиция курсора : int
  • displayText : константа QString
  • dragEnabled : логическое
  • эхорежим : эхомод
  • кадр : бул
  • hasSelectedText :
  • маска ввода : QString
  • maxLength :
  • изменено : логическое значение
  • заполнительтекст : QString
  • только для чтения : логическое
  • redoAvailable : const bool
  • selectedText : константа QString
  • текст : QString
  • undoAvailable : const bool

Public Functions

Реализованные общественные функции

virtual bool event(QEvent *e) override
virtual QVariant inputMethodQuery(Qt::InputMethodQueryproperty) const переопределить
virtual QSize minSizeHint () переопределить
virtual QSize sizeHint () переопределение const
virtual void timerEvent(QTimerEvent *e) override

Public Slots

Signals

Protected Functions

Реализованные защищенные функции

Detailed Description

Редактирование строки позволяет пользователю вводить и редактировать одну строку обычного текста с помощью полезного набора функций редактирования, включая отмену и повтор, вырезание и вставку, а также перетаскивание (см. setDragEnabled ()).

Изменяя echoMode () редактирования строки, его также можно использовать как поле «только для записи» для таких входных данных, как пароли.

Длина текста может быть ограничена maxLength (). Текст может быть произвольно ограничен с помощью валидатора () или inputMask () или обоих. При переключении между валидатором и маской ввода в одной и той же строке редактирования лучше всего очистить валидатор или маску ввода, чтобы предотвратить неопределенное поведение.

Связанный класс — QTextEdit, который позволяет редактировать многострочный форматированный текст.

Вы можете изменить текст с помощью setText () или insert (). Текст извлекается с помощью text (); отображаемый текст (который может отличаться, см. EchoMode ) извлекается с помощью displayText (). Текст можно выделить с помощью setSelection () или selectAll (), а выделение можно вырезать (), скопировать ()ied и вставить ()d. Текст можно выровнять с помощью setAlignment ().

При изменении текста испускается сигнал textChanged (); когда текст изменяется иначе, чем вызовом setText (), выдается сигнал textEdited (); при перемещении курсора испускается сигнал cursorPositionChanged (); и когда нажата клавиша Return или Enter, выдается сигнал returnPressed ().

Когда редактирование завершено, либо из-за того, что редактирование строки потеряло фокус, либо из-за нажатия клавиши Return/Enter, выдается сигнал editingFinished (). Обратите внимание, что если фокус потерян без внесения каких-либо изменений, сигнал editFinished () не будет выдан.

Обратите внимание, что если для редактирования строки установлен валидатор, сигналы returnPressed ()/ editingFinished () будут выдаваться только в том случае, если валидатор вернет QValidator::Acceptable .

По умолчанию QLineEdits имеют рамку, указанную в руководствах по стилю платформы; вы можете отключить его, вызвав setFrame (false).

Ниже описаны привязки клавиш по умолчанию.Редактирование строки также предоставляет контекстное меню (обычно вызываемое правой кнопкой мыши),в котором представлены некоторые из этих опций редактирования.

Keypress Action
Left Arrow Перемещает курсор на один персонаж влево.
Shift+Left Arrow Перемещает и выбирает текст на один символ влево.
Right Arrow Перемещает курсор на один персонаж вправо.
Shift+Right Arrow Перемещает и выбирает текст на один символ справа.
Home Перемещает курсор в начало строки.
End Перемещает курсор в конец строки.
Backspace Удаляет символ слева от курсора.
Ctrl+Backspace Удаляет слово слева от курсора.
Delete Удаляет символ справа от курсора.
Ctrl+Delete Удаляет слово справа от курсора.
Ctrl+A Select all.
Ctrl+C Скопирует выделенный текст в буфер обмена.
Ctrl+Insert Скопирует выделенный текст в буфер обмена.
Ctrl+K Уходит в конец очереди.
Ctrl+V Вставляет текст буфера обмена в строку редактирования.
Shift+Insert Вставляет текст буфера обмена в строку редактирования.
Ctrl+X Удаляет выбранный текст и копирует его в буфер обмена.
Shift+Delete Удаляет выбранный текст и копирует его в буфер обмена.
Ctrl+Z Отменяет последнюю операцию.
Ctrl+Y Переделывает последнюю незавершенную операцию.

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

См. также QTextEdit , QLabel , QComboBox , GUI Design Handbook: Field, Entry и Line Edits Example .

Тип члена Документация

[since 5.2] версии 5.2] перечисление QLineEdit :: ActionPosition

Этот тип перечисления описывает,как редактирование строки должно отображать виджеты действий,которые необходимо добавить.

Constant Value Description
QLineEdit::LeadingPosition 0 Виджет отображается слева от текста при использовании направления компоновки Qt::LeftToRight или справа при использовании Qt::RightToLeft , соответственно.
QLineEdit::TrailingPosition 1 Виджет отображается справа от текста при использовании направления компоновки Qt::LeftToRight или слева при использовании Qt::RightToLeft соответственно.

Это перечисление было введено или изменено в Qt 5.2.

См. также addAction (), removeAction () и QWidget::layoutDirection .

enum QLineEdit::EchoMode

Этот тип перечисления описывает,как редактирование строки должно отображать ее содержимое.

Constant Value Description
QLineEdit::Normal 0 Отображение символов в том виде,в каком они были введены.По умолчанию.
QLineEdit::NoEcho 1 Ничего не показывайте.Это может быть уместно для паролей,где даже длина пароля должна храниться в секрете.
QLineEdit::Password 2 Отображать символы маски пароля,зависящие от платформы,вместо символов,которые были введены на самом деле.
QLineEdit::PasswordEchoOnEdit 3 Отображать символы по мере их ввода при редактировании, в противном случае отображать символы, как с Password .

См. также setEchoMode () и echoMode ().

Property Documentation

[read-only] acceptInput: const bool

Это свойство определяет, удовлетворяет ли ввод inputMask и валидатору.

По умолчанию это свойство true .

Access functions:

bool hasAcceptableInput() const

См. также setInputMask () и setValidator ().


© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qlineedit.html


Qt

6.2

  • QLine Class

    Класс QLine предоставляет двумерный вектор с целочисленной точностью.

  • QLinearGradient Class

    Класс QLinearGradient используется в сочетании с QBrush для задания линейных градиентов,интерполирующих цвета между начальной и конечной точками.

  • alignment :

    Это свойство содержит выравнивание редактирования строки.

  • Документация по функциям члена

    Создает строку редактирования, содержащую текстовое содержимое.


QLineEdit object is the most commonly used input field. It provides a box in which one line of text can be entered. In order to enter multi-line text, QTextEdit object is required.

The following table lists a few important methods of QLineEdit class −

Sr.No. Methods & Description
1

setAlignment()

Aligns the text as per alignment constants

Qt.AlignLeft

Qt.AlignRight

Qt.AlignCenter

Qt.AlignJustify

2

clear()

Erases the contents

3

setEchoMode()

Controls the appearance of the text inside the box. Echomode values are −

QLineEdit.Normal

QLineEdit.NoEcho

QLineEdit.Password

QLineEdit.PasswordEchoOnEdit

4

setMaxLength()

Sets the maximum number of characters for input

5

setReadOnly()

Makes the text box non-editable

6

setText()

Programmatically sets the text

7

text()

Retrieves text in the field

8

setValidator()

Sets the validation rules. Available validators are

QIntValidator − Restricts input to integer

QDoubleValidator − Fraction part of number limited to specified decimals

QRegexpValidator − Checks input against a Regex expression

9

setInputMask()

Applies mask of combination of characters for input

10

setFont()

Displays the contents QFont object

QLineEdit object emits the following signals −

Given below are the most commonly used methods of signals.

Sr.No. Methods & Description
1

cursorPositionChanged()

Whenever the cursor moves

2

editingFinished()

When you press ‘Enter’ or the field loses focus

3

returnPressed()

When you press ‘Enter’

4

selectionChanged()

Whenever the selected text changes

5

textChanged()

As text in the box changes either by input or by programmatic means

6

textEdited()

Whenever the text is edited

Example

QLineEdit objects in this example demonstrate use of some of these methods.

First field e1 shows text using a custom font, in right alignment and allows integer input. Second field restricts input to a number with 2 digits after decimal point. An input mask for entering the phone number is applied on the third field. textChanged() signal on the field e4 is connected to textchanged() slot method.

Contents of e5 field are echoed in password form as its EchoMode property is set to Password. Its editingfinished() signal is connected to presenter() method. So, once the user presses the Enter key, the function will be executed. The field e6 shows a default text, which cannot be edited as it is set to read only.

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
   app = QApplication(sys.argv)
   win = QWidget()
	
   e1 = QLineEdit()
   e1.setValidator(QIntValidator())
   e1.setMaxLength(4)
   e1.setAlignment(Qt.AlignRight)
   e1.setFont(QFont("Arial",20))
	
   e2 = QLineEdit()
   e2.setValidator(QDoubleValidator(0.99,99.99,2))
	
   flo = QFormLayout()
   flo.addRow("integer validator", e1)
   flo.addRow("Double validator",e2)
	
   e3 = QLineEdit()
   e3.setInputMask('+99_9999_999999')
   flo.addRow("Input Mask",e3)
	
   e4 = QLineEdit()
   e4.textChanged.connect(textchanged)
   flo.addRow("Text changed",e4)
	
   e5 = QLineEdit()
   e5.setEchoMode(QLineEdit.Password)
   flo.addRow("Password",e5)
	
   e6 = QLineEdit("Hello Python")
   e6.setReadOnly(True)
   flo.addRow("Read Only",e6)
	
   e5.editingFinished.connect(enterPress)
   win.setLayout(flo)
   win.setWindowTitle("PyQt")
   win.show()
	
   sys.exit(app.exec_())

def textchanged(text):
   print "contents of text box: "+text
	
def enterPress():
   print "edited"

if __name__ == '__main__':
   window()

Output

The above code produces the following output −

QLineEdit Widget Output

contents of text box: h
contents of text box: he
contents of text box: hel
contents of text box: hell
contents of text box: hello
editing finished

pyqt_basic_widgets.htm


QLineEdit object is the most commonly used input field. It provides a box in which one line of text can be entered. In order to enter multi-line text, QTextEdit object is required.

The following table lists a few important methods of QLineEdit class −

Sr.No. Methods & Description
1

setAlignment()

Aligns the text as per alignment constants

Qt.AlignLeft

Qt.AlignRight

Qt.AlignCenter

Qt.AlignJustify

2

clear()

Erases the contents

3

setEchoMode()

Controls the appearance of the text inside the box. Echomode values are −

QLineEdit.Normal

QLineEdit.NoEcho

QLineEdit.Password

QLineEdit.PasswordEchoOnEdit

4

setMaxLength()

Sets the maximum number of characters for input

5

setReadOnly()

Makes the text box non-editable

6

setText()

Programmatically sets the text

7

text()

Retrieves text in the field

8

setValidator()

Sets the validation rules. Available validators are

QIntValidator − Restricts input to integer

QDoubleValidator − Fraction part of number limited to specified decimals

QRegexpValidator − Checks input against a Regex expression

9

setInputMask()

Applies mask of combination of characters for input

10

setFont()

Displays the contents QFont object

QLineEdit object emits the following signals −

Given below are the most commonly used methods of signals.

Sr.No. Methods & Description
1

cursorPositionChanged()

Whenever the cursor moves

2

editingFinished()

When you press ‘Enter’ or the field loses focus

3

returnPressed()

When you press ‘Enter’

4

selectionChanged()

Whenever the selected text changes

5

textChanged()

As text in the box changes either by input or by programmatic means

6

textEdited()

Whenever the text is edited

Example

QLineEdit objects in this example demonstrate use of some of these methods.

First field e1 shows text using a custom font, in right alignment and allows integer input. Second field restricts input to a number with 2 digits after decimal point. An input mask for entering the phone number is applied on the third field. textChanged() signal on the field e4 is connected to textchanged() slot method.

Contents of e5 field are echoed in password form as its EchoMode property is set to Password. Its editingfinished() signal is connected to presenter() method. So, once the user presses the Enter key, the function will be executed. The field e6 shows a default text, which cannot be edited as it is set to read only.

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
   app = QApplication(sys.argv)
   win = QWidget()
	
   e1 = QLineEdit()
   e1.setValidator(QIntValidator())
   e1.setMaxLength(4)
   e1.setAlignment(Qt.AlignRight)
   e1.setFont(QFont("Arial",20))
	
   e2 = QLineEdit()
   e2.setValidator(QDoubleValidator(0.99,99.99,2))
	
   flo = QFormLayout()
   flo.addRow("integer validator", e1)
   flo.addRow("Double validator",e2)
	
   e3 = QLineEdit()
   e3.setInputMask('+99_9999_999999')
   flo.addRow("Input Mask",e3)
	
   e4 = QLineEdit()
   e4.textChanged.connect(textchanged)
   flo.addRow("Text changed",e4)
	
   e5 = QLineEdit()
   e5.setEchoMode(QLineEdit.Password)
   flo.addRow("Password",e5)
	
   e6 = QLineEdit("Hello Python")
   e6.setReadOnly(True)
   flo.addRow("Read Only",e6)
	
   e5.editingFinished.connect(enterPress)
   win.setLayout(flo)
   win.setWindowTitle("PyQt")
   win.show()
	
   sys.exit(app.exec_())

def textchanged(text):
   print "contents of text box: "+text
	
def enterPress():
   print "edited"

if __name__ == '__main__':
   window()

Output

The above code produces the following output −

QLineEdit Widget Output

contents of text box: h
contents of text box: he
contents of text box: hel
contents of text box: hell
contents of text box: hello
editing finished

pyqt_basic_widgets.htm

PyQt5 является одним из наиболее часто используемых модулей для создания GUI приложений в Python, и это связанно с его простотой, о которой вы узнаете далее.

Еще одна замечательная особенность, которая вдохновляет разработчиков пользоваться PyQt5 – это PyQt5 Designer, благодаря которому можно создавать сложные GUI приложения достаточно быстро. Вам нужно только перетаскивать свои виджеты для создания собственной формы. У нас есть готовый сборник 54 уроков по другому фреймворку wxPython.

  • Создаем простой калькулятор в PyQt5
  • Создаем игру Сапёр на PyQt5
  • История курса рубля на PyQt5 + XML от ЦБ РФ

Другие фреймворки

  • wxPython
  • Tkinter
  • PyCairo

В данном руководстве по PyQt5, я буду использовать Python 3.6 на Ubuntu и предположение, что вы уже имеете базовое представление о Python.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Звучит замечательно! Начнем с установки PyQt5, и затем перейдем к тому, как разрабатывать GUI приложение с примерами.

Краткое содержание

  • 1 Установка PyQt5
  • 1.1 Установка PyQt5 через pip
  • 1.2 Установка PyQt5 из исходников на Linux
  • 1.3 Установка PyQt5 из исходников на Windows
  • 2 Устанавливаем PyQt5 Designer
  • 2.1 Где находится дизайнер PyQt5?
  • 3 Как использовать дизайнер PyQt5
  • 4 Разница между QDialog, QMainWindow, и QWidget
  • 5 Загрузка .ui против конвертации .ui в .py
  • 5.1 Загрузка файла .ui в ваш код Python
  • 5.2 Конвертация файла .ui в .py file при помощи pyuic5
  • 6 Виджет QLabel
  • 6.1 Меняем шрифт QLabel
  • 6.2 Меняем размер QLabel
  • 6.3 Меняем текст в QLabel
  • 7 Виджет QLineEdit
  • 7.1 Метод setStyleSheet()
  • 8 Виджет QPushButton
  • 9 Визуальный редактор signal/slot
  • 10 Как испускать сигналы в PyQt5
  • 10.1 Как использовать сигнал в PyQt5
  • 10.2 Переопределение сигнала (события) в PyQt5
  • 11 Виджет QComboBox
  • 11.1 Получаем все элементы из QComboBox
  • 11.2 Выбор одного элемента из QCombobox
  • 12 QTableWidget
  • 12.1 Очистка содержимого QTableWidget
  • 12.2 Заполнение QTableWidget из кода
  • 12.3 Делаем QTableWidget нередактируемым (только для чтения)
  • 12.4 Заголовок для столбцов в QTableWidget
  • 12.5 Как сортировать QTableWidget
  • 12.6 Добавляем QComboBox в QTableWidget
  • 12.7 QProgressBar в QTableWidget
  • 13 Компиляция Python приложения

Установка PyQt5

Существует две версии PyQt5: коммерческая и бесплатная версия GPL, которой мы будем пользоваться в этом руководстве.

Есть два способа установки PyQt5:

  • Установка PyQt5 через pip
  • Установка PyQt5 из исходников на Linux

Установка PyQt5 через pip

Чтобы установить PyQt5 при помощи pip, выполните следующую команду:

Чтобы убедиться в том, что установка прошла успешно, запустите следующий код:

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

Установка PyQt5 из исходников на Linux

Для установки PyQt5 из исходника, вам нужно сделать следующее:

  1. Установить SIP;
  2. Скачать исходник PyQt5;
  3. Настроить и установить.

Как вы возможно знаете, PyQt5 связывает Python с популярной библиотекой Qt, которая написана на С++.

Инструмент, который создает эту связь, называется SIP. Так что для установки PyQt5 из исходника, вам для начала нужно установить SIP.

Для установки SIP, запустите следующую команду:

sudo pip3 install pyqt5sip

Теперь вы можете загрузить и установить исходник PyQt5.

Исходники

Скачать исходник PyQt5 можно отсюда: https://www.riverbankcomputing.com/software/pyqt/download5

Руководство по PyQt5

Внимание: На момент прочтения статьи возможно появилась новая версия которая отличается от той что в скрине. Версия на текущий момент 5.11.3, вы должны самостоятельно скопировать ссылку с сайта и предоставить её в wget. Заметьте, что обновить версию придется во всех ниже предоставленных командах.

wget https://sourceforge.net/projects/pyqt/files/PyQt5/PyQt5.11.3/PyQt5_gpl5.11.3.tar.gz

tar xvzf PyQt5_gpl5.11.3.tar.gz

cd PyQt5_gpl5.11.3

Мы распаковали сжатый исходник, теперь запустите следующие команды внутри корня папки:

sudo python3 configure.py

sudo make

sudo make install

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

Установка PyQt5 из исходников на Windows

Скачивайте и распакуйте архив с сайта которого мы указали выше.

Руководство по PyQt5

Так как SIP требует компилятор GCC, вам нужно установить MinGW, который является портом Windows для компилятора Linux, GCC.

Единственное, что нужно поменять — это момент конфигурации. Вам нужно сообщить Python о платформе.

Это можно выполнить следующим образом:

python configure.py platform win32g++

make

make install

Поздравляем! Вы успешно установили PyQt5 из исходника.

Установка PyQt5 Designer

Есть два способа создания GUI приложений при помощи PyQt5:

  1. Дизайн виджетов при помощи кода;
  2. Использование PyQt5 Designer.

В этом руководстве мы используем PyQt5 Designer, который упрощает процесс на столько, что вы можете выполнить большой объем работы за секунды.

Недорого заказать услуги SMM продвижения более чем в 9 социальных сетях можно на https://doctorsmm.com/. С помощью этого сервиса можно раскрутить свою группу, страницу, сообщество или канал и набрать нужное количество подписчиков, лайков, репостов и других соцсигналов.

Дизайнер PyQt5 поставляется вместе с набором инструментов. Для его установки, вам нужно установить эти инструменты.

$ pip3 install pyqt5tools

Где находится дизайнер PyQt5?

После удачной установки, вы можете найти дизайнер PyQt5 здесь:

C:Program FilesPython36Libsitepackagespyqt5tools

Кстати, если вы установили только для своего текущего пользовательского аккаунта, вы найдете дизайнер PyQt5 вот здесь:

C:UsersPythonUserAppDataLocalProgramsPythonPython3632Libsitepackages pyqt5tools

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

Как использовать дизайнер PyQt5

Откройте designer.exe и увидите диалоговое окно, спрашивающее о том, какую форму шаблона вы предпочитаете.

Руководство по PyQt5

Существует пять видов доступных шаблонов:

  • Диалоговое окно с кнопками внизу (Dialog with Buttons Bottom): создает форму с кнопками ОК и Cancel в правом нижнем углу формы.
  • Диалоговое окно с кнопками справа (Dialog with Buttons Right): создает форму с кнопками OK и Cancel в верхнем правом углу формы.
  • Диалоговое окно без кнопок (Dialog without Buttons): создает пустую форму;
  • Главное окно (Main Window): создает окно с панелью меню и набором инструментов. Унаследовано из QmainWindow;
  • Виджет (Widget): создает виджет, наследуемый из класса Qwidget. Отличается от диалоговых шаблонов тем, что они наследуются из класса QВialog

Итак, у нас есть три типа шаблонов. В чем между ними разница?

Разница между QDialog, QMainWindow, и Qwidget

  • QWidget – это базовый класс для всех GUI Элементов в PyQt5;
  • QDialog используется при запросе чего-либо у пользователя, например, запросы о принятии или отклонении чего-нибудь. Основан на Qwidget.
  • QMainWindow – самый большой шаблон, где вы можете разместить вашу панель инструментов, меню, статус и другие виджеты. Не имеет встроенных кнопок разрешения, таких как в QDialog.

Загрузка .ui против конвертации .ui в .py

В данном руководстве мы используем PyQt5 Designer, но перед тем, как мы пойдем дальше, давайте рассмотрим, как еще мы можем использовать сгенерированный файл из PyQt5 Designer.

Нам нужно открыть PyQt5 Designer, выбрать шаблон Main Window и нажать кнопку create.

Руководство по PyQt5

Далее в файловом меню (File), нажимаем сохранить. PyQt5 Designer экспортирует вашу форму в XML с расширением .ui.

Для использования этого дизайна, у вас есть два способа:

  • Загрузить файл .ui в ваш код Python;
  • Конвертировать файл .ui в файл .py при помощи pyuic5;

Загрузка .ui файла в ваш код Python

Чтобы загрузить файл .ui в ваш код Python, вы можете использовать функцию loadUI() из uic вот так:

from PyQt5 import QtWidgets, uic

import sys

app = QtWidgets.QApplication([])

win = uic.loadUi(«mydesign.ui») # расположение вашего файла .ui

win.show()

sys.exit(app.exec())

Если вы запустите код, вы увидите окно, в котором есть только ярлык.

Это значит, что ui файл успешно загрузился!

Мы используем sys.exit(app.exec()) вместо использования app.exec() напрямую, чтобы выслать правильный код статуса, родительский процесс, или процесс вызова.

Если вы использовали app.exec() напрямую, приложение отправит ноль, что говорит об успехе, и это произойдет даже если приложение упадет.

Конвертация файла .ui в файл .py при помощи pyuic5

Давайте попробуем еще один способ и конвертируем файл .ui в код Python:

$ pyuic5 mydesign.ui o mydesign.py

Да! Был создан новый файл под названием mydesign.py. Теперь, импортируем этот файл, чтобы показать его в окне.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

from PyQt5 import QtWidgets

from mydesign import Ui_MainWindow  # импорт нашего сгенерированного файла

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Если запустите этот код, вы должны увидеть то же окно, что было в первом методе.

Преимущество использования второго метода — это автоматическое завершение, которое выполнит IDE, так как все ваши виджеты импортированы. В то же время, пользуясь первым методом, вы просто загружаете файл .ui и вам нужно обращать внимание на названия ваших виджетов.

Еще одно преимущество использования второго метода. Скорость: вам не нужен парсинг XML для загрузки UI.

Так что мы можем сказать, что конвертация файла .ui в файл .py – безопаснее для кодинга и быстрее для загрузки.

Настало время закатить рукава и поиграть с виджетами PyQt5.

Для внесение виджета QLabel в вашу форму, выполните следующее:

  • Откройте PyQt5 Designer и выберите шаблон Main Window;
  • Перетяните виджет ярлыка из бокса слева;

Руководство по PyQt5

Сохраните дизайн в файл как qlabel.ui и конвертируйте его в файл qlabel.py. Теперь поработаем с ярлыком виджета при помощи кода.

pyuic5 qlabel.ui o qlabel.py

Результат:
Руководство по PyQt5

Меняем шрифт QLabel

Чтобы поменять шрифт QLabel, используйте метод setFont() и передайте ему QFont следующим образом:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

from PyQt5 import QtWidgets, QtGui

from mydesign import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.label.setFont(

            QtGui.QFont(‘SansSerif’, 30)

        ) # Изменение шрифта и размера

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

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

Меняем размер QLabel

Чтобы поменять размер QLabel, вам нужно указать его геометрию при помощи метода setGeometry(), вот так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

from PyQt5 import QtWidgets, QtGui,QtCore

from mydesign import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.label.setFont(

            QtGui.QFont(‘SansSerif’, 30)

        )

        self.ui.label.setGeometry(

            QtCore.QRect(10, 10, 200, 200)

        ) # изменить геометрию ярлыка

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Руководство по PyQt5

Меняем текст в QLabel

Чтобы изменить текст в QLabel, вы можете использовать метод setText(), вот так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

from PyQt5 import QtWidgets, QtGui,QtCore

from qlabel import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.label.setFont(

            QtGui.QFont(‘SansSerif’, 30)

        )

        self.ui.label.setGeometry(

            QtCore.QRect(10, 10, 200, 200)

        )

        self.ui.label.setText(«PyScripts») # Меняем текст

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Руководство по PyQt5

Именно на столько все просто! Давайте рассмотрим другие виджеты.

Виджет QLineEdit – это редактируемое поле, где вы можете принимать данные от пользователя. LineEdit содержит множество методов, с которыми можно работать.

QLineEdit PyQt5 Designer

Я создам новый дизайн qline.ui, используя дизайнер PyQt5 и внесу шесть виджетов QLineEdit и экспортирую его в файл qline.py.

pyuic5 qline.ui o qline.py

Cодержимое файла qline.py после конвертации:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file ‘qline.ui’

#

# Created by: PyQt5 UI code generator 5.11.3

#

# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):

    def setupUi(self, MainWindow):

        MainWindow.setObjectName(«MainWindow»)

        MainWindow.resize(785, 600)

        self.centralwidget = QtWidgets.QWidget(MainWindow)

        self.centralwidget.setObjectName(«centralwidget»)

        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)

        self.lineEdit.setGeometry(QtCore.QRect(10, 10, 291, 31))

        self.lineEdit.setObjectName(«lineEdit»)

        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)

        self.lineEdit_2.setGeometry(QtCore.QRect(10, 50, 291, 31))

        self.lineEdit_2.setObjectName(«lineEdit_2»)

        self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)

        self.lineEdit_3.setGeometry(QtCore.QRect(10, 90, 291, 31))

        self.lineEdit_3.setObjectName(«lineEdit_3»)

        self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget)

        self.lineEdit_4.setGeometry(QtCore.QRect(10, 130, 291, 31))

        self.lineEdit_4.setObjectName(«lineEdit_4»)

        self.lineEdit_5 = QtWidgets.QLineEdit(self.centralwidget)

        self.lineEdit_5.setGeometry(QtCore.QRect(10, 170, 291, 31))

        self.lineEdit_5.setObjectName(«lineEdit_5»)

        self.lineEdit_6 = QtWidgets.QLineEdit(self.centralwidget)

        self.lineEdit_6.setGeometry(QtCore.QRect(10, 210, 291, 31))

        self.lineEdit_6.setObjectName(«lineEdit_6»)

        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QtWidgets.QMenuBar(MainWindow)

        self.menubar.setGeometry(QtCore.QRect(0, 0, 785, 25))

        self.menubar.setObjectName(«menubar»)

        MainWindow.setMenuBar(self.menubar)

        self.statusbar = QtWidgets.QStatusBar(MainWindow)

        self.statusbar.setObjectName(«statusbar»)

        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):

        _translate = QtCore.QCoreApplication.translate

        MainWindow.setWindowTitle(_translate(«MainWindow», «MainWindow»))

Давайте познакомимся с методами QLineEdit:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

from PyQt5 import QtWidgets, QtCore

# Импортируем наш файл

from qline import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        # Меняем текст

        self.ui.lineEdit.setText(«Добро пожаловать на PythonScripts»)

        # указать максимальную длину

        self.ui.lineEdit_2.setMaxLength(10)

        # ввод пароля

        self.ui.lineEdit_3.setEchoMode(QtWidgets.QLineEdit.Password)

        # только чтение без изменения содержимого.

        self.ui.lineEdit_4.setReadOnly(True)

        # меняем цвет вводимого текста

        self.ui.lineEdit_5.setStyleSheet(«color: rgb(28, 43, 255);»)

        # изменение цвета фона QLineEdit

        self.ui.lineEdit_6.setStyleSheet(«background-color: rgb(28, 43, 255);»)

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Результат:

Руководство по PyQt5

  • Для 1-го QLineEdit, мы изменили текст, при помощи метода setText().
  • Для 2-го QLineEdit, мы установили максимум доступных 10-и символов, так что более 10-и приниматься не будут.
  • Для 3-го QLineEdit, мы установили режим пароля, так ваши введенные данные отображаются как звездочки;
  • Для 4-го QLineEdit, мы установили режим «только для чтения», так что редактировать контент не представляется возможным.
  • Для 5-го QLineEdit мы изменили цвет шрифта при помощи метода setStyleSheet() и указали нужный цвет с помощью CSS (как и для обычной веб страницы).
  • Для 6-го QLineEdit мы изменили цвет фона при помощи метода setStyleSheet() и CSS.

Метод setStyleSheet()

Метод setStyleSheet() может быть использован с виджетами PyQt5 для изменения стилей.

Вы можете изменить следующие параметры, пользуясь методом setStyleSheet():

  • Размер и тип шрифта;
  • Цвет текста;
  • Цвет заднего фона;
  • Цвет верхней границы;
  • Цвет нижней границы;
  • Цвет левой границы;
  • Цвет правой границы;
  • Цвет выделения;
  • Цвет выделения заднего фона.

Это наиболее важные значения, которые можно передать методу setStyleSheet().

Большая часть ваших программ Python будут содержать виджет QPushButton. Вы нажимаете кнопку, и какой-нибудь код выполняется.

Если у вас имеется опыт в программировании, вы могли слышать об обработке событий, где вы взаимодействуете с виджетом и функция выполняется.

Суть идеи сохранилась такой же и в PyQt5, только определения немного отличаются.

Событие клика в PyQt5 называется сигналом, и метод, который будет выполняться, называется слот.

Так что при нажатии на QPushButton, сигнал издается. Названием сигнала в данном случае, является clicked().

Чтобы связать сигнал со слотом, вам нужно использовать метод connect(), что вы сейчас и увидите.

Этот процесс обработки события продолжает работать до тех пор, пока вы не закроете вашу форму, или главный виджет.

Давайте создадим форму myform.ui при помощи QLabel и QPushButton и экспортируем её в файл myform.py.

QLabel QPushButton

Экспортируем myform.ui в myform.py

pyuic5 myform.ui o myform.py

Сейчас, мы подключим сигнал clicked() к слоту при помощи метода connect(), вот так:

self.ui.pushButton.clicked.connect(self.btnClicked)

Здесь, btnClicked – это слот, или функция, которая будет выполнена после того, как вы кликните на QPushButton.

Итак, ваш код будет выглядеть следующим образом:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

from PyQt5 import QtWidgets

# Импортируем наш шаблон.

from myform import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        # подключение клик-сигнал к слоту btnClicked

        self.ui.pushButton.clicked.connect(self.btnClicked)

    def btnClicked(self):

        self.ui.label.setText(«Вы нажали на кнопку!»)

        # Если не использовать, то часть текста исчезнет.

        self.ui.label.adjustSize()

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Результат:

QPushButton

Замечательно!

Визуальный редактор слота/сигнала

Мы видели, как подключать сигнал виджета к слоту при помощи метода connect(), но это не единственный способ.

На самом деле, для каждого виджета есть предопределенные слоты. Вы можете связать сигнал с любым предопределенным слотом, без необходимости кодить в дизайнере PyQt5.

Перетяните QPushButton и QLineEdit в вашу форму.

Нажмите F4 и перетяните курсор из QPushButton и отпустите его в верхней части QLineEdit. Чтобы вернуться в обычный режим, нажмите на F3.

Руководство по PyQt5

Благодаря этому появится редактор сигнала/слота.

Руководство по PyQt5

Слева находятся предопределенные сигналы, справа — предопределенные слоты. Скажем, нам нужно подключить сигнал clicked() с слотом «очистки содержимого«.

Выберите сигнал clicked слева и выберите clear слот справа и нажмите OK.

Руководство по PyQt5

После выполнения подключений ваших сигналов и слотов, вы можете выйти из этого режима, нажав ESC, или F3.

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

Сохраните форму как signaledit.ui и конвертируем её в signaledit.py:

pyuic5 signaledit.ui o signaledit.py

Полученный файл импортируем в наш код:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

from PyQt5 import QtWidgets

# Импортируем наш шаблон.

from signaledit import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Результат:

Руководство по PyQt5

Как выпускать сигналы в PyQt5

Мы увидели, как работают сигналы и слоты. Все сигналы, с которыми мы работали, являются предопределенными для нас.

Но что на счет выпуска собственного сигнала?

Это очень просто! Вы можете сделать это, просто использовав класс pyqtSignal, как показано ниже:

  • Определите ваше событие типом pyqtSignal;
  • Вызовите метод emit() в том месте, где вы хотите, чтобы произошло событие.

Скажем, у нас есть класс nut, и мы хотим, чтобы сигнал cracked был выпущен.

from PyQt5.QtCore import pyqtSignal, QObject

class nut(QObject):

    cracked = pyqtSignal()

    def __init__(self):

        QObject.__init__(self)

    def crack(self):

        self.cracked.emit()

Как использовать сигнал

Сейчас мы сделаем наш пример более практичным, создаем экземпляр класса nut и выпуская сигнал cracked:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

from PyQt5.QtCore import pyqtSignal, QObject

class nut(QObject):

    cracked = pyqtSignal()

    def __init__(self):

        QObject.__init__(self)

    def crack(self):

        self.cracked.emit()

def crackit():

    print(«hazelnut cracked!»)

hazelnut = nut()

# подключение сигнала cracked к слоту crackit

hazelnut.cracked.connect(crackit)

hazelnut.crack()

Сигнал cracked успешно выпущен.

Переопределение сигнала (события) в PyQt5

Иногда нам может понадобиться переопределить поведение по умолчанию для особенных событий или сигналов.

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

def keyPressEvent(self, e):

    if e.key() == Qt.Key_F12:

        self.close()

Теперь, если пользователь нажмет клавишу F12, главное окно будет закрыто.

Здесь мы переопределили основной сигнал нажатия в главном окне и закрыли это окно.

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

Давайте перетянем QComboBox в нашу форму и взглянем на её методы.

Руководство по PyQt5

Сохраняем файл как combobox.ui и конвертируем его в combobox.py:

pyuic5 combobox.ui o combobox.py

Если вы запустите приложение сейчас, обратите внимание на то, что QComboBox — пустой. Чтобы вносить объекты в QComboBox, используйте метод addItem():

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

from PyQt5 import QtWidgets

from combobox import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        # Добавляем новые значения

        self.ui.comboBox.addItem(«Программист»)

        self.ui.comboBox.addItem(«Дизайнер»)

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Руководство по PyQt5

Получаем все элементы из QComboBox

Нет прямого способа получить все значения из QComboBox, но вы можете применить цикл Python для этой цели. Для этого подойдет функция range.

for i in range(self.ui.comboBox.count()):

    print(self.ui.comboBox.itemText(i))

Выбор одного элемента из QCombobox

Чтобы выбрать элемент из QComboBox, у вас есть два метода:

# по индексу, который начинается с нуля

self.ui.comboBox.setCurrentIndex(1)

#выбор по тексту

self.ui.comboBox.setCurrentText(«Second item»)

Обратите внимание на то, что при выборе элемента по тексту, следует убедиться в том, что вы вводите правильный текст. В противном случае, QComboBox останется на первом элементе.

Если вы хотите просмотреть вашу базу данных в формате таблицы, в PyQt5 предоставляется QTableWidget как раз для этой цели.

QTableWidget состоит из клеток, каждая клетка — экземпляр класса QTableWidgetItem.

Давайте создадим форму, которая содержит QTableWidget и QPushButton.

QTableWidget

Перетяните QTableWidget и QPushButton из PyQt5 Designer. После этого, сохраните форму как qtable.ui и конвертируйте дизайн в qtable.py.

pyuic5 qtable.ui o qtable.py

Чтобы добавлять ряды в QTableWidget, вы можете использовать метод setRowCount().

Для внесения столбцов в QTableWidget, воспользуйтесь методом setColumnCount().

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

from PyQt5 import QtWidgets

# Импортируем нашу форму.

from qtable import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setColumnCount(2)

        self.ui.tableWidget.setRowCount(4)

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Руководство по PyQt5

Теперь вы можете писать текст вручную внутри клеток QTableWidget.

Очистка содержимого QTableWidget

Чтобы очистить содержимое QTableWidget, вы можете использовать метод clear, вот так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

from PyQt5 import QtWidgets

# Импортируем нашу форму.

from qtable import Ui_MainWindow

import sys

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(mywindow, self).__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setColumnCount(2)

        self.ui.tableWidget.setRowCount(4)

        # очистка таблицы при клике на кнопку.

        self.ui.pushButton.clicked.connect(self.clear)

    def clear(self):

        self.ui.tableWidget.clear()

app = QtWidgets.QApplication([])

application = mywindow()

application.show()

sys.exit(app.exec())

Руководство по PyQt5

Заполнение QTableWidget из кода

Чтобы заполнить QtableWidget программно, вам нужно использовать метод setItem() для каждого объекта QtableWidgetItem.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

from PyQt5.QtWidgets import QTableWidgetItem

from qtable import *

import sys

data = []

data.append((‘Заполнить’, ‘QTableWidget’))

data.append((‘с данными’, ‘в Python’))

data.append((‘очень’, ‘просто’))

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setRowCount(3)

        self.ui.tableWidget.setColumnCount(2)

        # очистка таблицы при клике на кнопку.

        self.ui.pushButton.clicked.connect(self.clear)

        row = 0

        for tup in data:

            col = 0

            for item in tup:

                cellinfo = QTableWidgetItem(item)

                self.ui.tableWidget.setItem(row, col, cellinfo)

                col += 1

            row += 1

    def clear(self):

        self.ui.tableWidget.clear()

app = QtWidgets.QApplication([])

win = mywindow()

win.show()

sys.exit(app.exec())

Руководство по PyQt5

  • Сначала мы создали список трех кортежей Python;
  • Внутри конструктора главного окна, мы установили количество столбцов и рядов;
  • Далее мы перебираем список и получаем каждый кортеж в списке, для заполнения клеток таблицы, при помощи метода setItem()
  • Наконец, мы показываем главное окно.

Делаем QTableWidget нередактируемым (только для чтения)

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

Чтобы сделать QTableWidget нередактируемым, вы можете использовать метод setFlags(), чтобы сделать каждый QTableWidgetItem доступным только для чтения.

# Только для чтения

cellinfo.setFlags(

    QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled

)

Вам нужно установить флажки, перед тем как настраивать содержимое вашей клетки.

Таким образом, ваш код будет выглядеть вот так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

from PyQt5.QtWidgets import QTableWidgetItem

from qtable import *

import sys

data = []

data.append((‘Заполнить’, ‘QTableWidget’))

data.append((‘с данными’, ‘в Python’))

data.append((‘очень’, ‘просто’))

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setRowCount(3)

        self.ui.tableWidget.setColumnCount(2)

        # очистка таблицы при клике на кнопку.

        self.ui.pushButton.clicked.connect(self.clear)

        row = 0

        for tup in data:

            col = 0

            for item in tup:

                cellinfo = QTableWidgetItem(item)

                # Только для чтения

                cellinfo.setFlags(

                    QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled

                )

                self.ui.tableWidget.setItem(row, col, cellinfo)

                col += 1

            row += 1

    def clear(self):

        self.ui.tableWidget.clear()

app = QtWidgets.QApplication([])

win = mywindow()

win.show()

sys.exit(app.exec())

Теперь, если вы попробуете отредактировать какую-либо клетку — у вас не выйдет, так как QtableWidgetItem теперь нельзя редактировать

До этого момента, названия столбцов QTableWidget были числами. Как на счет того, чтобы поменять названия столбцов на что-нибудь другое?

Чтобы задать текст заголовкам QTableWidget, вы можете использовать метод setHorizontalHeaderLabels(), вот так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

from PyQt5.QtWidgets import QTableWidgetItem

from qtable import *

import sys

data = []

data.append((‘BMW’, ‘1991’))

data.append((‘Audi’, ‘2003’))

data.append((‘Volvo’, ‘2010’))

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setRowCount(3)

        self.ui.tableWidget.setColumnCount(2)

        # очистка таблицы при клике на кнопку.

        self.ui.pushButton.clicked.connect(self.clear)

        # заголовки для столбцов.

        self.ui.tableWidget.setHorizontalHeaderLabels(

            (‘Марка’, ‘Год выпуска’)

        )

        row = 0

        for tup in data:

            col = 0

            for item in tup:

                cellinfo = QTableWidgetItem(item)

                self.ui.tableWidget.setItem(row, col, cellinfo)

                col += 1

            row += 1

    def clear(self):

        self.ui.tableWidget.clear()

app = QtWidgets.QApplication([])

win = mywindow()

win.show()

sys.exit(app.exec())

setHorizontalHeaderLabels

Таким же образом, вы можете менять заголовок ряда, при помощи метода setVerticalHeaderLabels():

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

from PyQt5.QtWidgets import QTableWidgetItem

from qtable import *

import sys

data = []

data.append((‘BMW’, ‘1991’))

data.append((‘Audi’, ‘2003’))

data.append((‘Volvo’, ‘2010’))

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setRowCount(3)

        self.ui.tableWidget.setColumnCount(2)

        # очистка таблицы при клике на кнопку.

        self.ui.pushButton.clicked.connect(self.clear)

        # заголовки для столбцов.

        self.ui.tableWidget.setHorizontalHeaderLabels(

            (‘Марка’, ‘Год выпуска’)

        )

        # названия рядов.

        self.ui.tableWidget.setVerticalHeaderLabels(

            (‘900$’, ‘5000$’, ‘13000$’)

        )

        row = 0

        for tup in data:

            col = 0

            for item in tup:

                cellinfo = QTableWidgetItem(item)

                self.ui.tableWidget.setItem(row, col, cellinfo)

                col += 1

            row += 1

    def clear(self):

        self.ui.tableWidget.clear()

app = QtWidgets.QApplication([])

win = mywindow()

win.show()

sys.exit(app.exec())

setVerticalHeaderLabels

Как сортировать QTableWidget

Вы можете сделать ваш QTableWidget сортируемым, при помощи метода setSortingEnabled().

self.ui.tableWidget.setSortingEnabled(True)

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

Вы можете использовать этот метод перед, или до наполнения QTableWidget данными.

Что на счет сортировки в QTableWidget, но только для определенного столбца?

Вы можете использовать метод sortByColumn(), и указать индекс столбца и порядок сортировки, вот так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

from PyQt5.QtWidgets import QTableWidgetItem

from qtable import *

import sys

data = []

data.append((‘BMW’, ‘2005’))

data.append((‘Audi’, ‘2003’))

data.append((‘Volvo’, ‘1990’))

data.append((‘Toyota’, ‘2018’))

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        # Кол-во рядов меняется в зависимости от значений в data.

        self.ui.tableWidget.setRowCount(

            len(data)

        )

        # Кол-во столбцов меняется в зависимости от data.

        self.ui.tableWidget.setColumnCount(

            len(data[0])

        )

        # очистка таблицы при клике на кнопку.

        self.ui.pushButton.clicked.connect(self.clear)

        # заголовки для столбцов.

        self.ui.tableWidget.setHorizontalHeaderLabels(

            (‘Марка’, ‘Год выпуска’)

        )

        row = 0

        for tup in data:

            col = 0

            for item in tup:

                cellinfo = QTableWidgetItem(item)

                self.ui.tableWidget.setItem(row, col, cellinfo)

                col += 1

            row += 1

        # Сортировка по году выпуска.

        # 0 — Марка

        # 1 — Год выпуска

        self.ui.tableWidget.sortByColumn(

            1, QtCore.Qt.AscendingOrder

        )

    def clear(self):

        self.ui.tableWidget.clear()

app = QtWidgets.QApplication([])

win = mywindow()

win.show()

sys.exit(app.exec())

Кстати, вы можете использовать метод sortItems() для сортировки QTableWidget в возрастающем порядке по умолчанию.

self.ui.tableWidget.sortItems(0)

Или вы можете определить свой порядок сортировки:

self.ui.tableWidget.sortItems(1, QtCore.Qt.DescendingOrder)

Помните, что если вы хотите сортировать ваши столбцы программно, вам нужно использовать методы сортировки после заполнения QTableWidget данными, иначе они не будут в нужном вам порядке.

Добавляем QComboBox в QTableWidget

У вас может появится задача, чтобы пользователь выбирал значение внутри QTableWidget, вместо ввода текста.
Как на счет того, чтобы добавить QComboBox в QTableWidgetItem?

Чтобы добавить QComboBox внутрь QTableWidgetItem, вы можете использовать метод setCellWidget():

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

from PyQt5.QtWidgets import QTableWidgetItem

from qtable import *

import sys

data = [‘Python’, ‘PHP’, ‘Java’]

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setRowCount(3)

        self.ui.tableWidget.setColumnCount(2)

        row = 0

        for item in data:

            cellinfo = QTableWidgetItem(item)

            combo = QtWidgets.QComboBox()

            combo.addItem(«Изучить»)

            combo.addItem(«Забыть»)

            combo.addItem(«Удалить»)

            self.ui.tableWidget.setItem(row, 0, cellinfo)

            self.ui.tableWidget.setCellWidget(row, 1, combo)

            row += 1

app = QtWidgets.QApplication([])

win = mywindow()

win.show()

sys.exit(app.exec())

QComboBox в QTableWidget

Отлично!

Не ограничивайте себя в воображении и попробуйте вставлять различные виджеты, такие как QСheckbox, или даже QProgressBar.

QProgressBar в QTableWidget

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

from PyQt5.QtWidgets import QTableWidgetItem

from qtable import *

import sys

data = (

    (‘Python’, 95.5),

    (‘PHP’, 55.1),

    (‘Java’, 0.29)

)

class mywindow(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.tableWidget.setRowCount(3)

        self.ui.tableWidget.setColumnCount(2)

        self.ui.tableWidget.setHorizontalHeaderLabels(

            (‘Язык’, ‘Знания’)

        )

        line = 0

        for item in data:

            cellinfo = QTableWidgetItem(item[0])

            self.ui.tableWidget.setItem(line, 0, cellinfo)

            # Создаем QProgressBar

            progress = QtWidgets.QProgressBar()

            progress.setMinimum(0)

            progress.setMaximum(100)

            # Формат вывода: 10.50%

            progress.setValue(item[1])

            progress.setFormat(‘{0:.2f}%’.format(item[1]))

            # Добавляем виджет в ячейку.

            self.ui.tableWidget.setCellWidget(line, 1, progress)

            line += 1

app = QtWidgets.QApplication([])

win = mywindow()

win.show()

sys.exit(app.exec())

Руководство по PyQt5

Указанный выше код будет таким же, за исключением строки, где вы создаете QСomboBox, здесь вы внесете тот виджет, который вам нужен.

Единственное ограничение — это ваше собственное воображение!

Компиляция Python приложения

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

Лично я предпочитаю pyinstaller, который подходит для упаковки кода Python в исполняемый файл под Windows, Mac OS X, Solaris, Linux и FreeBSD. Все это будет поддерживаться 32 и 64-битной архитектурой.

Лучшая в pyinstaller для нас — это наличие полной поддержки для PyQt5.

Отлично! Для начала, установим pyinstaller:

$ pip3 install pyinstaller

После проведения установки, вы можете конвертировать программы Python следующим образом:

Ваш исполняемый файл будет создан в папке под названием dist в директории вашей программы Python.

Как вы могли догадаться, вместе с исполняемым файлом будет генерироваться множество зависимостей. Как сделать из этого один файл?

Вы можете создать один исполняемый файл. Вот так:

$ pyinstaller onefile test.py

Каждый раз, когда вы запускаете ваш исполняемый файл, будет возникать окно, как его спрятать?

Вы можете использовать флажки -w или –noconsole, чтобы спрятать окно консоли:

Эта опция доступна только для Windows и Mac OS X.

Pyinstaller предоставляет множество вариантов для упаковки вашего приложения, чтобы увидеть полный список, используйте –help:

Я старался сделать все на столько простым, на сколько это возможно. Надеюсь, это руководство оказалось для вас полезным.

Спасибо.

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: vasile.buldumac@ati.utm.md

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

Описание Класса QLineEdit
[модуль QtGui]

Виджет QLineEdit представляет собой редактор однострочного текста. Далее…

#include <QLineEdit>

Наследует QWidget.

  • Список всех членов, включая унаследованные
  • Члены поддержки Qt 3

Открытые Типы

  • enum EchoMode { Normal, NoEcho, Password }

Свойства

  • 54 свойства, унаследованные от QWidget

  • 1 свойство, унаследованное от QObject

Открытые Функции

  • QLineEdit ( const QString & contents, QWidget * parent = 0 )

  • void end ( bool mark )

  • void home ( bool mark )

  • void insert ( const QString & newText )

  • QString text () const

  • const QValidator * validator () const

  • 188 открытых функций, унаследованных от QWidget

  • 28 открытых функций, унаследованных от QObject

  • 10 открытых функций, унаследованных от QPaintDevice

Открытые Слоты

  • void copy () const

  • void setText ( const QString & )

  • 17 открытых слотов, унаследованных от QWidget

  • 1 открытый слот, унаследованный от QObject

Сигналы

  • 1 сигнал, унаследованный от QWidget

  • 1 сигнал, унаследованный от QObject

Защищенные Функции

  • 39 защищенных функций, унаследованных от QWidget

  • 7 защищенных функций, унаследованных от QObject

Дополнительные Унаследованные Члены

  • 4 статических открытых члена, унаследованных от QWidget

  • 4 статических открытых члена, унаследованных от QObject


Подробное Описание

Виджет QLineEdit представляет собой редактор однострочного текста.

Редактор строки позволяет пользователю вводить и редактировать одну строку простого текста с набором полезных функций редактирования, включая отмену, повтор, вырезание, вставку, а также перетаскивание с помощью механизма drag-and-drop.

Изменяя свойства echoMode() редактора, можно использовать его в качестве поля «только-для-записи» и для ввода паролей.

Длина текста может быть ограничена с помощью maxLength(). Для текста можно задать условия, используя validator() или inputMask(), либо оба их.

QTextEdit — это подобный класс, но он позволяет редактировать многострочный форматированный текст.

Вы можете изменять текст с помощью setText() или insert(). Текст может быть получен с помощью text(); отображаемый текст (может отличаться от содержащегося текста, см. EchoMode) может быть получен с помощью displayText(). Текст может быть выделен с помощью setSelection() или selectAll(), а выделенный текст может быть вырезан с помощью cut(), скопирован с помощью copy() и вставлен с помощью paste(). Текст может быть выровнен с помощью setAlignment().

При изменении текста испускается сигнал textChanged(); при изменении текста с помощью setText(), испускается сигнал textEdited(); при перемещении курсора испускается сигнал cursorPositionChanged(); а при нажатии клавиш Return или Enter испускается сигнал returnPressed().

При окончании редактирования (редактор теряет фокус или нажата клавиша Return/Enter) испускается сигнал editingFinished().

Обратите внимание на то, что если установлено условие для текста (validator()), то сигналы returnPressed()/editingFinished() испускаются только в случае, если условие для текста возвращает QValidator::Acceptable.

По умолчанию, QLineEdits имеет рамку, определенную Windows или или стилем Motif; это может быть изменено с помощью setFrame(false).

Ниже приведены ключевые клавиши и сочетания клавиш и действия, вызываемые ими, определенные по умолчанию. Также редактор строки предоставляет контекстное меню (обычно вызываемое по нажатии правой кнопки мыши), в котором представлены некоторые из этих действий.

Клавиши Действие
Стрелка Влево Перемещает курсор на один символ влево.
Shift+Стрелка Влево Перемещает курсор на один символ влево с выделением текста.
Стрелка Вправо Перемещает курсор на один символ вправо.
Shift+Стрелка Вправо Перемещает курсор на один символ вправо с выделением текста.
Home Перемещает курсор в начало строки.
End Перемещает курсор в конец строки.
Backspace Удаляет один символ, стоящий слева от курсора.
Ctrl+Backspace Удаляет одно слово, стоящее слева от курсора.
Delete Удаляет один символ, стоящий справа от курсора.
Ctrl+Delete Удаляет одно слово, стоящее справа от курсора.
Ctrl+A Перемещает курсор в начало строки.
Ctrl+B Перемещает курсор в конец строки.
Ctrl+C Копирует выделенный текст в буфер обмена.
Ctrl+Insert Копирует выделенный текст в буфер обмена.
Ctrl+D Удаляет один символ, стоящие справа от курсора.
Ctrl+E Перемещает курсор в конец строки.
Ctrl+F Перемещает курсор на один символ вправо.
Ctrl+H Удаляет один символ, стоящий слева от курсора.
Ctrl+K Удаляет все символы от курсора до конца строки.
Ctrl+V Вставляет текст в редактор из буфера обмена.
Shift+Insert Вставляет текст в редактор из буфера обмена.
Ctrl+X Удаляет выделенный текст и копирует его в буфер обмена.
Shift+Delete Удаляет выделенный текст и копирует его в буфер обмена.
Ctrl+Z Отменяет последнюю операцию.
Ctrl+Y Повторяет последнюю отмененную операцию.

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

Screenshot in Macintosh style Screenshot in Windows style

См. также QTextEdit, QLabel, QComboBox и GUI Design Handbook: Field, Entry.


Описание Типов Членов

enum QLineEdit::EchoMode

Данное перечисление описывает, как редактор строки отображает свое содержимое.

Константа Значение Описание
QLineEdit::Normal 0 Отображаются те-же самые символы, что и введены. Это режим по умолчанию.
QLineEdit::NoEcho 1 Не отображается вообще ничего. Этот режим может использоваться для ввода паролей там, где даже длинна пароля должна оставаться в секрете.
QLineEdit::Password 2 Вместо фактически введенных символов отображаются звездочки.

См. также setEchoMode() и echoMode().


Описание Свойств

acceptableInput : const bool

Данное свойство сообщает, соответствует ли введенный текст маске ввода или условию, наложенному на текст.

Функции доступа:

  • bool hasAcceptableInput () const

См. также setInputMask() и setValidator().

alignment : Qt::Alignment

Данное свойство содержит выравнивание текста в редакторе.

Допускается только выравнивание по горизонтали, Qt::AlignJustify считается Qt::AlignLeft.

Функции доступа:

  • Qt::Alignment alignment () const

  • void setAlignment ( Qt::Alignment flag )

См. также Qt::Alignment.

cursorPosition : int

Данное свойство содержит текущее положение курсора в редакторе.

Установка положения курсора приводит к перерисовке виджета, если необходимо.

Функции доступа:

  • int cursorPosition () const

  • void setCursorPosition ( int )

displayText : const QString

Данное свойство содержит отображаемый текст.

Если echoMode равно Normal, то возвращается тоже самое, что возвращается text(); если EchoMode равно Password, то возвращается строка, содержащаю звездочки, с длиной text().length() символов, например, «******»; если EchoMode равно NoEcho, то возвращается пустая строка, «».

Функции доступа:

  • QString displayText () const

См. также setEchoMode(), text() и EchoMode.

dragEnabled : bool

Данное свойство указывает, начинает ли редактор процесс перетаскивания, если пользователь начинает перемещать мышь с нажатой кнопкой над выделенным текстом.

По умолчанию перетаскивание запрещено.

Функции доступа:

  • bool dragEnabled () const

  • void setDragEnabled ( bool b )

echoMode : EchoMode

Данное свойство содержит режим отображения содержимого редактора.

Изначальное значение — это Normal, но QLineEdit также поддерживает режимы NoEcho и Password.

Это свойство влияет на отображение содержимого текста, возможность копирования и перетаскивания текста.

Функции доступа:

  • EchoMode echoMode () const

  • void setEchoMode ( EchoMode )

См. также EchoMode и displayText().

frame : bool

Данное свойство указывает, отображается ли рамка редактора.

Если рамка доступна (по умолчанию), то редактор рисуется внутри рамки, в противном случае редактор отображается без рамки.

Функции доступа:

  • bool hasFrame () const

  • void setFrame ( bool )

hasSelectedText : const bool

Данное свойство сообщает, выделен ли какой либо текст в редакторе.

hasSelectedText() возвращает true, если пользователем выделена часть текста или весь текст; в противном случае возвращает false.

Функции доступа:

  • bool hasSelectedText () const

См. также selectedText().

inputMask : QString

Данное свойство содержит маску ввода.

Если маска не установлена, то inputMask() возвращает пустую строку.

Устанавливает маску ввода QLineEdit. Условие для текста может использоваться вместо маски или вместе с ней; см. setValidator().

Сброс маски в возвращение обычной работы QLineEdit производится с помощью передачи пустой строки («») или с помощью вызова setInputMask() без аргументов.

Формат маски предусматривает следующие символы:

Символ Значение
A Требуется алфавитный символ ASCII. A-Z, a-z.
a Разрешен, но не обязателен алфавитный симовл ASCII.
N Требуется алфавитный символ или цифра ASCII. A-Z, a-z, 0-9.
n Разрешен, но не обязателен алфавитный символ или цифра ASCII.
X Требуется любой символ.
x Разрешен, но не обязателен любой символ.
9 Требуется цифра ASCII. 0-9.
0 Разрешена, но не обязательна цифра ASCII.
D Требуется цифра ASCII не равная нулю. 1-9.
d Разрешена, но не обязательна цифра ASCII не равная нулю (1-9).
# Разрешена, но не обязательна цифра или знак плюс/минус ASCII.
H Требуется шестнадцатиричный символ. A-F, a-f, 0-9.
h Разрешен, но не обязателен шестнадцатиричный символ.
B Требуется двоичный символ. 0-1.
b Разрешен, но не обязателен двоичный символ.
> Все следующие алфавитный символы переводятся в верхний регистр.
< Все следующие алфавитный символы переводятся в нижний регистр.
! Изменение регистра отключается.
Используйте для того, чтобы отменить действие вышеприведенных знаков, как специальных символов, и использовать их в качестве разделителей.

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

Примеры:

Маска Описание
000.000.000.000;_ IP-адрес; пробелы обозначаются символом _.
HH:HH:HH:HH:HH:HH;_ MAC-адрес
0000-00-00 Дата ISO; пробелы обозначаются символом пробел
>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# Лицензионный номер; пробелы обозначаются символом — и все (алфавитные) символы приводятся к верхнему регистру.

Для контроля диапазона символов (например, при вводе IP-адреса) используйте маску с условием для текста.

Функции доступа:

  • QString inputMask () const

  • void setInputMask ( const QString & inputMask )

См. также maxLength.

maxLength : int

Данное свойство содержит максимальную разрешенную длину текста.

Если текст очень длинный, то он обрезается по установленному пределу.

Если происходит обрезание текста, то текст становится не выделенным (если раньше что либо было выделено), курсор помещается в позицию 0 и отображается первая часть текста.

Если для редактора установлена маска ввода, то эта маска определяет максимальную длину текста.

Функции доступа:

  • int maxLength () const

  • void setMaxLength ( int )

См. также inputMask.

modified : bool

Данное свойство указывает, было ли изменено содержимое редактора пользователем.

QLineEdit никогда не читает флаг изменения; по умолчанию флаг имеет значение false и изменяется на true всякий раз, когда пользователь изменяет содержимое редактора.

Это удобно в случаях, когда приложение предоставляет значение по умолчанию, но не знает, что такое значение есть (возможно, значение по умолчанию зависит от других полей формы). Сначала редактор не отображает значение по умолчанию, но при значет о нем, и только если modified() возвращает false (пользователь не ввел текст), вставляет значение по умолчанию.

Вызов setText() устанавливает флаг модификации в false.

Функции доступа:

  • bool isModified () const

  • void setModified ( bool )

readOnly : bool

Данное свойство указывает, позволяет ли редактор вводить текст или только читать.

В режиме только-для-чтения пользователь все еще может копировать в буфер обмена и перетаскивать текст (если echoMode() равно Normal), но не может редактировать его.

В режиме только-для-чтения, QLineEdit не отображает курсор.

Функции доступа:

  • bool isReadOnly () const

  • void setReadOnly ( bool )

См. также setEnabled().

redoAvailable : const bool

Данное свойство сообщает, доступен ли повтор последнего отмененного действия.

Функции доступа:

  • bool isRedoAvailable () const

selectedText : const QString

Данное свойство содержит выделенный текст.

Если ни какой текст не выделен, то значением свойства является пустая строка.

Функции доступа:

  • QString selectedText () const

См. также hasSelectedText().

text : QString

Данное свойство содержит редактируемый текст.

Установка данного свойства отменяет выделение текста, очищает историю отмены/повтора, устанавливает курсор в конец строки и устанавливает свойство modified в false. При вставке текста с помощью setText() не проверяется соответствие устанавливаемого текста заданному условию не текст.

Текст обрезается в соответствии с maxLength().

Функции доступа:

  • QString text () const

  • void setText ( const QString & )

См. также insert() и clear().

undoAvailable : const bool

Данное свойство сообщает, доступна ли отмена последнего действия.

Функции доступа:

  • bool isUndoAvailable () const


Описание Функций-Членов

QLineEdit::QLineEdit ( QWidget * parent = 0 )

Создает не заполненный текстом редактор.

Максимальная длина текста установлена равной 32767 символам.

Аргумент parent передается в конструктор QWidget.

См. также setText() и setMaxLength().

QLineEdit::QLineEdit ( const QString & contents, QWidget * parent = 0 )

Создает редактор, содержащий текст contents.

Курсор устанавливается в конец строки, а максимальная длина текста устанавливается равной 32767 символам.

Аргумент parent передается в конструктор QWidget.

См. также text() и setMaxLength().

QLineEdit::~QLineEdit ()

Разрушает редактор.

void QLineEdit::backspace ()

Если никакой текст не выделен, но символ, стоящий слева от курсора, удаляется, а курсор перемещается на одну позицию левее. Если есть выделенный текст, то курсор перемещается в начало выделенного текста, а выделенный текст удаляется.

См. также del().

void QLineEdit::clear ()   [slot]

Удаляет текст, содрежащийся в редакторе.

См. также setText() и insert().

void QLineEdit::contextMenuEvent ( QContextMenuEvent * event )   [virtual protected]

Отображает стандартное контекстное меню, созданное с помощью createStandardContextMenu().

Если Вы не хотите, чтобы редактор имел контекстное меню, то можете установить contextMenuPolicy в Qt::NoContextMenu. Если Вы хотите настроить контекстное меню, то должны заново реализовать данную функцию. Если Вы хотите расширить стандартное контекстное меню заново реализовав данную функцию, то вызовите createStandardContextMenu() и дополните возвращенное меню.

    void LineEdit::contextMenuEvent(QContextMenuEvent *event)
    {
        QMenu *menu = createStandardContextMenu();
        menu->addAction(tr("My Menu Item"));
        //...
        menu->exec(event->globalPos());
        delete menu;
    }

Параметр event используется для определения позиции, в которой находится указатель мыши во время создания сообщения контестного меню.

Заново реализовано по отношению к QWidget.

См. также setContextMenuPolicy().

void QLineEdit::copy () const   [slot]

Копирует выделенный текст, если таковой есть и если echoMode() равно Normal, в буфер обмена.

См. также cut() и paste().

QMenu * QLineEdit::createStandardContextMenu ()

Данная функция создает стандартное контекстное меню отображаемое при щелчке на редакторе правой кнопкой мыши. По умолчанию вызывается обработчиком сообщений contextMenuEvent(). Всплывающее меню передается вызывающему по значению.

void QLineEdit::cursorBackward ( bool mark, int steps = 1 )

Перемещает курсор назад на steps символов. Если mark равно true, то каждый символ, через который перемещается курсор, выделяется; если mark равно false то выделение с текста снимается.

См. также cursorForward().

void QLineEdit::cursorForward ( bool mark, int steps = 1 )

Перемещает курсор вперед на steps символов. Если mark равно true, то каждый символ, через который перемещается курсор, выделяется; если mark равно false то выделение с текста снимается.

См. также cursorBackward().

int QLineEdit::cursorPositionAt ( const QPoint & pos )

Возвращает позицию, которую мог бы занимать курсор, находясь в точке pos.

void QLineEdit::cursorPositionChanged ( int old, int new )   [signal]

Данный сигнал испускается всякий раз при перемещении курсора. Предыдущая позиция курсора помещается в old, а новая позиция — в new.

См. также setCursorPosition() и cursorPosition().

void QLineEdit::cursorWordBackward ( bool mark )

Перемещает курсор на одно слово назад. Если mark равно true, то слово выделяется.

См. также cursorWordForward().

void QLineEdit::cursorWordForward ( bool mark )

Перемещает курсор на одно слово вперед. Если mark равно true, то слово выделяется.

См. также cursorWordBackward().

void QLineEdit::cut ()   [slot]

Копирует выделенный текст, если таковой имеется и если echoMode() равно Normal, в буфер обмена и удаляет его.

Если текущее условие на текст отвергает удаление выделенного текста, то cut() будет скопирован, но не удален.

См. также copy(), paste() и setValidator().

void QLineEdit::del ()

Если нет выделенного текста, то удаляется символ, стоящий справа от курсора. Если есть выделенный текст, то курсор перемещается в начало выделенного текста, а выделенный текст удаляется.

См. также backspace().

void QLineEdit::deselect ()

Снимает выделение с выделенным текстом.

См. также setSelection() и selectAll().

void QLineEdit::editingFinished ()   [signal]

Данный сигнал испускается при нажатии клавиши Return или Enter или когда редактор теряет фокус. Обратите внимание, что если для редактора установлены validator() или inputMask() и нажата клавиша enter/return, то сигнал editingFinished() будет испущен только в том случае, если inputMask() и validator() для введенног текста возвратят QValidator::Acceptable.

void QLineEdit::end ( bool mark )

Перемещает курсор в конец редактируемой строки (если он уже не там). Если mark равно true, то текст от текущего положения до конца строки добавляется к выделенному; в противном случае, выделение с выделенного текста снимается (если курсор перемещается).

См. также home().

void QLineEdit::home ( bool mark )

Перемещает курсор в начало редактируемой строки (если он уже не там). Если mark равно true, то текст от начала строки до текущего положения добавляется к выделенному; в противном случае, выделение с выделенного текста снимается (если курсор перемещается).

См. также end().

void QLineEdit::insert ( const QString & newText )

Удаляет выделенный текст, вставляет новый текст newText и проверяет соответствие результата на соответствие установленному условию. Если новый текст соответствует условию, то он становится новым содержимым редактора.

См. также setText() и clear().

void QLineEdit::keyPressEvent ( QKeyEvent * event )   [virtual protected]

Преобразует полученное сообщение клавиатуры event в действие редактора.

Если нажата клавиша Return или Enter и текущий текст соответствует установленному условию (или может быть сделан соответствующим объектом условия), то испускается сигнал returnPressed().

Список ействий клавиш, заданные по умолчанию, приведен в подробном описании класса.

Повторно реализовано по отношению к QWidget.

QSize QLineEdit::minimumSizeHint () const   [virtual]

Возвращает минимальный размер редактора.

Ширина в возвращаемом значении достаточна для размещения по крайней мере одного символа.

Повторно реализовано по отношению к QWidget.

void QLineEdit::paste ()   [slot]

Вставляет текст из буфера обмена в позицию курсора, удаляет выделенный текст. Поддреживается редактором, если он находится не в режиме только-для-чтения.

Если полученный результат не соответствует установленному условию (validator), ничего не происходит.

См. также copy() и cut().

void QLineEdit::redo ()   [slot]

Повторяет последнюю отмененную операцию если это возможно (свойство redoАvailable).

void QLineEdit::returnPressed ()   [signal]

Данный сигнал испускается при нажатии клавиши Return или Enter. Обратите внимание, что если для редактора установлены validator() или inputMask(), то сигнал returnPressed() испускается только в том случае, если inputMask() и validator() для введенного текста возвращают QValidator::Acceptable.

void QLineEdit::selectAll ()   [slot]

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

См. также setSelection() и deselect().

void QLineEdit::selectionChanged ()   [signal]

Данный сигнал испускается всякий раз, когда изменяется выделение текста в редакторе.

См. также hasSelectedText() и selectedText().

int QLineEdit::selectionStart () const

selectionStart() возвращает индекс первого выделенного символа или, если никакой текст не выделен, -1.

См. также selectedText().

void QLineEdit::setSelection ( int start, int length )

Выделяет фрагмент текста начинающийся в позиции start и имеющий длину length символов. Допускается отрицательное значение длины.

См. также deselect(), selectAll() и selectedText().

void QLineEdit::setValidator ( const QValidator * v )

Устанавливает для редактора условие на вводимый текст v. Это позволяет устанавливать любые ограничения на вводимый текст.

Если v == 0, то setValidator() удаляет установленное условие на текст. Изначально для редактора не установлено никакое условие на текст (т.е. позволяется вводить любой текст длиной не более maxLength() символов).

См. также validator(), QIntValidator, QDoubleValidator и QRegExpValidator.

QSize QLineEdit::sizeHint () const   [virtual]

Возвращает рекомендуемый виджету размер.

Ширина, возвращаемая в пикселях, обычно достаточна для размещения 15-20 символам.

Повторно реализовано по отношению к QWidget.

void QLineEdit::textChanged ( const QString & text )   [signal]

Данный сигнал испускается всякий раз при изменении текста. Аргумент text содержит новый текст.

В отличие от textEdited(), данный сигнал испускается даже тогда, когда текст в редакторе устанавливается программно, с помощью setText().

void QLineEdit::textEdited ( const QString & text )   [signal]

Данный сигнал испускается всякий раз при редактировании текста. Аргумент text содрежит новый текст.

В отличие от textChanged(), данный сигнал не испускается при программной установке текста с помощью setText().

void QLineEdit::undo ()   [slot]

Отменяет последнюю операцию, если отмена возможна (свойство undoAvailable. Снимает выделение текста и переносит начало выделения текста к текущему положению курсора.

const QValidator * QLineEdit::validator () const

Возвращает указатель на текущее условие на вводимый текст или, если таковое условие на установлено, 0.

См. также setValidator().


Hosted by uCoz

К старту курса по разработке на Python делимся детальным руководством по работе с современным PyQt. Чтобы читать было удобнее, мы объединили несколько статей в одну:

  1. Первое приложение

  2. Слоты и сигналы

  3. Виджеты

За подробностями приглашаем под кат.


Простое приложение Hello World! на Python и Qt6

PyQt — это библиотека Python для создания приложений с графическим интерфейсом с помощью инструментария Qt. Созданная в Riverbank Computing, PyQt является свободным ПО (по лицензии GPL) и разрабатывается с 1999 года. Последняя версия PyQt6 — на основе Qt 6 — выпущена в 2021 году, и библиотека продолжает обновляться. Это руководство можно также использовать для PySide2, PySide6 и PyQt5.

Сегодня используются две основные версии: PyQt5 на основе Qt5 и PyQt6 на основе Qt6. Обе почти полностью совместимы, за исключением импорта и отсутствия поддержки некоторых продвинутых модулей из Qt6. В PyQt6 вносятся изменения в работу пространств имён и флагов, но ими легко управлять. В этом руководстве мы узнаем, как использовать PyQt6 для создания настольных приложений.

Сначала создадим несколько простых окон на рабочем столе, чтобы убедиться, что PyQt работает, и разберём базовые понятия. Затем кратко изучим цикл событий и то, как он связан с программированием графического интерфейса на Python. В заключение поговорим о QMainWindow с полезными элементами интерфейса, такими как панели инструментов и меню. Подробно я расскажу о них в следующих руководствах.

Создание приложения

Установка PyQt:

pip install pyqt6
# и на будущее
pip install pyqt-tools

Сначала создадим новый файл Python с любым названием (например app.py) и сохраним его. Исходный код приложения показан ниже. Введите его полностью и постарайтесь не ошибиться. Если что-то напутаете, Python укажет, что именно:

from PyQt6.QtWidgets import QApplication, QWidget

import sys # Только для доступа к аргументам командной строки

# Приложению нужен один (и только один) экземпляр QApplication.
# Передаём sys.argv, чтобы разрешить аргументы командной строки для приложения.
# Если не будете использовать аргументы командной строки, QApplication([]) тоже работает
app = QApplication(sys.argv)

# Создаём виджет Qt — окно.
window = QWidget()
window.show()  # Важно: окно по умолчанию скрыто.

# Запускаем цикл событий.
app.exec()


# Приложение не доберётся сюда, пока вы не выйдете и цикл
# событий не остановится.

Запускаем приложение из командной строки, как и любой скрипт Python:

python3 app.py

Выполнив его, мы увидим окно. В Qt автоматически создаётся окно с обычным оформлением, возможностью его перетаскивать и менять размер. То, что вы увидите, зависит от платформы, где этот пример выполняется. Вот как отображается это окно на Windows, macOS и Linux (Ubuntu):

Окно на Windows, macOS и Linux

Окно на Windows, macOS и Linux

Разбор кода

Пройдём код построчно, чтобы понять, что именно происходит. Сначала мы импортируем классы PyQt для приложения: здесь это обработчик приложения QApplication и базовый пустой виджет графического интерфейса QWidget (оба из модуля QtWidgets):

from PyQt6.QtWidgets import QApplication, QWidget

Основные модули для Qt: QtWidgets, QtGui и QtCore.

Возможен ещё from import *, но этот вид импорта обычно не приветствуется в Python. Дальше создаём экземпляр QApplication и передаём sys.arg (список Python с аргументами командной строки, передаваемыми приложению):

app = QApplication(sys.argv)

Если не будете использовать аргументы командной строки для управления Qt, передайте пустой список:

app = QApplication([])

Затем создаём экземпляр QWidget, используя имя переменной window:

window = QWidget()
window.show()

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

Виджеты без родительского элемента по умолчанию невидимы. Поэтому после создания объекта window необходимо всегда вызывать функцию .show(), чтобы сделать его видимым. .show() можно удалить, но тогда, запустив приложение, вы не сможете выйти из него!

В окне находится пользовательский интерфейс приложения. У каждого приложения он как минимум один. Приложение (по умолчанию) завершает работу при закрытии последнего окна.

Наконец, вызываем app.exec(), чтобы запустить цикл события.

Что такое «цикл событий»?

Прежде чем вывести окно на экран, разберём ключевые понятия, касающиеся организации приложений в мире Qt. Если вам уже знакомы циклы событий, можете пропустить эту часть статьи.

Основной элемент всех приложений в Qt — класс QApplication. Для работы каждому приложению нужен один — и только один — объект QApplication, который содержит цикл событий приложения. Это основной цикл, управляющий всем взаимодействием пользователя с графическим интерфейсом:

При каждом взаимодействии с приложением — будь то нажатие клавиши, щелчок или движение мыши — генерируется событие, которое помещается в очередь событий. В цикле событий очередь проверяется на каждой итерации: если найдено ожидающее событие, оно вместе с управлением передаётся определённому обработчику этого события. Последний обрабатывает его, затем возвращает управление в цикл событий и ждёт новых событий. Для каждого приложения выполняется только один цикл событий.

Класс QApplication содержит цикл событий Qt (нужен один экземпляр QApplication). Приложение ждёт в цикле событий новое событие, которое будет сгенерировано при выполнении действия. Всегда выполняется только один цикл событий.

QMainWindow

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

import sys
from PyQt6.QtWidgets import QApplication, QPushButton

app = QApplication(sys.argv)

window = QPushButton("Push Me")
window.show()

app.exec()

Классно, но не очень полезно на самом деле: редко когда нужен пользовательский интерфейс, состоящий только из одного элемента управления. Зато возможность с помощью макетов вкладывать одни виджеты в другие позволяет создавать сложные пользовательские интерфейсы внутри пустого QWidget.

В Qt уже есть решение для окна — виджет QMainWindow, имеющий стандартные функции окна для использования в приложениях, который содержит панели инструментов, меню, строку состояния, закрепляемые виджеты и многое другое. Рассмотрим эти расширенные функции позже, а пока добавим в приложение простой, пустой QMainWindow:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow

app = QApplication(sys.argv)

window = QMainWindow()
window.show()

# Запускаем цикл событий.
app.exec()

Запускаем и видим главное окно. Точно такое же, как и раньше.

QMainWindow пока не очень интересный. Добавим контент. Чтобы сделать настраиваемое окно, лучше создать подкласс QMainWindow, а затем настроить окно в блоке __init__. Так окно станет независимым в плане поведения. Итак, добавляем подкласс QMainWindow — MainWindow:

import sys

from PyQt6.QtCore import QSize, Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton


# Подкласс QMainWindow для настройки главного окна приложения
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")
        button = QPushButton("Press Me!")

        # Устанавливаем центральный виджет Window.
        self.setCentralWidget(button)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Для этого демо используем QPushButton. Основные виджеты Qt всегда импортируются из пространства имён QtWidgets, как и классы QMainWindow и QApplication. При использовании QMainWindow задействуем .setCentralWidget для размещения виджета (здесь виджет — QPushButton) в QMainWindow, по умолчанию он занимает всё окно. Как добавлять в окна несколько виджетов? Об этом поговорим рассмотрим в руководстве по макетам.

При создании подкласса из класса Qt, чтобы разрешить Qt настраивать объект, всегда нужно вызывать функцию super __init__.

В блоке __init__ сначала используем .setWindowTitle(), чтобы поменять заголовок главного окна. Затем добавляем первый виджет — QPushButton — в середину окна. Это один из основных виджетов Qt. При создании кнопки можно ввести текст, который будет на ней отображаться. Вызываем .setCentralWidget() в окне. Это специальная функция QMainWindow, которая позволяет установить виджет на середину окна.

Запускаем и снова видим окно, но на этот раз с виджетом QPushButton в центре. Нажатие кнопки ничего не даст — с этим мы разберёмся после:

QMainWindow с одной кнопкой QPushButton на Windows, macOS и Linux

QMainWindow с одной кнопкой QPushButton на Windows, macOS и Linux

Скоро мы подробно рассмотрим другие виджеты, но, если вам не терпится и хочется забежать вперёд, можете заглянуть в документацию QWidget. Попробуйте добавить различные виджеты в окно.

Изменение размеров окон и виджетов

Сейчас размер окна можно свободно поменять: щёлкните мышью на любой угол и перетаскивайте, меняя таким образом размер. Можно дать возможность пользователям самим менять размер приложений, а можно установить ограничения на минимальные или максимальные размеры или фиксированный размер окна.

В Qt размеры определяются с помощью объекта QSize. Он принимает параметры ширины и высоты. Например, так создаётся окно фиксированного размера 400 x 300 пикселей:

import sys

from PyQt6.QtCore import QSize, Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton


# Подкласс QMainWindow для настройки главного окна приложения
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        button = QPushButton("Press Me!")

        self.setFixedSize(QSize(400, 300))

        # Устанавливаем центральный виджет Window.
        self.setCentralWidget(button)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Запускаем и видим окно фиксированного размера. Поменять его размер не получится.

Окно фиксированного размера

Окно фиксированного размера

Элемент управления maximize отключён на Windows и Linux. На macOS можно развернуть приложение на весь экран, но размер центрального виджета не изменится.

Кроме .setFixedSize() можно также вызвать .setMinimumSize() и .setMaximumSize(), чтобы установить минимальный и максимальный размеры соответственно. Попробуйте сами! Эти методы регулирования размеров работают в любом виджете. Продолжить изучение Python вы сможете на наших курсах:

  • Курс Python-разработчик

  • Профессия Fullstack-разработчик на Python

  • Курс «Python для веб-разработки»

А ещё вы можете приобрести книгу автора этих уроков или продолжить чтение.


Слоты и сигналы

Ранее мы рассмотрели классы QApplication и QMainWindow, цикл событий и добавили в окно простой виджет. А теперь изучим механизмы Qt для взаимодействия виджетов и окон друг с другом. В статью внесены изменения, связанные с PyQt6.

Мы создали окно и добавили в него простой виджет push button, но кнопка пока бесполезна. Нужно связать действие нажатия кнопки с происходящим. В Qt это делается с помощью сигналов и слотов или событий.

Сигналы — это уведомления, отправляемые виджетами, когда что-то происходит. Этим «чем-то» может быть что угодно — нажатие кнопки, изменение текста в поле ввода или изменение текста в окне. Многие сигналы инициируются в ответ на действия пользователя, но не только: в сигналах могут отправляться данные с дополнительным контекстом произошедшего.

Можно также писать собственные сигналы, их мы рассмотрим позже.

Слоты в Qt — это приёмники сигналов. Слотом в приложении на Python можно сделать любую функцию (или метод), просто подключив к нему сигнал. Принимающая функция получает данные, отправляемые ей в сигнале. У многих виджетов Qt есть встроенные слоты, а значит, виджеты можно подключать друг к другу напрямую.

Рассмотрим основные сигналы Qt и их использование для подключения виджетов в приложениях. Сохраните эту заготовку приложения в файле app.py:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("My App")


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Сигналы QPushButton

Сейчас у нас есть QMainWindow с центральным виджетом QPushButton. Подключим эту кнопку к пользовательскому методу Python. Создадим простой настраиваемый слот the_button_was_clicked, принимающий сигнал clicked от QPushButton:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        button = QPushButton("Press Me!")
        button.setCheckable(True)
        button.clicked.connect(self.the_button_was_clicked)

        # Устанавливаем центральный виджет Window.
        self.setCentralWidget(button)

    def the_button_was_clicked(self):
        print("Clicked!")


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Запускаем. Если нажать на кнопку, в консоли появится текст Clicked! («Нажата!»):

Clicked!
Clicked!
Clicked!
Clicked!

Получение данных

В сигналах может отправляться дополнительная информация о произошедшем. И сигнал .clicked — не исключение: с его помощью сообщается о нажатом (или переключенном) состоянии кнопки. Для обычных кнопок это значение всегда False, поэтому первый слот проигнорировал эти данные. Включим возможность нажатия кнопки, чтобы увидеть этот эффект. Ниже добавляется второй слот и выводится состояние нажатия:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        button = QPushButton("Press Me!")
        button.setCheckable(True)
        button.clicked.connect(self.the_button_was_clicked)
        button.clicked.connect(self.the_button_was_toggled)

        self.setCentralWidget(button)

    def the_button_was_clicked(self):
        print("Clicked!")

    def the_button_was_toggled(self, checked):
        print("Checked?", checked)

Запускаем! Если нажать на кнопку, она подсветится и станет checked («Нажатой»). Чтобы отключить её, нажимаем ещё раз. Найдите состояние нажатия в консоли:

Clicked!
Checked? True
Clicked!
Checked? False
Clicked!
Checked? True
Clicked!
Checked? False
Clicked!
Checked? True

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

Хранение данных

Текущее состояние виджета на Python часто хранят в переменной, что позволяет работать со значениями без доступа к исходному виджету. Причём для их хранения используются отдельные переменные или словарь. В следующем примере сохраняем значение кнопки checked («Нажата») в переменной button_is_checked в self:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.button_is_checked = True

        self.setWindowTitle("My App")

        button = QPushButton("Press Me!")
        button.setCheckable(True)
        button.clicked.connect(self.the_button_was_toggled)
        button.setChecked(self.button_is_checked)

        self.setCentralWidget(button)

    def the_button_was_toggled(self, checked):
        self.button_is_checked = checked

        print(self.button_is_checked)

Сначала устанавливаем переменной значение по умолчанию True, а затем используем это значение, чтобы установить исходное состояние виджета. Когда состояние виджета меняется, получаем сигнал и соответственно обновляем переменную.

Эта же схема применима к любым виджетам PyQt. Если в виджете нет сигнала, которым отправляется текущее состояние, нужно получить значение из виджета прямо в обработчике. Например, здесь мы проверяем состояние checked («Нажата») в нажатом обработчике:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.button_is_checked = True

        self.setWindowTitle("My App")

        self.button = QPushButton("Press Me!")
        self.button.setCheckable(True)
        self.button.released.connect(self.the_button_was_released)
        self.button.setChecked(self.button_is_checked)

        self.setCentralWidget(self.button)

    def the_button_was_released(self):
        self.button_is_checked = self.button.isChecked()

        print(self.button_is_checked)

Сохраним ссылку на кнопку в self, чтобы получить к ней доступ в слоте.

Сигнал released срабатывает, когда кнопка отпускается, при этом состояние нажатия не отправляется. Его получают из кнопки в обработчике, используя .isChecked().

Изменение интерфейса

Мы уже видели, как принимаются сигналы и выводятся на консоль результаты. Но что происходит с интерфейсом, когда нажимают на кнопку? Обновим метод слота, чтобы изменить кнопку, поменяв текст, отключив её и сделав её недоступной. И отключим пока состояние, допускающее нажатие:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        self.button = QPushButton("Press Me!")
        self.button.clicked.connect(self.the_button_was_clicked)

        self.setCentralWidget(self.button)

    def the_button_was_clicked(self):
        self.button.setText("You already clicked me.")
        self.button.setEnabled(False)

        # Также меняем заголовок окна.
        self.setWindowTitle("My Oneshot App")

Снова нужен доступ к кнопке в методе the_button_was_clicked, поэтому сохраняем ссылку на неё в self. Чтобы поменять текст кнопки, передаём str в .setText(). Чтобы отключить кнопку, вызываем .setEnabled() с аргументом False. И запускаем программу. Если нажать на кнопку, текст изменится и кнопка станет недоступной.

В методах слота можно не только менять кнопку, которая активирует сигнал, но и делать всё что угодно. Например, поменять заголовок окна, добавив в метод the_button_was_clicked эту строку:

self.setWindowTitle("A new window title")

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

from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton

import sys
from random import choice

window_titles = [
    'My App',
    'My App',
    'Still My App',
    'Still My App',
    'What on earth',
    'What on earth',
    'This is surprising',
    'This is surprising',
    'Something went wrong'
]


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.n_times_clicked = 0

        self.setWindowTitle("My App")

        self.button = QPushButton("Press Me!")
        self.button.clicked.connect(self.the_button_was_clicked)

        self.windowTitleChanged.connect(self.the_window_title_changed)

        # Устанавливаем центральный виджет Window.
        self.setCentralWidget(self.button)

    def the_button_was_clicked(self):
        print("Clicked.")
        new_window_title = choice(window_titles)
        print("Setting title:  %s" % new_window_title)
        self.setWindowTitle(new_window_title)

    def the_window_title_changed(self, window_title):
        print("Window title changed: %s" % window_title)

        if window_title == 'Something went wrong':
            self.button.setDisabled(True)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Сначала создаём список заголовков окна и выбираем один из них наугад, используя встроенную функцию Python random.choice(). Подключаем пользовательский метод слота the_window_title_changed к сигналу окна .windowTitleChanged.

При нажатии на кнопку заголовок окна случайным образом изменится. Если новый заголовок окна изменится на Something went wrong («Что-то пошло не так»), кнопка отключится.

Запускаем! Нажимайте на кнопку, пока заголовок не изменится на Something went wrong. В этом примере стоит обратить внимание вот на что:

  1. Сигнал windowTitleChanged при установке заголовка окна выдаётся не всегда. Он срабатывает, только если новый заголовок отличается от предыдущего: если один и тот же заголовок устанавливается несколько раз, сигнал срабатывает только в первый раз. Чтобы избежать неожиданностей, важно перепроверять условия срабатывания сигналов при их использовании в приложении.

  2. С помощью сигналов создаются цепочки. Одно событие — нажатие кнопки — может привести к тому, что поочерёдно произойдут другие. Эти последующие эффекты отделены от того, что их вызвало. Они возникают согласно простым правилам. И это отделение эффектов от их триггеров — один из ключевых принципов, которые учитываются при создании приложений с графическим интерфейсом. Возвращаться к этому будем на протяжении всего курса.

Мы рассмотрели сигналы и слоты, показали простые сигналы и их использование для передачи данных и состояния в приложении. Теперь переходим к виджетам Qt, которые будут использоваться в приложениях вместе с сигналами.

Подключение виджетов друг к другу напрямую

Мы уже видели примеры подключения сигналов виджетов к методам Python. Когда сигнал из виджета срабатывает, вызывается метод Python, из сигнала он получает данные. Но для обработки сигналов не всегда нужна функция Python — можно подключать виджеты друг к другу напрямую.

Добавим в окно виджеты QLineEdit и QLabel. В __init__ для окна и подключим сигнал редактирования строки .textChanged к методу .setText в QLabel. Когда в QLineEdit меняется текст, он сразу будет поступать в QLabel (в метод .setText):

from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QLineEdit, QVBoxLayout, QWidget

import sys


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        self.label = QLabel()

        self.input = QLineEdit()
        self.input.textChanged.connect(self.label.setText)

        layout = QVBoxLayout()
        layout.addWidget(self.input)
        layout.addWidget(self.label)

        container = QWidget()
        container.setLayout(layout)

        # Устанавливаем центральный виджет Window.
        self.setCentralWidget(container)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

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

Запускаем программу:

Введите текст в верхнем поле — он сразу появится в виде метки.

У большинства виджетов Qt есть доступные слоты, к которым подключается любой сигнал, возврощающий тот же тип, что он принимает. В документации по виджетам, в разделе Public Slots («Общедоступные слоты»), имеются слоты для каждого виджета. Посмотрите документацию для QLabel.

События

Любое взаимодействие пользователя с приложением Qt — это событие. Есть много типов событий, каждое из которых — это отдельный тип взаимодействия. В Qt события представлены объектами событий, в которые упакована информация о произошедшем. События передаются определённым обработчикам событий в виджете, где произошло взаимодействие.

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

QMouseEvent — одно из основных событий, получаемых виджетами. События QMouseEvent создаются для каждого отдельного нажатия кнопки мыши и её перемещения в виджете. Вот обработчики событий мыши:

Обработчик

Событие

mouseMoveEvent

Мышь переместилась

mousePressEvent

Кнопка мыши нажата

mouseReleaseEvent

Кнопка мыши отпущена

mouseDoubleClickEvent

Обнаружен двойной клик

Например, нажатие на виджет приведёт к отправке QMouseEvent в обработчик событий .mousePressEvent в этом виджете.

События можно перехватывать, создав подкласс и переопределив метод обработчика в этом классе. Их можно фильтровать, менять или игнорировать, передавая обычному обработчику путём вызова функции суперкласса методом super(). Они добавляются в класс главного окна следующим образом (в каждом случае в e будет получено входящее событие):

import sys

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QLabel, QMainWindow, QTextEdit


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.label = QLabel("Click in this window")
        self.setCentralWidget(self.label)

    def mouseMoveEvent(self, e):
        self.label.setText("mouseMoveEvent")

    def mousePressEvent(self, e):
        self.label.setText("mousePressEvent")

    def mouseReleaseEvent(self, e):
        self.label.setText("mouseReleaseEvent")

    def mouseDoubleClickEvent(self, e):
        self.label.setText("mouseDoubleClickEvent")


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

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

События перемещения мыши регистрируются только при нажатой кнопке. Чтобы это изменить, вызовите в окне self.setMouseTracking(True). События press («Нажатие кнопки»), click («Клика») и double-click («Двойного клика») срабатывают при нажатии кнопки. Событие release («Отпускание») срабатывает, только когда кнопка отпускается. Клик пользователя регистрируется обычно при нажатии кнопки мыши и её отпускании.

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

События управления мышью

В Qt все события управления мышью отслеживаются с помощью объекта QMouseEvent. При этом информация о событии считывается из следующих методов событий:

Метод

Возвращает

.button()

Конкретную кнопку, вызвавшую данное событие

.buttons()

Состояние всех кнопок мыши (флаги OR)

.position()

Относительную позицию виджета в виде целого QPoint .

Эти методы используются в обработчике событий, чтобы на разные события реагировать по-разному или полностью их игнорировать. Через методы позиционирования в виде объектов QPoint предоставляется глобальная и локальная (касающаяся виджета) информация о местоположении. Сведения о кнопках поступают с использованием типов кнопок мыши из пространства имён Qt. Например, в этом коде показаны разные реакции на нажатие левой, правой или средней кнопки мыши в окне:

    def mousePressEvent(self, e):
        if e.button() == Qt.LeftButton:
            # здесь обрабатываем нажатие левой кнопки
            self.label.setText("mousePressEvent LEFT")

        elif e.button() == Qt.MiddleButton:
            # здесь обрабатываем нажатие средней кнопки.
            self.label.setText("mousePressEvent MIDDLE")

        elif e.button() == Qt.RightButton:
            # здесь обрабатываем нажатие правой кнопки.
            self.label.setText("mousePressEvent RIGHT")

    def mouseReleaseEvent(self, e):
        if e.button() == Qt.LeftButton:
            self.label.setText("mouseReleaseEvent LEFT")

        elif e.button() == Qt.MiddleButton:
            self.label.setText("mouseReleaseEvent MIDDLE")

        elif e.button() == Qt.RightButton:
            self.label.setText("mouseReleaseEvent RIGHT")

    def mouseDoubleClickEvent(self, e):
        if e.button() == Qt.LeftButton:
            self.label.setText("mouseDoubleClickEvent LEFT")

        elif e.button() == Qt.MiddleButton:
            self.label.setText("mouseDoubleClickEvent MIDDLE")

        elif e.button() == Qt.RightButton:
            self.label.setText("mouseDoubleClickEvent RIGHT")

Идентификаторы кнопок определяются в пространстве имён Qt:

Код

Бинарное значение

Описание

Qt.NoButton

0 (000)

Кнопка не нажата, или событие не связано с нажатием кнопки

Qt.LeftButton

1 (001)

Левая кнопка нажата

Qt.RightButton

2 (010)

Правая кнопка нажата

Qt.MiddleButton

4 (100)

Средняя кнопка [обычно это колёсико мыши] нажата

В мышках для правшей положения левой и правой кнопок меняются местами, то есть при нажатии правой кнопки вернётся Qt.LeftButton. Иными словами, учитывать ориентацию мыши не нужно.

Контекстные меню

Контекстные меню — это небольшие контекстно-зависимые меню, которые обычно появляются в окне при нажатии правой кнопкои мыши. В Qt у виджетов есть определённое событие для активации таких меню.

В примере ниже мы будем перехватывать событие .contextMenuEvent в QMainWindow. Это событие запускается всякий раз перед самым появлением контекстного меню, а передаётся событие с одним значением типа QContextMenuEvent.

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

import sys

from PyQt6.QtCore import Qt
from PyQt6.QtGui import QAction
from PyQt6.QtWidgets import QApplication, QLabel, QMainWindow, QMenu


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

    def contextMenuEvent(self, e):
        context = QMenu(self)
        context.addAction(QAction("test 1", self))
        context.addAction(QAction("test 2", self))
        context.addAction(QAction("test 3", self))
        context.exec(e.globalPos())


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Если запустить этот код и нажать правой кнопкой в окне, появится контекстное меню. В действиях меню можно настроить слоты .triggered как обычные (и повторно использовать действия, определённые для меню и панелей инструментов).

При передаче исходного положения в функцию exec оно должно соответствовать родительскому элементу, переданному при определении. В нашем случае в качестве родительского элемента передаётся self, поэтому используем глобальное положение. Для полноты картины нужно сказать, что создавать контекстные меню можно и при помощи сигналов:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.show()

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.on_context_menu)

    def on_context_menu(self, pos):
        context = QMenu(self)
        context.addAction(QAction("test 1", self))
        context.addAction(QAction("test 2", self))
        context.addAction(QAction("test 3", self))
        context.exec(self.mapToGlobal(pos))

Что выбрать — решать только вам.

Иерархия событий

В PyQt каждый виджет — это часть двух различных иерархий: иерархии объектов в Python и иерархии макета в Qt. Реакция на события или их игнорирование влияет на поведение пользовательского интерфейса.

Перенаправление наследования Python

Часто бывает нужно перехватить событие, что-то с ним сделать, запустив при этом поведение обработки событий по умолчанию. Если объект унаследован от стандартного виджета, у него наверняка будет поведение по умолчанию. Запустить его можно, методом super() вызвав реализацию из суперкласса. Будет вызван именно суперкласс в Python, а не .parent() из PyQt:

def mousePressEvent(self, event):
    print("Mouse pressed!")
    super(self, MainWindow).contextMenuEvent(event)

Интерфейс ведёт себя как раньше, при этом мы добавили новое поведение, которое не вмешивается в прежнее.

Передача вверх по иерархии макета

Когда в приложение добавляется виджет, он также получает из макета другой родительский элемент. Чтобы найти родительский элемент виджета, надо вызвать функцию .parent(). Иногда эти родительские элементы указываются вручную (и часто автоматически), например для QMenu или QDialog. Когда в главное окно добавляется виджет, оно становится родительским элементом виджета.

Когда события создаются для взаимодействия пользователя с пользовательским интерфейсом, они передаются в его самый верхний виджет. Если в окне есть кнопка и вы нажмёте её, она получит событие первой.

Если первый виджет не может обработать событие, оно перейдёт к следующему по очереди родительскому виджету. Эта передача вверх по иерархии вложенных виджетов продолжится, пока событие не будет обработано или не достигнет главного окна. В обработчиках событий событие помечают как обработанное через вызов .accept():

    class CustomButton(QPushButton)
        def mousePressEvent(self, e):
            e.accept()

Вызвав в объекте события .ignore(), помечают его как необработанное. В этом случае событие будет передаваться по иерархии вверх:

    class CustomButton(QPushButton)
        def event(self, e):
            e.ignore()

Чтобы виджет пропускал события, вы можете спокойно игнорировать те, на которые каким-то образом реагировали. Аналогично вы можете отреагировать на одни события, заглушая другие. А продолжить изучение Python вы сможете на наших курсах:

  • Курс Python-разработчик

  • Профессия Fullstack-разработчик на Python

  • Курс «Python для веб-разработки»

Напомним также о книге автора этих уроков.


Виджеты

В большинстве пользовательских интерфейсов и в Qt «виджет» — это компонент, с которым взаимодействует пользователь. Пользовательские интерфейсы состоят из нескольких виджетов, расположенных внутри окна. В Qt большой выбор виджетов и можно создать собственные виджеты.

Краткое демо

Посмотрим на самые распространённые виджеты PyQt. Они создаются и добавляются в макет окна с помощью этого кода (работу макетов в Qt рассмотрим в следующем руководстве):

import sys

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (
    QApplication,
    QCheckBox,
    QComboBox,
    QDateEdit,
    QDateTimeEdit,
    QDial,
    QDoubleSpinBox,
    QFontComboBox,
    QLabel,
    QLCDNumber,
    QLineEdit,
    QMainWindow,
    QProgressBar,
    QPushButton,
    QRadioButton,
    QSlider,
    QSpinBox,
    QTimeEdit,
    QVBoxLayout,
    QWidget,
)


# Подкласс QMainWindow для настройки основного окна приложения
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Widgets App")

        layout = QVBoxLayout()
        widgets = [
            QCheckBox,
            QComboBox,
            QDateEdit,
            QDateTimeEdit,
            QDial,
            QDoubleSpinBox,
            QFontComboBox,
            QLCDNumber,
            QLabel,
            QLineEdit,
            QProgressBar,
            QPushButton,
            QRadioButton,
            QSlider,
            QSpinBox,
            QTimeEdit,
        ]

        for w in widgets:
            layout.addWidget(w())

        widget = QWidget()
        widget.setLayout(layout)

        # Устанавливаем центральный виджет окна. Виджет будет расширяться по умолчанию,
        # заполняя всё пространство окна.
        self.setCentralWidget(widget)


app = QApplication(sys.argv)
window = MainWindow()
window.show()

app.exec()

Запускаем! Появится окно со всеми созданными виджетами:

Виджеты на Windows, Mac и Ubuntu Linux

Виджеты на Windows, Mac и Ubuntu Linux

Посмотрим внимательно на все эти виджеты:

Класс виджета

Описание виджета

QCheckbox

Чекбокс

QComboBox

Окно выпадающего списка

QDateEdit

Для редактирования даты и времени

QDateTimeEdit

Для редактирования даты и времени

QDial

Поворотный циферблат

QDoubleSpinbox

Спиннер для чисел с плавающей точкой

QFontComboBox

Список шрифтов

QLCDNumber

Довольно неприятный дисплей LCD

QLabel

Просто метка, не интерактивная

QLineEdit

Поле ввода со строкой

QProgressBar

Индикатор выполнения

QPushButton

Кнопка

QRadioButton

Переключаемый набор, в котором активен только один элемент

QSlider

Слайдер

QSpinBox

Спиннер для целых чисел

QTimeEdit

Поле редактирования времени

Их гораздо больше, но они не поместятся в статью. Полный список есть в документации Qt.

Разберём подробно самые используемые виджеты и поэкспериментируем с ними в простом приложении. Сохраните следующий код в файле app.py и, запустив его, убедитесь, что он работает:

import sys
from PyQt6.QtWidgets import (
    QMainWindow, QApplication,
    QLabel, QCheckBox, QComboBox, QListBox, QLineEdit,
    QLineEdit, QSpinBox, QDoubleSpinBox, QSlider
)
from PyQt6.QtCore import Qt

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("My App")


app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec()

Выше мы импортировали несколько виджетов Qt. Разберём каждый по очереди. Добавим их в приложение и посмотрим, как они себя ведут.

QLabel

Начнём с QLabel, одного из простейших виджетов в Qt. Он состоит из строчки текста и устанавливается в приложении. Текст задаётся аргументом QLabel:

widget = QLabel("Hello")

Или с помощью метода .setText():

widget = QLabel("1")  # Создана метка с текстом 1.
widget.setText("2")   # Создана метка с текстом 2.

Параметры шрифта, например его размер или выравнивание в виджете, настраиваются так:

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("My App")

        widget = QLabel("Hello")
        font = widget.font()
        font.setPointSize(30)
        widget.setFont(font)
        widget.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)

        self.setCentralWidget(widget)

QLabel на Windows, Mac и Ubuntu Linux

QLabel на Windows, Mac и Ubuntu Linux

Рекомендация по шрифту: чтобы изменить свойства шрифта виджета, лучше получить текущий шрифт, обновить его и применить снова. Так начертание шрифта будет соответствовать ограничениям рабочего стола. Выравнивание указывается с помощью флага из пространства имён Qt. Вот флаги для горизонтального выравнивания:

Флаг PyQt6 (полный код)

Поведение

Qt.AlignmentFlag.AlignLeft

Выравнивает по левому краю

Qt.AlignmentFlag.AlignRight

Выравнивает по правому краю

Qt.AlignmentFlag.AlignHCenter

Центрирует по горизонтали в доступном пространстве

Qt.AlignmentFlag.AlignJustify

Выравнивает текст в доступном пространстве

Флаги используются вместе с помощью каналов (|), но флаги вертикального и горизонтального выравнивания не применяются одновременно:

Флаг PyQt6 (полный код)

Поведение

Qt.AlignmentFlag.AlignTop

Выравнивается по верху

Qt.AlignmentFlag.AlignBottom

Выравнивается по низу

Qt.AlignmentFlag.AlignVCenter

Центрирует вертикально в доступном пространстве

align_top_left = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop

При этом для совместного применения двух флагов (не A & B) используется канал | с операцией логического «ИЛИ». Эти флаги — неперекрывающиеся битовые маски. Например, у Qt.AlignmentFlag.AlignLeft шестнадцатеричное значение 0x0001, а у Qt.AlignmentFlag.AlignBottom — 0x0040. С помощью операции логического «ИЛИ» получаем значение «внизу слева» — 0x0041. Этот принцип применим и ко всем остальным парам флагов Qt. Если вам что-то здесь непонятно, смело пропускайте эту часть и переходите к следующей. Только не забывайте использовать |. Наконец, есть флаг, с помощью которого выполняется выравнивание по центру в обоих направлениях одновременно:

Флаг PyQt6

Поведение

Qt.AlignmentFlag.AlignCenter

Центрирует горизонтально и вертикально.

Как ни странно, QLabel используется и для показа изображения с помощью .setPixmap(). Этот метод принимает QPixmap, создаваемый передачей имени файла изображения в QPixmap. Среди примеров из этой книги есть файл otje.jpg, который отображается в окне так:

widget.setPixmap(QPixmap('otje.jpg'))

Кот Отье

Кот Отье

Какая мордочка! По умолчанию изображение масштабируется, сохраняя соотношение ширины и высоты. Если нужно растянуть и подогнать его по размерам окна, установите .setScaledContents(True) в QLabel:

widget.setScaledContents(True)

QCheckBox

А этот виджет, как следует из названия, предоставляет пользователю чекбокс с флажками. Как и во всех виджетах Qt, здесь есть настраиваемые параметры, изменяющие его поведение:

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("My App")

        widget = QCheckBox()
        widget.setCheckState(Qt.CheckState.Checked)

        # Включение трёх состояний: widget.setCheckState(Qt.PartiallyChecked)
        # Или: widget.setTriState(True)
        widget.stateChanged.connect(self.show_state)

        self.setCentralWidget(widget)


    def show_state(self, s):
        print(s == Qt.CheckState.Checked)
        print(s)

QCheckBox на Windows, Mac & Ubuntu Linux

QCheckBox на Windows, Mac & Ubuntu Linux

Состояние чекбокса устанавливается программно с помощью .setChecked или .setCheckState. Первый принимает True или False, то есть чекбокс с галочкой или без неё соответственно. В случае с .setCheckState с помощью флага пространства имён Qt также указывается конкретное состояние чекбокса:

Флаг PyQt6 (Полный код)

Состояние

Qt.CheckState.Unchecked

Элемент не отмечен

Qt.CheckState.PartiallyChecked

Элемент отмечен частично

Qt.CheckState.Checked

Элемент отмечен

Чекбокс, поддерживающий состояние частичной отмеченности (Qt.CheckState.PartiallyChecked) галочками, обычно называют «имеющим третье состояние», т. е. он и отмечен, и не отмечен. Чекбокс в этом состоянии часто отображается в виде серого флажка и используется в иерархических структурах чекбоксов, где дочерние чекбоксы связаны с родительскими.

Установив значение Qt.CheckState.PartiallyChecked, вы переведёте чекбокс в третье состояние. То же самое, но без перевода текущего состояния в состояние частичной отмеченности галочками, делается с помощью .setTriState(True).

При запуске скрипта номер текущего состояния отображается в виде значения целочисленного типа int. Причём состоянию, отмеченному галочками, соответствует 2, не отмеченному — 0, а состоянию частичной отмеченности — 1. Запоминать эти значения не нужно: К примеру, переменная пространства имён Qt.Checked равна 2. Это значение соответствующих флагов состояния. То есть вы можете проверить состояние с помощью state == Qt.Checked.

QComboBox

QComboBox — это выпадающий список, закрытый по умолчанию, с кнопкой, чтобы открыть его. Можно выбрать один элемент из списка, при этом выбранный в данный момент элемент отображается в виджете в виде метки. Поле со списком подходит для выбора варианта из длинного списка вариантов. Такое поле используется при выборе начертания или размера шрифта в текстовых редакторах. В Qt для выбора шрифта есть специальное поле со списком шрифтов — QFontComboBox.

В QComboBox можно добавлять элементы, передавая список строк в .addItems(). Элементы добавляются в порядке расположения соответствующих элементам строк кода.

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("My App")

        widget = QComboBox()
        widget.addItems(["One", "Two", "Three"])

        # Отправляет текущий индекс (позицию) выбранного элемента.
        widget.currentIndexChanged.connect( self.index_changed )

        # Есть альтернативный сигнал отправки текста.
        widget.textChanged.connect( self.text_changed )

        self.setCentralWidget(widget)


    def index_changed(self, i): # i — это int
        print(i)

    def text_changed(self, s): # s — это str
        print(s)

QComboBox на Windows, Mac и Ubuntu Linux

QComboBox на Windows, Mac и Ubuntu Linux

Сигнал .currentIndexChanged срабатывает при обновлении выбранного в данный момент элемента, индекс которого в списке передаётся по умолчанию. Кроме того, есть сигнал .currentTextChanged, при срабатывании которого вместо индекса предоставляется метка выбранного в данный момент элемента. Это часто оказывается полезнее.

Также QComboBox можно редактировать, вводя значения, которых в данный момент нет в списке, — вставлять их или просто использовать как значения. Поле делается редактируемым так:

widget.setEditable(True)

Чтобы определить, как обрабатываются вставляемые значения, устанавливается флаг. Флаги хранятся в самом классе QComboBox. Вот их список:

Флаг PyQt6 (полный код)

Поведение

QComboBox.InsertPolicy.NoInsert

Не вставлять

QComboBox.InsertPolicy.InsertAtTop

Вставить как первый элемент

QComboBox.InsertPolicy.InsertAtCurrent

Заменить текущий выбранный элемент

QComboBox.InsertPolicy.InsertAtBottom

Вставить после последнего элемента

QComboBox.InsertPolicy.InsertAfterCurrent

Вставить после текущего элемента

QComboBox.InsertPolicy.InsertBeforeCurrent

Вставить перед текущим элементом

QComboBox.InsertPolicy.InsertAlphabetically

Вставить в алфавитном порядке

Чтобы использовать их, применяется флаг:

widget.setInsertPolicy(QComboBox.InsertPolicy.InsertAlphabetically)

Кроме того, можно ограничить количество элементов поля, например при помощи .setMaxCount:

widget.setMaxCount(10)

Подробнее о QComboBox рассказывается здесь.

QListWidget

Этот виджет похож на QComboBox, но варианты здесь представлены в виде прокручиваемого списка элементов и возможен выбор нескольких элементов одновременно. В QListWidget есть сигнал currentItemChanged для отправки QListItem (элемента виджета списка) и сигнал currentTextChanged для отправки текста текущего элемента:

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("My App")

        widget = QListWidget()
        widget.addItems(["One", "Two", "Three"])

        widget.currentItemChanged.connect(self.index_changed)
        widget.currentTextChanged.connect(self.text_changed)

        self.setCentralWidget(widget)


    def index_changed(self, i); # i — не индекс, а сам QList
        print(i.text())

    def text_changed(self, s): # s — это строка
        print(s)

QListWidget на Windows, Mac и Ubuntu Linux

QListWidget на Windows, Mac и Ubuntu Linux

QLineEdit

Виджет QLineEdit — это простое однострочное текстовое поле для редактирования вводимых пользователями данных. Он используется для полей, где нет ограничений на входные данные. Например, при вводе адреса электронной почты или имени компьютера:

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("My App")

        widget = QLineEdit()
        widget.setMaxLength(10)
        widget.setPlaceholderText("Enter your text")

        #widget.setReadOnly(True) # раскомментируйте, чтобы сделать доступным только для чтения

        widget.returnPressed.connect(self.return_pressed)
        widget.selectionChanged.connect(self.selection_changed)
        widget.textChanged.connect(self.text_changed)
        widget.textEdited.connect(self.text_edited)

        self.setCentralWidget(widget)


    def return_pressed(self):
        print("Return pressed!")
        self.centralWidget().setText("BOOM!")

    def selection_changed(self):
        print("Selection changed")
        print(self.centralWidget().selectedText())

    def text_changed(self, s):
        print("Text changed...")
        print(s)

    def text_edited(self, s):
        print("Text edited...")
        print(s)

QLineEdit на Windows, Mac и Ubuntu Linux

QLineEdit на Windows, Mac и Ubuntu Linux

Как показано в этом коде, при однострочном редактировании вы можете установить максимальную длину текста.

В QLineEdit есть ряд сигналов для различных событий редактирования, в том числе при нажатии клавиши return (пользователем), когда пользователь изменил свой выбор. Также есть два сигнала редактирования: один — на случай, когда текст в поле отредактирован, другой — когда он изменён. Здесь различаются два вида изменений: пользовательские и выполненные программой. Сигнал textEdited отправляется только при редактировании текста пользователем.

Кроме того, с помощью маски ввода можно выполнить проверку вводимых данных, чтобы определить, какие символы поддерживаются и где. Применяется к соответствующему полю так:

widget.setInputMask('000.000.000.000;_')

Это позволяет использовать серию трёхзначных чисел, разделённых точками, для проверки адресов IPv4.

QSpinBox и QDoubleSpinBox

QSpinBox — это небольшое поле ввода чисел со стрелками для изменения значения. Оно поддерживает целые числа, а QDoubleSpinBox — числа с плавающей точкой:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        widget = QSpinBox()
        # Или: widget = QDoubleSpinBox()

        widget.setMinimum(-10)
        widget.setMaximum(3)
        # Или: widget.setRange(-10,3)

        widget.setPrefix("$")
        widget.setSuffix("c")
        widget.setSingleStep(3)  # Или, например, 0.5 в QDoubleSpinBox
        widget.valueChanged.connect(self.value_changed)
        widget.textChanged.connect(self.value_changed_str)

        self.setCentralWidget(widget)

    def value_changed(self, i):
        print(i)

    def value_changed_str(self, s):
        print(s)

Запустив код, вы увидите поле для ввода чисел. Значение в нём показывает префиксные и постфиксные блоки и ограничено диапазоном от +3 до –10:

QSpinBox на Windows, Mac и Ubuntu Linux

QSpinBox на Windows, Mac и Ubuntu Linux

В этом коде показан разнообразный функционал виджета. Чтобы задать диапазон допустимых значений, используются setMinimum и setMaximum. Одновременно они устанавливаются с помощью SetRange. Аннотация типов значений поддерживается префиксами и суффиксами, добавляемыми к числу. Например, для обозначений валюты или денежных единиц используются .setPrefix и .setSuffix соответственно.

Нажав на стрелки «вверх» и «вниз» на виджете, можно увеличить или уменьшить значение на величину, устанавливаемую с помощью .setSingleStep. Но это не повлияет на допустимые для виджета значения.

В QSpinBox и QDoubleSpinBox есть сигнал .valueChanged, срабатывающий при изменении их значений. С помощью необработанного сигнала .valueChanged отправляется числовое значение (целочисленного типа int или типа числа с плавающей точкой float), а с помощью .textChanged — значение в виде строки, включающей символы префикса и суффикса.

QSlider

QSlider — это ползунок, очень схожий по внутреннему функционалу с QDoubleSpinBox. Текущее значение представлено не числами, а в виде маркера ползунка, располагающегося по всей длине виджета. Этот виджет удобен для указания значения в промежутке между максимумом и минимумом, где абсолютная точность не требуется. Чаще всего этот тип виджетов используется при регулировке громкости. Есть и другие сигналы: .sliderMoved срабатывает при перемещении ползунка а .sliderPressed — при нажатии на ползунок:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        widget = QSlider()

        widget.setMinimum(-10)
        widget.setMaximum(3)
        # Или: widget.setRange(-10,3)

        widget.setSingleStep(3)

        widget.valueChanged.connect(self.value_changed)
        widget.sliderMoved.connect(self.slider_position)
        widget.sliderPressed.connect(self.slider_pressed)
        widget.sliderReleased.connect(self.slider_released)

        self.setCentralWidget(widget)

    def value_changed(self, i):
        print(i)

    def slider_position(self, p):
        print("position", p)

    def slider_pressed(self):
        print("Pressed!")

    def slider_released(self):
        print("Released")

Запустив код, вы увидите ползунок. Переместите его, чтобы изменить значение:

QSlider на Windows, Mac и Ubuntu Linux

QSlider на Windows, Mac и Ubuntu Linux

Также можно сделать вертикальный или горизонтальный ползунок, задав соответствующее расположение при его создании. Флаги расположения определены в пространстве имён Qt, например:

widget.QSlider(Qt.Orientiation.Vertical)

Или так:

widget.QSlider(Qt.Orientiation.Horizontal)

QDial

Наконец, QDial — это круговой виджет, схожий по функционалу с механическим ползунком из реального мира. Красиво, но с точки зрения пользовательского интерфейса не очень удобно. Он часто используется в аудиоприложениях:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        widget = QDial()
        widget.setRange(-10, 100)
        widget.setSingleStep(0.5)

        widget.valueChanged.connect(self.value_changed)
        widget.sliderMoved.connect(self.slider_position)
        widget.sliderPressed.connect(self.slider_pressed)
        widget.sliderReleased.connect(self.slider_released)

        self.setCentralWidget(widget)

    def value_changed(self, i):
        print(i)

    def slider_position(self, p):
        print("position", p)

    def slider_pressed(self):
        print("Pressed!")

    def slider_released(self):
        print("Released")

Запустив код, вы увидите круговой ползунок. Поверните его, чтобы выбрать число:

QDial на Windows, Mac и Ubuntu Linux

QDial на Windows, Mac и Ubuntu Linux

На сегодня мы заканчиваем, но это далеко не всё. Мы также расскажем о макете в PyQt, о работе с QAction, тулбарами, диалогами и не только. А пока ещё раз напоминаем о книге автора этих уроков и приглашаем на наши курсы:

  • Курс Python-разработчик

  • Профессия Fullstack-разработчик на Python

  • Курс «Python для веб-разработки»

Узнайте подробности здесь.

Профессии и курсы

Понравилась статья? Поделить с друзьями:
  • Как изменить текст на маленькие буквы если уже напечатано большими
  • Как изменить текст placeholder css
  • Как изменить текст на любом сайте
  • Как изменить текст notepad
  • Как изменить текст на логотипе