Перейти к содержимому

Qmainwindow pyqt6 как сделать сетку

  • автор:

PyQt6 — полное руководство для новичков. Продолжение

В первом материале мы рассказали о создании первого окна, о сигналах, слотах и событиях, а также о виджетах. Сегодня, к старту курса по Fullstack-разработке на Python, делимся продолжением — о макетах, работе с панелями инструментов и меню при помощи QAction, дополнительных и диалоговых окнах. За подробностями приглашаем под кат.

  1. Макеты
  2. Панели инструментов, меню и QAction
  3. Диалоговые окна и окна предупреждений
  4. Дополнительные окна

Макеты

Ранее мы создали окно и добавили в него виджет. Нужно добавить ещё виджеты и определить, где они окажутся. Для этого в Qt используются макеты. Доступны 4 базовых макета, приведённые в этой таблице:

Горизонтальный линейный макет

Вертикальный линейный макет

Индексируемая сетка X на Y

Уложенные друг на друга по оси Z виджеты

Также можно создать и разместить интерфейс графически с помощью Qt designer. Здесь используется код, чтобы была понятна базовая система.

В Qt есть три макета расположения виджетов: VBoxLayout, QHBoxLayout и QGridLayout. И есть QStackedLayout, позволяющий размещать виджеты один над другим в одном месте, одновременно отображая только один макет. Сначала понадобится простая схема приложения, в котором мы будем экспериментировать с различными макетами. Сохраните следующий код в файле app.py:

import sys from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget from PyQt6.QtGui import QPalette, QColor class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()

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

class Color(QWidget): def __init__(self, color): super(Color, self).__init__() self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.ColorRole.Window, QColor(color)) self.setPalette(palette)

В этом коде мы пишем подкласс QWidget для пользовательского виджета Color, при создании которого принимаем один параметр — color (str). Сначала устанавливаем .setAutoFillBackground в True, чтобы фон виджета автоматически заполнялся цветом окна. Затем получаем текущую палитру (по умолчанию это глобальная палитра рабочего стола) и меняем текущий цвет QPalette.Window на новый QColor, который соответствует переданному значению color. Мы применяем эту палитру к виджету. Результат — виджет, заполненный сплошным цветом (каким именно — указывается при его создании).

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

Color('red')

Сначала протестируем новый виджет Color, используя его для заполнения всего окна одним цветом. По завершении добавим его в QMainWindow с помощью .setCentralWidget и получим окно со сплошным красным цветом:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") widget = Color('red') self.setCentralWidget(widget)

Запускаем. Появится полностью красное окно, при этом виджет расширяется, заполняя всё доступное пространство.

Далее рассмотрим каждый из макетов Qt по очереди. Обратите внимание: макеты будут добавляться в окно, находясь в фиктивном QWidget.

QVBoxLayout: вертикально расположенные виджеты

В макете QVBoxLayout виджеты размещаются один над другим. При добавлении виджет отправляется в низ столбца.

QVBoxLayout, заполняемый сверху вниз

Добавим виджет в макет. Чтобы добавить макет в QMainWindow, нужно применить его к фиктивному QWidget, а затем использовать .setCentralWidget, чтобы применить виджет и макет к окну. Цветные виджеты расположатся в макете, находящемся в QWidget, в окне. Сначала просто добавляем красный виджет, как раньше:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QVBoxLayout() layout.addWidget(Color('red')) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)

Теперь вокруг красного виджета видна рамка. Это интервал между макетами — позже посмотрим, как его настроить.

Если добавить в макет ещё цветных виджетов, они разместятся вертикально в порядке добавления:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QVBoxLayout() layout.addWidget(Color('red')) layout.addWidget(Color('green')) layout.addWidget(Color('blue')) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)
QHBoxLayout: горизонтально расположенные виджеты

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

QHBoxLayout, заполняемый слева направо

Просто меняем макет QVBoxLayout на QHBoxLayout. Виджеты теперь располагаются слева направо:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QHBoxLayout() layout.addWidget(Color('red')) layout.addWidget(Color('green')) layout.addWidget(Color('blue')) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)
Вложенные макеты

Есть более сложные макеты, состоящие из вложенных друг в друга макетов. Такие вложения делаются в макете с помощью .addLayout. Ниже мы добавляем QVBoxLayout в основной макет QHBoxLayout. Если добавить в QVBoxLayout несколько виджетов, они примут вертикальное расположение в первом слоте макета-предка:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout3 = QVBoxLayout() layout2.addWidget(Color('red')) layout2.addWidget(Color('yellow')) layout2.addWidget(Color('purple')) layout1.addLayout( layout2 ) layout1.addWidget(Color('green')) layout3.addWidget(Color('red')) layout3.addWidget(Color('purple')) layout1.addLayout( layout3 ) widget = QWidget() widget.setLayout(layout1) self.setCentralWidget(widget)

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

Установим интервал между макетами с помощью .setContentMargins, а между элементами — с помощью .setSpacing:

layout1.setContentsMargins(0,0,0,0) layout1.setSpacing(20)

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

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout3 = QVBoxLayout() layout1.setContentsMargins(0,0,0,0) layout1.setSpacing(20) layout2.addWidget(Color('red')) layout2.addWidget(Color('yellow')) layout2.addWidget(Color('purple')) layout1.addLayout( layout2 ) layout1.addWidget(Color('green')) layout3.addWidget(Color('red')) layout3.addWidget(Color('purple')) layout1.addLayout( layout3 ) widget = QWidget() widget.setLayout(layout1) self.setCentralWidget(widget)
QGridLayout: виджеты в сетке

Несмотря на все достоинства QVBoxLayout и QHBoxLayout, очень сложно добиться ровного расположения виджетов разного размера, если использовать эти макеты, например, для размещения нескольких элементов формы. Проблему решает QGridLayout.

В QGridLayout показываются позиции сетки для каждого местоположения

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

QGridLayout с незаполненными слотами

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QGridLayout() layout.addWidget(Color('red'), 0, 0) layout.addWidget(Color('green'), 1, 0) layout.addWidget(Color('blue'), 1, 1) layout.addWidget(Color('purple'), 2, 1) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)
QStackedLayout: несколько виджетов в одном месте

Последним рассмотрим макет QStackedLayout. В нём элементы размещаются друг за другом. Можно выбрать, какой виджет показывать. QStackedLayout используется для слоёв векторной графики в графическом приложении или для имитации интерфейса вкладок. Есть и виджет-контейнер QStackedWidget с точно таким же принципом работы. Он применяется, когда с помощью .setCentralWidget стопка виджетов добавляется прямо в QMainWindow.

QStackedLayout — здесь оказывается видимым только самый верхний виджет, который первым добавляется в макетQStackedLayout — здесь выбран 2-й виджет (обозначен цифрой 1) и выдвинут вперёд

from PyQt6.QtWidgets import QStackedLayout # импортируем модули class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") layout = QStackedLayout() layout.addWidget(Color("red")) layout.addWidget(Color("green")) layout.addWidget(Color("blue")) layout.addWidget(Color("yellow")) layout.setCurrentIndex(3) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)

Именно с помощью QStackedWidget работают представления с вкладками. В любой момент времени видимым оказывается только одна вкладка (таб). С помощью .setCurrentIndex() или .setCurrentWidget() определяется, какой виджет отображать в тот или иной момент: здесь элемент задаётся по индексу в порядке добавления виджетов или по самому виджету.

Вот краткое демо с использованием QStackedLayout вместе с QButton при реализации интерфейса в виде вкладок:

import sys from PyQt6.QtCore import Qt from PyQt6.QtWidgets import ( QApplication, QHBoxLayout, QLabel, QMainWindow, QPushButton, QStackedLayout, QVBoxLayout, QWidget, ) from layout_colorwidget import Color class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") pagelayout = QVBoxLayout() button_layout = QHBoxLayout() self.stacklayout = QStackedLayout() pagelayout.addLayout(button_layout) pagelayout.addLayout(self.stacklayout) btn = QPushButton("red") btn.pressed.connect(self.activate_tab_1) button_layout.addWidget(btn) self.stacklayout.addWidget(Color("red")) btn = QPushButton("green") btn.pressed.connect(self.activate_tab_2) button_layout.addWidget(btn) self.stacklayout.addWidget(Color("green")) btn = QPushButton("yellow") btn.pressed.connect(self.activate_tab_3) button_layout.addWidget(btn) self.stacklayout.addWidget(Color("yellow")) widget = QWidget() widget.setLayout(pagelayout) self.setCentralWidget(widget) def activate_tab_1(self): self.stacklayout.setCurrentIndex(0) def activate_tab_2(self): self.stacklayout.setCurrentIndex(1) def activate_tab_3(self): self.stacklayout.setCurrentIndex(2) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()

Пользовательский интерфейс в виде вкладок, реализованный с помощью QStackedLayout

В Qt есть TabWidget, предоставляющий такой макет «из коробки», хотя и в виде виджета. Вот демо вкладки, воссоздаваемой с помощью QTabWidget:

import sys from PyQt6.QtCore import Qt from PyQt6.QtWidgets import ( QApplication, QLabel, QMainWindow, QPushButton, QTabWidget, QWidget, ) from layout_colorwidget import Color class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") tabs = QTabWidget() tabs.setTabPosition(QTabWidget.West) tabs.setMovable(True) for n, color in enumerate(["red", "green", "blue", "yellow"]): tabs.addTab(Color(color), color) self.setCentralWidget(tabs) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()

Интерфейс в виде вкладок с использованием QTabWidget

Видите? Немного проще и красивее! Расположение вкладок устанавливается по сторонам света, а возможность их перемещения — с помощью .setMoveable. Панель вкладок на macOS отличается от других: по умолчанию они здесь даны в виде кружков и обычно используются в панелях конфигурации. Для документов включается режим документа — здесь создаются тонкие вкладки, похожие на вкладки других платформ. Эта опция относится только к macOS:

 tabs = QTabWidget() tabs.setDocumentMode(True)

QTabWidget в режиме документа на macOS

Позже мы рассмотрим другие виджеты сложнее.

Продолжить изучение Python вы сможете по книге автора этих статей или на наших курсах:

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

Панели инструментов, меню и QAction

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

Панели инструментов

Панель инструментов — один из самых часто встречающихся элементов пользовательского интерфейса. Это панели с иконками и/или текстом, используемые в приложении для выполнения стандартных задач, доступ к которым через меню затруднителен. Этот функционал пользовательского интерфейса есть почти во всех приложениях. Хотя некоторые сложные приложения, в частности в пакете Microsoft Office, перешли на контекстные ленточные интерфейсы, для большинства создаваемых приложений обычно достаточно стандартной панели инструментов.

Стандартные элементы графического интерфейса

Начнём со «скелета» простого приложения и его настройки. Сохраните этот код в файле app.py (в нём прописан весь импорт для последующих этапов):

import sys from PyQt6.QtWidgets import ( QMainWindow, QApplication, QLabel, QToolBar, QStatusBar ) from PyQt6.QtGui import QAction, QIcon from PyQt6.QtCore import Qt class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My Awesome App") app = QApplication(sys.argv) w = MainWindow() w.show() app.exec()

Если вы переходите с PyQt5 на PyQt6, QAction в новой версии доступен через модуль QtGui.

Добавление панели инструментов

Панель инструментов в Qt создаётся из класса QToolBar. Добавим панель в приложение, создав сначала экземпляр класса, а затем вызвав .addToolbar в QMainWindow. Передав первым параметром QToolBar строку, задаём имя панели инструментов: по нему эта панель идентифицируется в пользовательском интерфейсе:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My Awesome App") label = QLabel("Hello!") label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.setCentralWidget(label) toolbar = QToolBar("My main toolbar") self.addToolBar(toolbar) def onMyToolBarButtonClick(self, s): print("click", s)

Запускаем. Появится тонкая серая полоска наверху окна. Это панель инструментов. Нажмите правую кнопку и выберите имя панели, чтобы отключить её.

Окно с панелью инструментов

Но как теперь вернуть панель инструментов? После её удаления негде нажать правой кнопкой, чтобы снова её добавить. Поэтому нужно или оставлять одну панель неудалённой, или иметь альтернативный интерфейс, чтобы включать и выключать панели.

Сделаем панель чуть интереснее. Вместо добавления виджета QButton используем дополнительный функционал Qt — класс QAction для описания абстрактных пользовательских интерфейсов.

С его помощью внутри одного объекта определяется несколько элементов интерфейса, с которыми пользователь сможет взаимодействовать. Например, опция «Вырезать» есть в меню «Правка», и в панели инструментов (значок ножниц) и доступна по комбинации клавиш Ctrl-X (Cmd-X на Mac).

Без QAction пришлось бы определять её в нескольких местах. А в Qt определяем один QAction с запущенным действием, которое добавляется и в меню, и в панель инструментов. У каждого QAction есть имена, сообщения о состоянии, иконки и сигналы, к которым можно подключиться (и многое другое).

Вот первый добавленный QAction:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My Awesome App") label = QLabel("Hello!") label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.setCentralWidget(label) toolbar = QToolBar("My main toolbar") self.addToolBar(toolbar) button_action = QAction("Your button", self) button_action.setStatusTip("This is your button") button_action.triggered.connect(self.onMyToolBarButtonClick) toolbar.addAction(button_action) def onMyToolBarButtonClick(self, s): print("click", s)

Сначала создаём функцию, принимающую сигнал от QAction (так мы проверяем её работоспособность). Затем определяем сам QAction. Когда создаётся экземпляр, передаётся метка для действия и/или иконка.

Также нужно передать любой QObject (это предок действия). Передаём self как ссылку на главное окно. Как ни странно, для QAction элемент-предок передаётся в последнем параметре.

Дальше настраиваем подсказку статуса — этот текст будет отображаться в строке состояния, как только она появится. Наконец, подключаем сигнал .triggered к пользовательской функции. Он срабатывает, когда вызывается (или активируется) QAction.

Запускаем! Появится кнопка с определённой нами меткой. Нажимаем её, и пользовательская функция выдаст click («Нажатие») и статус кнопки.

Панель инструментов с кнопкой QAction

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

Добавляем строку состояния. Создаём объект строки состояния, вызывая QStatusBar, и передаём его в .setStatusBar. Настройки этого statusBar (строки состояния) менять не нужно: просто передаём её в одной строке при создании:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My Awesome App") label = QLabel("Hello!") label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.setCentralWidget(label) toolbar = QToolBar("My main toolbar") self.addToolBar(toolbar) button_action = QAction("Your button", self) button_action.setStatusTip("This is your button") button_action.triggered.connect(self.onMyToolBarButtonClick) toolbar.addAction(button_action) self.setStatusBar(QStatusBar(self)) def onMyToolBarButtonClick(self, s): print("click", s)

Запускаем. Наводим курсор мыши на кнопку панели инструментов и видим в строке состояния текст статуса.

Текст строки состояния обновляется при наведении курсора на actions (действия)

Теперь сделаем QAction переключаемым: при первом нажатии он включается, при повторном — отключается. Для этого просто вызываем setCheckable(True) в объекте QAction:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My Awesome App") label = QLabel("Hello!") label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.setCentralWidget(label) toolbar = QToolBar("My main toolbar") self.addToolBar(toolbar) button_action = QAction("Your button", self) button_action.setStatusTip("This is your button") button_action.triggered.connect(self.onMyToolBarButtonClick) button_action.setCheckable(True) toolbar.addAction(button_action) self.setStatusBar(QStatusBar(self)) def onMyToolBarButtonClick(self, s): print("click", s)

Запускаем и нажимаем кнопку — её состояние переключается из нажатого в ненажатое. При этом пользовательская функция слота теперь чередует вывод True и False.

Включённая кнопка на панели инструментов

Есть .toggled, который сигнализирует только при включении/отключении кнопки. Эффект тот же, поэтому в .toggled особой надобности нет.

Добавим к кнопке иконку. Скачаем отличный набор красивых иконок Fugue 16 х 16 пикселей Юсукэ Камияманэ, которые придадут приложениям приятный профессиональный вид. Это бесплатно — при распространении приложения требуется только ссылка на автора.

Набор иконок Fugue от Юсукэ Камияманэ

Выбираем изображение (я выбрал файл bug.png) и копируем его в папку с исходным кодом. Создаём объект QIcon, передав имя файла классу, например QIcon(‘bug.png’). Если поместить файл в другую папку, нужен полный относительный или абсолютный путь к нему. Наконец, чтобы добавить иконку и кнопку в QAction, просто передаём её первым параметром при создании QAction.

Также нужно указать размер иконок, иначе вокруг них будет множество отступов. Сделаем это, вызвав функцию .setIconSize() с объектом QSize:

class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My Awesome App") label = QLabel("Hello!") label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.setCentralWidget(label) toolbar = QToolBar("My main toolbar") toolbar.setIconSize(QSize(16,16)) self.addToolBar(toolbar) button_action = QAction(QIcon("bug.png"), "Your button", self) button_action.setStatusTip("This is your button") button_action.triggered.connect(self.onMyToolBarButtonClick) button_action.setCheckable(True) toolbar.addAction(button_action) self.setStatusBar(QStatusBar(self)) def onMyToolBarButtonClick(self, s): print("click", s)

Запускаем. QAction теперь в виде иконки. Всё должно работать точно так же, как и раньше.

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

Внимание! Чтобы определить, что отображать на панели инструментов: иконку, текст или иконку с текстом, в Qt используются стандартные настройки ОС. Выбрать можно и самостоятельно с помощью .setToolButtonStyle. Этот слот принимает из пространства имён Qt такие флаги:

Флаг PyQt6 (полный код)

PyQt6 — полное руководство для новичков

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

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

Простое приложение 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 с полезными элементами интерфейса, такими как панели инструментов и меню. Подробно я расскажу о них в следующих руководствах.

Создание приложения
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

Разбор кода

Пройдём код построчно, чтобы понять, что именно происходит. Сначала мы импортируем классы 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

Скоро мы подробно рассмотрим другие виджеты, но, если вам не терпится и хочется забежать вперёд, можете заглянуть в документацию 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 создаются для каждого отдельного нажатия кнопки мыши и её перемещения в виджете. Вот обработчики событий мыши:

Вопросы с меткой [pyqt6]

Руководство по использованию метки pyqt6 отсутствует.

51 вопрос без принятого ответа или без ответа, за который были отданы голоса
Конкурсные
Неотвеченные

  • Конкурсные 0
  • Неотвеченные
  • Цитируемые
  • Рейтинг
  • Неотвеченные (мои метки)

Проблема при запуске PyQt6

Ошибка: from PyQt6.QtWidgets import QApplication, QWidget ImportError: DLL load failed while importing QtCore: The specified procedure could not be found. у меня винда 11, как решить эту проблему? .

задан 4 дек 2023 в 6:52
70 показов

Проблема с обновлением модели QAbstractTableModel в QTreeView

У меня есть модель, содержащая список класса MyClass. Для обновления данных в модели я написал функцию updateData, которая передаёт в модель новый список класса MyClass. Класс MyClass содержит .

задан 22 окт 2023 в 21:49
109 показов

PyQt6: Как создать таблицу с флажками в одном из столбцов?

Подскажите, пожалуйста, как на PyQt6 реализовать таблицу из 4 столбцов и N строк, которая, в последнем столбце, содержит только флажки? Таблица имеет отображение в базе данных и последний столбец .

задан 19 сен 2023 в 9:19
125 показов

Уcтановка PyQt6 на Raspberry Pi

При попытке уcтановить библиотеку PyQt6 на Raspberry Pi cредcтвами pip (команда «pip install PyQt6») я получаю cледующую ошибку: AttributeError: module ‘sipbuild.api’ has no attribute ‘.

задан 20 фев 2023 в 11:34
68 показов

Не отображаются объекты на сцене QGraphicsScene

Задача была следующая — создаем сцену и добавляем на нее много объектов в другом потоке, пока объекты добавляются, сама сцена не виснет, т.е. я могу передвигаться скроллами по сцене без фризов, да еще .

задан 7 дек 2022 в 18:47
89 показов

Не компилируется проект на PyQt6

Использую PyInstaller v5.6.2. Прописываю pyinstaller mp3pyqt6.py, после чего в mp3pyqt6.spec добавляю нужные файлы, обновляя командой pyinstaller mp3pyqt6.spec. В консоле, которая появляется вместе с .

задан 10 ноя 2022 в 18:28
13 показов

Построение векторных полей в pyqtgraph

Недавно решил переписать своё приложение по построению векторных электростатических полей с TKinter на PyQT6. В предыдущей версии для отрисовки графика я использовал matplotlib и её функцию streamplot(.

задан 29 дек 2023 в 8:51

Как передать переменную в дочернее окно?

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

задан 28 дек 2023 в 10:01

Проблемы с callback в `QWebEnginePage().runJavaScript(js_code, callback)`

В настоящее время я изучаю PyQt6 и мне интересно узнать больше о возможностях QtWebEngine. Буду признателен, если вы порекомендуете какие-нибудь руководства или учебные пособия по изучению .

задан 17 дек 2023 в 17:31
29 показов

Изменение размера дочернего виджета при масштабировании колесом родительского

у меня есть родительский виджет(QWidget). Я рисую на нем сетку с помощью метода paintEvent. Этот виджет имеет дочерний виджет(QWidget). Дочерний виджет может перемещаться только по ячейкам сетки .

задан 8 дек 2023 в 10:07
17 показов

Как я могу получить заголовки ответа responseHeaders() из PyQt6.QtWebEngineCore.QWebEngineLoadingInfo()

Вот пример кода: from PyQt6.QtWidgets import QApplication from PyQt6.QtWebEngineWidgets import QWebEngineView from PyQt6.QtWebEngineCore import QWebEngineLoadingInfo from PyQt6.QtCore import QUrl .

задан 6 дек 2023 в 20:14
59 показов

При связи сигнала со слотом в PyQt6 генерируется ошибка

Я переписываю программу с Python2, PyQt4 на Python3, PyQt6. Столкнулся с проблемой переформатирования старых сигналов на их новый формат вызова в PyQt6. Старый сигнал выглядел так: self.connect(.

задан 31 окт 2023 в 14:32
56 показов

Как импортировать шрифт в PyQT6

Читал на форумах что PyQT6 не поддерживает файлы ресурсов. Воспользовался модулем pyqt6rc 0.6.0. Попробовал что-то вроде этого (на странице модуля был приведён пример только с иконками): from .

задан 26 окт 2023 в 19:00
88 показов

QMessageBox срабатывает только если окно приложения находится в фокусе?

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

задан 24 окт 2023 в 8:56

Заполнение comboBox из БД SQLite в PyQt

Пытаюсь заполнить comboBox из БД SQLite, но ничего не подтягивается. Мой код import sys from PyQt6 import QtWidgets from PyQt6.QtSql import QSqlTableModel import sqlite3 from test_rt_sql import .

задан 13 окт 2023 в 21:23
15 30 50 на странице

    Важное на Мете

Связанные метки

Подписаться на ленту

Лента вопросов с наивысшим рейтингом по меткам [pyqt6]

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Вопросы с меткой [pyqt6]

Руководство по использованию метки pyqt6 отсутствует.

159 вопросов
Конкурсные
Неотвеченные

  • Конкурсные 0
  • Неотвеченные
  • Цитируемые
  • Рейтинг
  • Неотвеченные (мои метки)

13 показов

Построение векторных полей в pyqtgraph

Недавно решил переписать своё приложение по построению векторных электростатических полей с TKinter на PyQT6. В предыдущей версии для отрисовки графика я использовал matplotlib и её функцию streamplot(.

задан 29 дек 2023 в 8:51

Как передать переменную в дочернее окно?

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

задан 28 дек 2023 в 10:01

Извлечение данных из динамически генерируемых виджетов PyQt

Как можно получить текст из динамически генерируемых QLineEdit в PyQT5/PyQT6? Я смог извлечь текст только из последнего созданного виджета, но я бы хотел проверять все созданные виджеты и извлекать .

задан 26 дек 2023 в 14:30

Не создаётся ScrollBar в QScrollArea, PyQt

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

задан 26 дек 2023 в 7:18

Проблемы с callback в `QWebEnginePage().runJavaScript(js_code, callback)`

В настоящее время я изучаю PyQt6 и мне интересно узнать больше о возможностях QtWebEngine. Буду признателен, если вы порекомендуете какие-нибудь руководства или учебные пособия по изучению .

задан 17 дек 2023 в 17:31
29 показов

Изменение размера дочернего виджета при масштабировании колесом родительского

у меня есть родительский виджет(QWidget). Я рисую на нем сетку с помощью метода paintEvent. Этот виджет имеет дочерний виджет(QWidget). Дочерний виджет может перемещаться только по ячейкам сетки .

задан 8 дек 2023 в 10:07
17 показов

Как я могу получить заголовки ответа responseHeaders() из PyQt6.QtWebEngineCore.QWebEngineLoadingInfo()

Вот пример кода: from PyQt6.QtWidgets import QApplication from PyQt6.QtWebEngineWidgets import QWebEngineView from PyQt6.QtWebEngineCore import QWebEngineLoadingInfo from PyQt6.QtCore import QUrl .

задан 6 дек 2023 в 20:14

Проблема при запуске PyQt6

Ошибка: from PyQt6.QtWidgets import QApplication, QWidget ImportError: DLL load failed while importing QtCore: The specified procedure could not be found. у меня винда 11, как решить эту проблему? .

задан 4 дек 2023 в 6:52
60 показов

Как связать кнопку с полем ввода в PyQt?

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

задан 30 ноя 2023 в 11:15
45 показов

Сортировка столбцов QTableWidget PyQt6

В оригинальном файле с интерфейсом есть QTableWidget который в котором рисуется таблица куда выводятся данные из базы: self.table_widget = QtWidgets.QTableWidget(parent=self.frame_7) sizePolicy = .

задан 19 ноя 2023 в 10:05
48 показов

Как разрешить изменение размеров окна в PyQt6

Я делаю приложение на PyQt6 и для запрета изменения размеров окна я использую метод setFixedSize, но сейчас мне надо разрешить это самое изменение. Как это сделать? main.py class MainWindow(.

задан 8 ноя 2023 в 15:55
35 показов

Помогите пожалуйста с кодом на Python, нужно чтобы при нажатии на next_Button данные отправлялись на сервер [закрыт]

from PyQt6 import QtCore, QtGui, QtWidgets from PyQt6 import QtCore, QtGui, QtWidgets from pymongo import MongoClient from bson.objectid import ObjectId import datetime class Ui_Registration(object): .

задан 5 ноя 2023 в 9:10
59 показов

При связи сигнала со слотом в PyQt6 генерируется ошибка

Я переписываю программу с Python2, PyQt4 на Python3, PyQt6. Столкнулся с проблемой переформатирования старых сигналов на их новый формат вызова в PyQt6. Старый сигнал выглядел так: self.connect(.

задан 31 окт 2023 в 14:32
70 показов

Как правильно показать в основном окне результат счетчика цикла, который выполняется в дополнительном потоке?

Прошу помощи. Есть класс Example(), в котором выполняется определенная работа с файлами на ПК в цикле продолжительное время. Есть класс окна MainWindow() PyQt в другом модуле. В окне я выбираю пути, .

задан 29 окт 2023 в 20:14

Не работает setGeometry для QDockWidget при размещении его в QMainWindow PyQt6

Надо установить положение и размер для QDockWidget, который находиться в QMainWindow. В QMainWindow, 7 QDockWidget. Создание QDock: self.dock = QDockWidget(‘Фильтр’) self.dock.setAllowedAreas(Qt.

задан 27 окт 2023 в 9:56
15 30 50 на странице

    Важное на Мете

Связанные метки

Подписаться на ленту

Лента новых вопросов с меткой [pyqt6]

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *