PyQt - Краткое руководство
PyQt - это набор инструментов для виджетов с графическим интерфейсом. Это интерфейс Python дляQt, одна из самых мощных и популярных кроссплатформенных графических библиотек. PyQt был разработан RiverBank Computing Ltd. Последнюю версию PyQt можно загрузить с ее официального сайта - riverbankcomputing.com
PyQt API - это набор модулей, содержащий большое количество классов и функций. В то время какQtCore модуль содержит функции без графического интерфейса для работы с файлом, каталогом и т. д., QtGuiмодуль содержит все графические элементы управления. Кроме того, есть модули для работы с XML.(QtXml), SVG (QtSvg), и SQL (QtSql), и т.д.
Поддерживающие среды
PyQt совместим со всеми популярными операционными системами, включая Windows, Linux и Mac OS. Он имеет двойную лицензию, доступен как под GPL, так и под коммерческой лицензией.
Windows
Вы можете загрузить и установить соответствующий установщик по указанной выше ссылке для загрузки, соответствующей версии Python (2.7 или 3.4) и архитектуре оборудования (32-разрядная или 64-разрядная). Обратите внимание, что доступны две версии PyQt, а именно:PyQt 4.8 и PyQt 5.5.
Хотя PyQt4 доступен как для Python 2, так и для Python 3, PyQt5 можно использовать только вместе с Python 3. *.
PyQt4 Windows Binaries
PyQt4-4.11.4-gpl-Py3.4-Qt4.8.7-x64.exe | Установщик для 64-разрядной версии Windows |
PyQt4-4.11.4-gpl-Py3.4-Qt4.8.7-x32.exe | Установщик для 32-разрядной версии Windows |
PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x64.exe | Установщик для 64-разрядной версии Windows |
PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x32.exe | Установщик для 32-разрядной версии Windows |
PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x64.exe | Установщик для 64-разрядной версии Windows |
PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe | Установщик для 32-разрядной версии Windows |
PyQt5 Windows Binaries
PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x64.exe | Установщик для 64-разрядной версии Windows |
PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x32.exe | Установщик для 32-разрядной версии Windows |
Linux
Для Ubuntu или любого другого дистрибутива debian Linux используйте следующую команду для установки PyQt -
sudo apt-get install python-qt4
or
sudo apt-get install pyqt5-dev-tools
Вы также можете выполнить сборку из исходного кода, доступного на странице «загрузки».
PyQt-x11-gpl-4.11.4.tar.gz | Linux, исходный код UNIX для PyQt4 |
PyQt-gpl-5.5.tar.gz | Исходники Linux, UNIX, MacOS / X для PyQt5 |
Mac OS
Проект PyQtX (http://sourceforge.net/projects/pyqtx/) размещает двоичные файлы PyQt для Mac. Используйте установщик Homebrew в соответствии со следующей командой -
brew install pyqt
Создание простого приложения с графическим интерфейсом пользователя с использованием PyQt включает следующие шаги:
Импортируйте модуль QtGui.
Создайте объект приложения.
Объект QWidget создает окно верхнего уровня. Добавьте в него объект QLabel.
Установите заголовок метки как «привет, мир».
Определите размер и положение окна методом setGeometry ().
Войдите в главный цикл приложения, app.exec_() метод.
import sys
from PyQt4 import QtGui
def window():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
b = QtGui.QLabel(w)
b.setText("Hello World!")
w.setGeometry(100,100,200,50)
b.move(50,20)
w.setWindowTitle(“PyQt”)
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
Приведенный выше код дает следующий вывод -
PyQt APIпредставляет собой большой набор классов и методов. Эти классы определены более чем в 20 модулях. Ниже приведены некоторые из часто используемых модулей -
Sr.No. | Модули и описание |
---|---|
1 | QtCore Основные классы без графического интерфейса, используемые другими модулями |
2 | QtGui Компоненты графического пользовательского интерфейса |
3 | QtMultimedia Занятия по низкоуровневому мультимедийному программированию |
4 | QtNetwork Классы сетевого программирования |
5 | QtOpenGL Классы поддержки OpenGL |
6 | QtScript Классы для оценки скриптов Qt |
7 | QtSql Классы для интеграции базы данных с использованием SQL |
8 | QtSvg Классы для отображения содержимого файлов SVG |
9 | QtWebKit Классы для рендеринга и редактирования HTML |
10 | QtXml Классы для обработки XML |
11 | QtAssistant Поддержка онлайн-справки |
12 | QtDesigner Классы для расширения Qt Designer |
PyQt API содержит более 400 классов. ВQObjectкласс находится на вершине иерархии классов. Это базовый класс всех объектов Qt. Дополнительно,QPaintDevice class - это базовый класс для всех объектов, которые можно раскрашивать.
QApplicationкласс управляет основными настройками и потоком управления приложения с графическим интерфейсом. Он содержит основной цикл событий, внутри которого обрабатываются и отправляются события, генерируемые элементами окна и другими источниками. Он также обрабатывает общесистемные и общесистемные настройки.
QWidget Класс, производный от классов QObject и QPaintDevice, является базовым классом для всех объектов пользовательского интерфейса. QDialog и QFrameклассы также являются производными от класса QWidget. У них есть своя собственная система подклассов.
На следующих диаграммах показаны некоторые важные классы в их иерархии.
Вот избранный список часто используемых виджетов -
Ниже приведены наиболее часто используемые виджеты.
Sr.No. | Виджеты и описание |
---|---|
1 | QLabel Используется для отображения текста или изображения |
2 | QLineEdit Позволяет пользователю вводить одну строку текста |
3 | QTextEdit Позволяет пользователю вводить многострочный текст |
4 | QPushButton Командная кнопка для вызова действия |
5 | QRadioButton Позволяет выбрать один из нескольких вариантов |
6 | QCheckBox Позволяет выбрать более одного варианта |
7 | QSpinBox Позволяет увеличивать / уменьшать целочисленное значение |
8 | QScrollBar Позволяет получить доступ к содержимому виджета за пределами апертуры дисплея |
9 | QSlider Позволяет изменять граничное значение линейно. |
10 | QComboBox Предоставляет раскрывающийся список элементов для выбора |
11 | QMenuBar Горизонтальная полоса с объектами QMenu |
12 | QStatusBar Обычно внизу QMainWindow предоставляет информацию о состоянии. |
13 | QToolBar Обычно вверху QMainWindow или с плавающей точкой. Содержит кнопки действий |
14 | QListView Предоставляет выбираемый список элементов в ListMode или IconMode |
15 | QPixmap Внеэкранное представление изображения для отображения на объекте QLabel или QPushButton |
16 | QDialog Модальное или немодальное окно, которое может возвращать информацию в родительское окно |
Окно верхнего уровня типичного приложения на основе графического интерфейса пользователя создается QMainWindowобъект виджета. Некоторые виджеты, перечисленные выше, занимают назначенное место в этом главном окне, а другие размещаются в центральной области виджетов с помощью различных менеджеров компоновки.
На следующей диаграмме показана структура QMainWindow -
Установщик PyQt поставляется с инструментом построения графического интерфейса пользователя, который называется Qt Designer. Используя простой интерфейс перетаскивания, можно быстро создать графический интерфейс без написания кода. Однако это не IDE, такая как Visual Studio. Следовательно, Qt Designer не имеет возможности для отладки и сборки приложения.
Создание графического интерфейса пользователя с помощью Qt Designer начинается с выбора окна верхнего уровня для приложения.
Затем вы можете перетащить необходимые виджеты из поля виджетов на левой панели. Вы также можете присвоить значение свойствам виджета, размещенного на форме.
Созданная форма сохраняется как demo.ui. Этот файл пользовательского интерфейса содержит XML-представление виджетов и их свойств в дизайне. Этот дизайн переведен в эквивалент Python с помощью утилиты командной строки pyuic4. Эта утилита является оболочкой для модуля uic. Использование pyuic4 выглядит следующим образом -
pyuic4 –x demo.ui –o demo.py
В приведенной выше команде ключ -x добавляет небольшой объем дополнительного кода к сгенерированному XML, так что он становится самоисполняемым автономным приложением.
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
Результирующий скрипт python выполняется, чтобы показать следующее диалоговое окно -
Пользователь может вводить данные в поля ввода, но нажатие кнопки «Добавить» не вызовет никаких действий, поскольку не связано с какой-либо функцией. Реакция на пользовательский ответ называетсяevent handling.
В отличие от приложения в режиме консоли, которое выполняется последовательно, приложение на основе графического интерфейса пользователя управляется событиями. Функции или методы выполняются в ответ на действия пользователя, такие как нажатие кнопки, выбор элемента из коллекции или щелчок мышью и т. Д., Называемыеevents.
Виджеты, используемые для создания интерфейса GUI, выступают в качестве источника таких событий. Каждый виджет PyQt, производный от класса QObject, предназначен для выдачи 'signal'в ответ на одно или несколько событий. Сам по себе сигнал не выполняет никаких действий. Вместо этого он «подключен» кslot'. Слот может быть любымcallable Python function.
В PyQt связь между сигналом и слотом может быть достигнута по-разному. Ниже приведены наиболее часто используемые методы -
QtCore.QObject.connect(widget, QtCore.SIGNAL(‘signalname’), slot_function)
Более удобный способ вызвать slot_function, когда виджет испускает сигнал, выглядит следующим образом:
widget.signal.connect(slot_function)
Предположим, если функция должна вызываться при нажатии кнопки. Здесь сигнал clicked должен быть связан с вызываемой функцией. Это может быть достигнуто любым из следующих двух методов:
QtCore.QObject.connect(button, QtCore.SIGNAL(“clicked()”), slot_function)
или же
button.clicked.connect(slot_function)
пример
В следующем примере два объекта QPushButton (b1 и b2) добавляются в окно QDialog. Мы хотим вызывать функции b1_clicked () и b2_clicked () при нажатии b1 и b2 соответственно.
При щелчке по b1 сигнал clicked () подключается к функции b1_clicked ()
b1.clicked.connect(b1_clicked())
При щелчке по b2 сигнал clicked () подключается к функции b2_clicked ()
QObject.connect(b2, SIGNAL("clicked()"), b2_clicked)
пример
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def window():
app = QApplication(sys.argv)
win = QDialog()
b1 = QPushButton(win)
b1.setText("Button1")
b1.move(50,20)
b1.clicked.connect(b1_clicked)
b2 = QPushButton(win)
b2.setText("Button2")
b2.move(50,50)
QObject.connect(b2,SIGNAL("clicked()"),b2_clicked)
win.setGeometry(100,100,200,100)
win.setWindowTitle("PyQt")
win.show()
sys.exit(app.exec_())
def b1_clicked():
print "Button 1 clicked"
def b2_clicked():
print "Button 2 clicked"
if __name__ == '__main__':
window()
Приведенный выше код дает следующий вывод -
Вывод
Button 1 clicked
Button 2 clicked
Виджет с графическим интерфейсом пользователя можно разместить внутри окна контейнера, указав его абсолютные координаты в пикселях. Координаты указаны относительно размеров окна, определенного методом setGeometry ().
setGeometry () синтаксис
QWidget.setGeometry(xpos, ypos, width, height)
В следующем фрагменте кода окно верхнего уровня размером 300 на 200 пикселей отображается в позиции (10, 10) на мониторе.
import sys
from PyQt4 import QtGui
def window():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
b = QtGui.QPushButton(w)
b.setText("Hello World!")
b.move(50,20)
w.setGeometry(10,10,300,200)
w.setWindowTitle(“PyQt”)
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
А PushButton виджет добавляется в окно и размещается на 50 пикселей вправо и на 20 пикселей ниже верхнего левого угла окна.
Этот Absolute Positioning, однако, не подходит по следующим причинам -
Положение виджета не меняется даже при изменении размера окна.
Внешний вид может быть неодинаковым на разных устройствах отображения с разным разрешением.
Изменить макет сложно, так как может потребоваться переработка всей формы.
PyQt API предоставляет классы макета для более элегантного управления позиционированием виджетов внутри контейнера. Преимущества менеджеров компоновки перед абсолютным позиционированием:
Размер виджетов внутри окна изменяется автоматически.
Обеспечивает единообразный внешний вид на устройствах отображения с разным разрешением.
Динамическое добавление или удаление виджета возможно без изменения дизайна.
Вот список классов, которые мы будем обсуждать один за другим в этой главе.
Sr.No. | Классы и описание |
---|---|
1 | QBoxLayout Класс QBoxLayout выстраивает виджеты вертикально или горизонтально. Его производными классами являются QVBoxLayout (для размещения виджетов по вертикали) и QHBoxLayout (для размещения виджетов по горизонтали). |
2 | QGridLayout Объект класса GridLayout представляет собой сетку ячеек, расположенных в строках и столбцах. Класс содержит метод addWidget (). Любой виджет можно добавить, указав количество строк и столбцов ячейки. |
3 | QFormLayout QFormLayout - удобный способ создать форму с двумя столбцами, где каждая строка состоит из поля ввода, связанного с меткой. Как правило, левый столбец содержит метку, а правый столбец содержит поле ввода. |
Вот список виджетов, которые мы будем обсуждать один за другим в этой главе.
Старший Нет | Виджеты и описание |
---|---|
1 | QLabel Объект QLabel действует как заполнитель для отображения нередактируемого текста или изображения или фильма в анимированном формате GIF. Его также можно использовать как мнемонический ключ для других виджетов. |
2 | QLineEdit Объект QLineEdit - это наиболее часто используемое поле ввода. Он предоставляет поле, в которое можно ввести одну строку текста. Для ввода многострочного текста необходим объект QTextEdit. |
3 | QPushButton В PyQt API объект класса QPushButton представляет собой кнопку, при нажатии которой можно запрограммировать вызов определенной функции. |
4 | QRadioButton Объект класса QRadioButton представляет собой выбираемую кнопку с текстовой меткой. Пользователь может выбрать один из множества вариантов, представленных в форме. Этот класс является производным от класса QAbstractButton. |
5 | QCheckBox Прямоугольное поле перед текстовой меткой появляется, когда объект QCheckBox добавляется в родительское окно. Как и QRadioButton, это кнопка, которую можно выбрать. |
6 | QComboBox Объект QComboBox представляет собой раскрывающийся список элементов для выбора. На форме требуется минимум места на экране, необходимый для отображения только текущего выбранного элемента. |
7 | QSpinBox Объект QSpinBox представляет пользователю текстовое поле, в котором отображается целое число с кнопкой вверх / вниз справа. |
8 | Виджет и сигнал QSlider Объект класса QSlider представляет пользователю канавку, по которой можно перемещать ручку. Это классический виджет для управления ограниченным значением. |
9 | QMenuBar, QMenu и QAction Горизонтальная панель QMenuBar чуть ниже строки заголовка объекта QMainWindow зарезервирована для отображения объектов QMenu. |
10 | QToolBar Виджет QToolBar - это подвижная панель, состоящая из текстовых кнопок, кнопок со значками или других виджетов. |
11 | QInputDialog Это предварительно настроенный диалог с текстовым полем и двумя кнопками, ОК и Отмена. Родительское окно собирает ввод в текстовое поле после того, как пользователь нажимает кнопку Ok или Enter. |
12 | QFontDialog Другой часто используемый диалог, виджет выбора шрифта, визуально представляет собой класс QDialog. Результатом этого диалога является объект Qfont, который может использоваться родительским окном. |
13 | QFileDialog Этот виджет представляет собой диалог выбора файлов. Он позволяет пользователю перемещаться по файловой системе и выбирать файл для открытия или сохранения. Диалог вызывается либо через статические функции, либо путем вызова функции exec_ () для объекта диалога. |
14 | QTab Если в форме слишком много полей для одновременного отображения, их можно расположить на разных страницах, помещенных под каждой вкладкой виджета с вкладками. QTabWidget предоставляет панель вкладок и область страницы. |
15 | QStacked Функционирование QStackedWidget аналогично QTabWidget. Это также помогает эффективно использовать клиентскую область окна. |
16 | QSplitter Если в форме слишком много полей для одновременного отображения, их можно расположить на разных страницах, помещенных под каждой вкладкой виджета с вкладками. QTabWidget предоставляет панель вкладок и область страницы. |
17 | QDock Закрепляемое окно - это подокно, которое может оставаться в плавающем состоянии или может быть прикреплено к главному окну в указанной позиции. Объект главного окна класса QMainWindow имеет область, зарезервированную для закрепляемых окон. |
18 | QStatusBar Объект QMainWindow резервирует горизонтальную полосу внизу как строку состояния. Он используется для отображения постоянной или контекстной информации о состоянии. |
19 | QList Класс QListWidget - это интерфейс на основе элементов для добавления или удаления элементов из списка. Каждый элемент в списке - это объект QListWidgetItem. ListWidget может быть настроен на выбор нескольких элементов. |
20 | QScrollBar Элемент управления с полосой прокрутки позволяет пользователю получать доступ к частям документа, находящимся за пределами области просмотра. Он обеспечивает визуальный индикатор текущей позиции. |
21 год | QCalendar Виджет QCalendar - это полезный элемент управления для выбора даты. Он обеспечивает просмотр по месяцам. Пользователь может выбрать дату с помощью мыши или клавиатуры, по умолчанию текущая дата. |
А QDialogвиджет представляет собой окно верхнего уровня, в основном используемое для сбора ответа от пользователя. Его можно настроить какModal (где он блокирует свое родительское окно) или Modeless (диалоговое окно можно пропустить).
PyQt API имеет ряд предварительно настроенных виджетов Dialog, таких как InputDialog, FileDialog, FontDialog и т. Д.
пример
В следующем примере атрибут WindowModality диалогового окна определяет, является ли оно модальным или немодальным. Любую кнопку в диалоговом окне можно установить по умолчанию. Диалог отклоняется методом QDialog.reject (), когда пользователь нажимает клавишу Escape.
PushButton в окне QWidget верхнего уровня при нажатии создает диалоговое окно. В строке заголовка диалогового окна отсутствуют элементы управления свертыванием и разворачиванием.
Пользователь не может перевести это диалоговое окно в фоновый режим, поскольку его WindowModality имеет значение ApplicationModal.
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
def window():
app = QApplication(sys.argv)
w = QWidget()
b = QPushButton(w)
b.setText("Hello World!")
b.move(50,50)
b.clicked.connect(showdialog)
w.setWindowTitle("PyQt Dialog demo")
w.show()
sys.exit(app.exec_())
def showdialog():
d = QDialog()
b1 = QPushButton("ok",d)
b1.move(50,50)
d.setWindowTitle("Dialog")
d.setWindowModality(Qt.ApplicationModal)
d.exec_()
if __name__ == '__main__':
window()
Приведенный выше код дает следующий вывод -
QMessageBoxэто обычно используемый модальный диалог для отображения некоторого информационного сообщения и, при желании, с просьбой пользователя ответить, щелкнув любую из стандартных кнопок на нем. Каждая стандартная кнопка имеет предопределенный заголовок, роль и возвращает предопределенное шестнадцатеричное число.
Важные методы и перечисления, связанные с классом QMessageBox, приведены в следующей таблице -
Sr.No. | Методы и описание |
---|---|
1 | setIcon() Отображает предопределенный значок, соответствующий серьезности сообщения
|
2 | setText() Задает отображаемый текст основного сообщения |
3 | setInformativeText() Отображает дополнительную информацию |
4 | setDetailText() В диалоговом окне отображается кнопка «Подробности». Этот текст появляется при нажатии на него |
5 | setTitle() Отображает настраиваемый заголовок диалога |
6 | setStandardButtons() Список стандартных кнопок для отображения. Каждая кнопка связана с QMessageBox.Ok 0x00000400 QMessageBox.Open 0x00002000 QMessageBox.Save 0x00000800 QMessageBox.Cancel 0x00400000 QMessageBox.Close 0x00200000 QMessageBox.Yes 0x00004000 QMessageBox.No 0x00010000 QMessageBox.Abort 0x00040000 QMessageBox.Retry 0x00080000 QMessageBox.Ignore 0x00100000 |
7 | setDefaultButton() Устанавливает кнопку по умолчанию. Он издает сигнал щелчка, если нажата Enter |
8 | setEscapeButton() Устанавливает кнопку, которая будет считаться нажатой, если нажата клавиша выхода |
пример
В следующем примере сигнал нажатия кнопки в окне верхнего уровня, подключенная функция отображает диалоговое окно окна сообщений.
msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText("This is a message box")
msg.setInformativeText("This is additional information")
msg.setWindowTitle("MessageBox demo")
msg.setDetailedText("The details are as follows:")
Функция setStandardButton () отображает нужные кнопки.
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
Сигнал buttonClicked () связан с функцией слота, которая определяет заголовок источника сигнала.
msg.buttonClicked.connect(msgbtn)
Полный код для примера выглядит следующим образом:
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
def window():
app = QApplication(sys.argv)
w = QWidget()
b = QPushButton(w)
b.setText("Show message!")
b.move(50,50)
b.clicked.connect(showdialog)
w.setWindowTitle("PyQt Dialog demo")
w.show()
sys.exit(app.exec_())
def showdialog():
msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText("This is a message box")
msg.setInformativeText("This is additional information")
msg.setWindowTitle("MessageBox demo")
msg.setDetailedText("The details are as follows:")
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msg.buttonClicked.connect(msgbtn)
retval = msg.exec_()
print "value of pressed message box button:", retval
def msgbtn(i):
print "Button pressed is:",i.text()
if __name__ == '__main__':
window()
Приведенный выше код дает следующий вывод -
Типичное приложение с графическим интерфейсом может иметь несколько окон. Виджеты с вкладками и стеком позволяют активировать одно такое окно за раз. Однако во многих случаях этот подход может оказаться бесполезным, поскольку вид других окон скрыт.
Один из способов одновременного отображения нескольких окон - создать их как независимые окна. Это называется SDI (единый интерфейс документа). Для этого требуется больше ресурсов памяти, поскольку каждое окно может иметь свою собственную систему меню, панель инструментов и т. Д.
Приложения MDI (Multiple Document Interface) потребляют меньше ресурсов памяти. Вспомогательные окна располагаются внутри основного контейнера относительно друг друга. Виджет контейнера называетсяQMdiArea.
Виджет QMdiArea обычно занимает центральный виджет объекта QMainWondow. Дочерние окна в этой области являются экземплярами класса QMdiSubWindow. Можно установить любой QWidget как внутренний виджет объекта subWindow. Подокна в области MDI могут быть расположены каскадом или мозаикой.
В следующей таблице перечислены важные методы класса QMdiArea и класса QMdiSubWindow.
Sr.No. | Методы и описание |
---|---|
1 | addSubWindow() Добавляет виджет как новое подокно в область MDI |
2 | removeSubWindow() Удаляет виджет, который является внутренним виджетом подокна |
3 | setActiveSubWindow() Активирует подокно |
4 | cascadeSubWindows() Располагает подокна в MDiArea каскадно |
5 | tileSubWindows() Располагает подокна в MDiArea мозаичным способом |
6 | closeActiveSubWindow() Закрывает активное подокно |
7 | subWindowList() Возвращает список подокон в области MDI. |
8 | setWidget() Устанавливает QWidget как внутренний виджет экземпляра QMdiSubwindow |
Объект QMdiArea испускает сигнал subWindowActivated (), тогда как сигнал windowStateChanged () испускает объект QMdisubWindow.
пример
В следующем примере окно верхнего уровня, состоящее из QMainWindow, имеет меню и MdiArea.
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
Сигнал Triggered () меню связан с функцией windowaction ().
file.triggered[QAction].connect(self.windowaction)
Новое действие меню добавляет подокно в область MDI с заголовком, к которому добавляется порядковый номер.
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
Каскадные и мозаичные кнопки меню упорядочивают отображаемые в данный момент подокна в каскадном и мозаичном порядке соответственно.
Полный код выглядит следующим образом -
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MainWindow(QMainWindow):
count = 0
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
file.triggered[QAction].connect(self.windowaction)
self.setWindowTitle("MDI demo")
def windowaction(self, q):
print "triggered"
if q.text() == "New":
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
if q.text() == "cascade":
self.mdi.cascadeSubWindows()
if q.text() == "Tiled":
self.mdi.tileSubWindows()
def main():
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Приведенный выше код дает следующий вывод -
Предоставление drag and dropочень интуитивно понятен для пользователя. Он присутствует во многих настольных приложениях, где пользователь может копировать или перемещать объекты из одного окна в другое.
Передача данных перетаскиванием на основе MIME основана на классе QDrag. QMimeDataобъекты связывают данные с их соответствующим типом MIME. Он сохраняется в буфере обмена, а затем используется в процессе перетаскивания.
Следующие функции класса QMimeData позволяют удобно обнаруживать и использовать тип MIME.
Тестер | Геттер | Сеттер | Типы MIME |
---|---|---|---|
hasText () | текст() | setText () | текст / простой |
hasHtml () | html () | setHtml () | текст / html |
hasUrls () | URL-адреса () | setUrls () | текст / список URI |
hasImage () | imageData () | setImageData () | изображение / * |
hasColor () | colorData () | setColorData () | приложение / x-color |
Многие объекты QWidget поддерживают перетаскивание. Те, которые позволяют перетаскивать свои данные, имеют setDragEnabled (), для которого должно быть установлено значение true. С другой стороны, виджеты должны реагировать на события перетаскивания, чтобы сохранить перетаскиваемые в них данные.
DragEnterEvent предоставляет событие, которое отправляется в целевой виджет, когда в него входит действие перетаскивания.
DragMoveEvent используется, когда выполняется перетаскивание.
DragLeaveEvent генерируется, когда действие перетаскивания покидает виджет.
DropEvent, с другой стороны, происходит, когда сброс завершен. Предлагаемое мероприятие действие может быть принято или отклонено условно.
пример
В следующем коде DragEnterEvent проверяет, содержат ли данные MIME события текст. Если да, действие, предложенное событием, принимается, и текст добавляется как новый элемент в ComboBox.
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class combo(QComboBox):
def __init__(self, title, parent):
super(combo, self).__init__( parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, e):
print e
if e.mimeData().hasText():
e.accept()
else:
e.ignore()
def dropEvent(self, e):
self.addItem(e.mimeData().text())
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
lo = QFormLayout()
lo.addRow(QLabel("Type some text in textbox and drag it into combo box"))
edit = QLineEdit()
edit.setDragEnabled(True)
com = combo("Button", self)
lo.addRow(edit,com)
self.setLayout(lo)
self.setWindowTitle('Simple drag & drop')
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
if __name__ == '__main__':
main()
Приведенный выше код дает следующий вывод -
PyQt API содержит сложную систему классов для взаимодействия со многими базами данных на основе SQL. Его QSqlDatabase предоставляет доступ через объект Connection. Ниже приведен список доступных в настоящее время драйверов SQL -
Sr.No. | Тип и описание драйвера |
---|---|
1 | QDB2 IBM DB2 |
2 | QIBASE Драйвер Borland InterBase |
3 | QMYSQL Драйвер MySQL |
4 | QOCI Драйвер интерфейса вызова Oracle |
5 | QODBC Драйвер ODBC (включает Microsoft SQL Server) |
6 | QPSQL Драйвер PostgreSQL |
7 | QSQLITE SQLite версии 3 или выше |
8 | QSQLITE2 SQLite версии 2 |
пример
Соединение с базой данных SQLite устанавливается статическим методом -
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sports.db')
Другие методы класса QSqlDatabase следующие:
Sr.No. | Методы и описание |
---|---|
1 | setDatabaseName() Устанавливает имя базы данных, с которой ищется соединение |
2 | setHostName() Устанавливает имя хоста, на котором установлена база данных |
3 | setUserName() Задает имя пользователя для подключения |
4 | setPassword() Устанавливает пароль объекта подключения, если есть |
5 | commit() Фиксирует транзакции и возвращает истину в случае успеха |
6 | rollback() Откатывает транзакцию базы данных |
7 | close() Закрывает соединение |
Класс QSqlQuery имеет функциональные возможности для выполнения команд SQL и управления ими. Могут выполняться запросы SQL как DDL, так и DML. Самый важный метод в классе - exec_ (), который принимает в качестве аргумента строку, содержащую SQL-оператор, который нужно выполнить.
query = QtSql.QSqlQuery()
query.exec_("create table sportsmen(id int primary key,
" "firstname varchar(20), lastname varchar(20))")
Следующий сценарий создает базу данных SQLite sports.db с таблицей спортсменов, заполненной пятью записями.
from PyQt4 import QtSql, QtGui
def createDB():
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sports.db')
if not db.open():
QtGui.QMessageBox.critical(None, QtGui.qApp.tr("Cannot open database"),
QtGui.qApp.tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information "
"how to build it.\n\n" "Click Cancel to exit."),
QtGui.QMessageBox.Cancel)
return False
query = QtSql.QSqlQuery()
query.exec_("create table sportsmen(id int primary key, "
"firstname varchar(20), lastname varchar(20))")
query.exec_("insert into sportsmen values(101, 'Roger', 'Federer')")
query.exec_("insert into sportsmen values(102, 'Christiano', 'Ronaldo')")
query.exec_("insert into sportsmen values(103, 'Ussain', 'Bolt')")
query.exec_("insert into sportsmen values(104, 'Sachin', 'Tendulkar')")
query.exec_("insert into sportsmen values(105, 'Saina', 'Nehwal')")
return True
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
createDB()
Класс QSqlTableModel в PyQt - это интерфейс высокого уровня, который предоставляет редактируемую модель данных для чтения и записи записей в одной таблице. Эта модель используется для заполнения объекта QTableView. Он представляет пользователю прокручиваемый и редактируемый вид, который может быть помещен в любое окно верхнего уровня.
Объект QTableModel объявляется следующим образом -
model = QtSql.QSqlTableModel()
Его стратегия редактирования может быть установлена на любую из следующих:
QSqlTableModel.OnFieldChange | Все изменения вступят в силу немедленно |
QSqlTableModel.OnRowChange | Изменения будут применены, когда пользователь выберет другую строку |
QSqlTableModel.OnManualSubmit | Все изменения будут кэшироваться до тех пор, пока не будет вызван submitAll () или revertAll () |
пример
В следующем примере таблица спортсмена используется в качестве модели, а стратегия задана как -
model.setTable('sportsmen')
model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
model.select()
Класс QTableView является частью структуры Модель / Представление в PyQt. Объект QTableView создается следующим образом -
view = QtGui.QTableView()
view.setModel(model)
view.setWindowTitle(title)
return view
Этот объект QTableView и два виджета QPushButton добавляются в окно QDialog верхнего уровня. Сигнал Clicked () кнопки добавления связан с addrow (), который выполняет insertRow () для таблицы модели.
button.clicked.connect(addrow)
def addrow():
print model.rowCount()
ret = model.insertRows(model.rowCount(), 1)
print ret
Слот, связанный с кнопкой удаления, выполняет лямбда-функцию, которая удаляет строку, выбранную пользователем.
btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))
Полный код выглядит следующим образом -
import sys
from PyQt4 import QtCore, QtGui, QtSql
import sportsconnection
def initializeModel(model):
model.setTable('sportsmen')
model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
model.select()
model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
model.setHeaderData(1, QtCore.Qt.Horizontal, "First name")
model.setHeaderData(2, QtCore.Qt.Horizontal, "Last name")
def createView(title, model):
view = QtGui.QTableView()
view.setModel(model)
view.setWindowTitle(title)
return view
def addrow():
print model.rowCount()
ret = model.insertRows(model.rowCount(), 1)
print ret
def findrow(i):
delrow = i.row()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sports.db')
model = QtSql.QSqlTableModel()
delrow = -1
initializeModel(model)
view1 = createView("Table Model (View 1)", model)
view1.clicked.connect(findrow)
dlg = QtGui.QDialog()
layout = QtGui.QVBoxLayout()
layout.addWidget(view1)
button = QtGui.QPushButton("Add a row")
button.clicked.connect(addrow)
layout.addWidget(button)
btn1 = QtGui.QPushButton("del a row")
btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))
layout.addWidget(btn1)
dlg.setLayout(layout)
dlg.setWindowTitle("Database Demo")
dlg.show()
sys.exit(app.exec_())
Приведенный выше код дает следующий вывод -
Все QWidgetклассы в PyQt являются подклассами класса QPaintDevice. АQPaintDeviceпредставляет собой абстракцию двухмерного пространства, которое можно нарисовать с помощью QPainter. Размеры устройства рисования измеряются в пикселях, начиная с левого верхнего угла.
Класс QPainter выполняет низкоуровневую отрисовку виджетов и других раскрашиваемых устройств, таких как принтер. Обычно он используется в событии рисования виджета. ВQPaintEvent происходит всякий раз, когда обновляется внешний вид виджета.
Живописец активируется вызовом метода begin (), а метод end () деактивирует его. Между ними желаемый узор наносится подходящими методами, указанными в следующей таблице.
Sr.No. | Методы и описание |
---|---|
1 | begin() Начинает рисование на целевом устройстве |
2 | drawArc() Рисует дугу между начальным и конечным углом |
3 | drawEllipse() Рисует эллипс внутри прямоугольника |
4 | drawLine() Рисует линию с указанными координатами конечной точки |
5 | drawPixmap() Извлекает растровое изображение из файла изображения и отображает его в указанной позиции |
6 | drwaPolygon() Рисует многоугольник с использованием массива координат |
7 | drawRect() Рисует прямоугольник, начиная с верхней левой координаты, с заданной шириной и высотой. |
8 | drawText() Отображает текст в заданных координатах |
9 | fillRect() Заполняет прямоугольник параметром QColor |
10 | setBrush() Устанавливает стиль кисти для рисования |
11 | setPen() Устанавливает цвет, размер и стиль пера, который будет использоваться для рисования |
Предопределенные стили QColor
Qt.NoBrush | Нет рисунка кисти |
Qt.SolidPattern | Равномерный цвет |
Qt.Dense1Pattern | Чрезвычайно плотный рисунок кисти |
Qt.HorPattern | Горизонтальные линии |
Qt.VerPattern | Вертикальные линии |
Qt.CrossPattern | Пересечение горизонтальных и вертикальных линий |
Qt.BDiagPattern | Обратные диагональные линии |
Qt.FDiagPattern | Прямые диагональные линии |
Qt.DiagCrossPattern | Пересечение диагональных линий |
Предопределенные объекты QColor
Qt.white |
Qt.black |
Qt.red |
Qt.darkRed |
Qt.green |
Qt.darkGreen |
Qt.blue |
Qt.cyan |
Qt.magenta |
Qt.yellow |
Qt.darkYellow |
Qt.gray |
Пользовательский цвет можно выбрать, указав значения RGB, CMYK или HSV.
пример
В следующем примере реализуются некоторые из этих методов.
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.text = "hello world"
self.setGeometry(100,100, 400,300)
self.setWindowTitle('Draw Demo')
self.show()
def paintEvent(self, event):
qp = QPainter()
qp.begin(self)
qp.setPen(QColor(Qt.red))
qp.setFont(QFont('Arial', 20))
qp.drawText(10,50, "hello Pyth
on")
qp.setPen(QColor(Qt.blue))
qp.drawLine(10,100,100,100)
qp.drawRect(10,150,150,100)
qp.setPen(QColor(Qt.yellow))
qp.drawEllipse(100,50,100,50)
qp.drawPixmap(220,10,QPixmap("python.jpg"))
qp.fillRect(200,175,150,100,QBrush(Qt.SolidPattern))
qp.end()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Приведенный выше код дает следующий вывод -
В QClipboardКласс обеспечивает доступ к общесистемному буферу обмена, который предлагает простой механизм для копирования и вставки данных между приложениями. Его действие аналогично классу QDrag и использует аналогичные типы данных.
Класс QApplication имеет статический метод clipboard (), который возвращает ссылку на объект буфера обмена. Любой тип MimeData можно скопировать в буфер обмена или вставить из него.
Ниже приведены методы класса буфера обмена, которые обычно используются.
Sr.No. | Методы и описание |
---|---|
1 | clear() Очищает содержимое буфера обмена |
2 | setImage() Копирует QImage в буфер обмена |
3 | setMimeData() Устанавливает данные MIME в буфер обмена |
4 | setPixmap() Копирует объект Pixmap в буфер обмена |
5 | setText() Копирует QString в буфер обмена |
6 | text() Извлекает текст из буфера обмена |
Сигнал, связанный с объектом буфера обмена -
Sr.No. | Метод и описание |
---|---|
1 | dataChanged() При изменении данных буфера обмена |
пример
В следующем примере два объекта TextEdit и две кнопки добавляются в окно верхнего уровня.
Для начала создается объект буфера обмена. Метод Copy () объекта textedit копирует данные в системный буфер обмена. При нажатии кнопки «Вставить» данные из буфера обмена выбираются и вставляются в другой объект texttedit.
QPixmapкласс обеспечивает представление изображения за пределами экрана. Его можно использовать как объект QPaintDevice или загрузить в другой виджет, обычно в метку или кнопку.
Qt API имеет еще один аналогичный класс QImage, который оптимизирован для ввода-вывода и других манипуляций с пикселями. Pixmap, с другой стороны, оптимизирован для отображения на экране. Оба формата взаимно конвертируемы.
Типы файлов изображений, которые могут быть прочитаны в объекте QPixmap, следующие:
BMP | Растровое изображение Windows |
Гифка | Графический формат обмена (необязательно) |
JPG | Объединенная группа экспертов в области фотографии |
JPEG | Объединенная группа экспертов в области фотографии |
PNG | Переносимая сетевая графика |
PBM | Переносимое растровое изображение |
PGM | Портативный Graymap |
PPM | Portable Pixmap |
XBM | Растровое изображение X11 |
XPM | X11 Pixmap |
Следующие методы полезны при обработке объекта QPixmap:
Sr.No. | Методы и описание |
---|---|
1 | copy() Копирует данные растрового изображения из объекта QRect |
2 | fromImage() Преобразует объект QImage в QPixmap |
3 | grabWidget() Создает изображение из заданного виджета |
4 | grabWindow() Создать растровое изображение данных в окне |
5 | Load() Загружает файл изображения как растровое изображение |
6 | save() Сохраняет объект QPixmap как файл |
7 | toImage Преобразует QPixmap в QImage |
Чаще всего QPixmap используется для отображения изображения на ярлыке / кнопке.
пример
В следующем примере показано изображение, отображаемое в QLabel с помощью метода setPixmap (). Полный код выглядит следующим образом -
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def window():
app = QApplication(sys.argv)
win = QWidget()
l1 = QLabel()
l1.setPixmap(QPixmap("python.jpg"))
vbox = QVBoxLayout()
vbox.addWidget(l1)
win.setLayout(vbox)
win.setWindowTitle("QPixmap Demo")
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
Приведенный выше код дает следующий вывод -