Pyqt 简明教程

PyQt - Quick Guide

PyQt - Introduction

PyQt 是一个 GUI 小部件工具包。它是 Qt 的 Python 接口,这是功能最强大的跨平台 GUI 库之一。PyQt 由 RiverBank Computing Ltd. 开发。可以从其官方网站 riverbankcomputing.com 下载最新版本的 PyQt

PyQt API 是一套包含大量类和函数的模块。其中 QtCore 模块包含用于处理文件、目录等的非 GUI 功能, QtGui 模块包含所有图形控制。此外,还有用于处理 XML (QtXml) 、SVG (QtSvg) 和 SQL (QtSql) 等的模块。

Supporting Environments

PyQt 与所有流行的操作系统兼容,包括 Windows、Linux 和 Mac OS。它具有双重许可证,既可以获得 GPL 也可以通过商业许可证使用。

Windows

您可以从上面与 Python 版本(2.7 或 3.4)和硬件架构(32 位或 64 位)相对应的下载链接下载并安装合适的安装程序。请注意,有两种可用的 PyQt 版本,即 PyQt 4.8PyQt 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

Windows 64 bit installer

PyQt4-4.11.4-gpl-Py3.4-Qt4.8.7-x32.exe

Windows 32 bit installer

PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x64.exe

Windows 64 bit installer

PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x32.exe

Windows 32 bit installer

PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x64.exe

Windows 64 bit installer

PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe

Windows 32 bit installer

PyQt5 Windows Binaries

PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x64.exe

Windows 64 bit installer

PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x32.exe

Windows 32 bit installer

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

适用于 PyQt4 的 Linux、UNIX 源代码

PyQt-gpl-5.5.tar.gz

适用于 PyQt5 的 Linux、UNIX、MacOS/X 源代码

Mac OS

PyQtX 项目 ( http://sourceforge.net/projects/pyqtx/ ) 托管用于 Mac 的 PyQt 二进制文件。使用 Homebrew 安装程序,按以下命令执行操作 −

brew install pyqt

PyQt - Hello World

使用 PyQt 创建简单的 GUI 应用程序涉及以下步骤 −

  1. Import QtGui module.

  2. Create an application object.

  3. QWidget 对象创建顶层窗口。在其中添加 QLabel 对象。

  4. 将标签的标题设置为“hello world”。

  5. 通过 setGeometry() 方法定义窗口的大小和位置。

  6. 通过 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()

上述代码生成以下输出 -

hello world

PyQt - Major Classes

PyQt API 是大量类和方法的集合。这些类在 20 多个模块中定义。以下是一些常用模块 −

Sr.No.

Modules & Description

1

其他模块使用的 QtCore Core 非 GUI 类

2

QtGui Graphical user interface components

3

用于低级多媒体编程的 QtMultimedia

4

QtNetwork Classes for network programming

5

QtOpenGL OpenGL support classes

6

用于评估 Qt 脚本的 QtScript

7

用于使用 SQL 进行数据库集成的 QtSql

8

用于显示 SVG 文件内容的 QtSvg

9

用于渲染和编辑 HTML 的 QtWebKit

10

QtXml Classes for handling XML

11

QtAssistant Support for online help

12

用于扩展 Qt Designer 的 QtDesigner

PyQt API 包含 400 多个类。 QObject 类位于类层次结构的顶部。它是所有 Qt 对象的基类。此外, QPaintDevice 类是所有可绘制对象的基类。

QApplication 类管理 GUI 应用程序的主设置和控制流。它包含主事件循环,在该循环中处理和分派由窗口元素和其他源生成的事件。它还处理系统范围和应用程序范围的设置。

QWidget 类派生自 QObject 和 QPaintDevice 类,是所有用户界面对象的基类。 QDialogQFrame 类也派生自 QWidget 类。它们有自己的子类系统。

以下图表描绘了它们在层次结构中的某些重要类。

hierarchy
qwidget
qdialog
qiodevice
qpaintdevice

以下是常用的部件精简列表 −

以下是常用的部件。

Sr.No.

Widgets & Description

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 可以向父窗口返回信息的模态或无模态窗口

典型的基于 GUI 的应用程序的顶级窗口由 QMainWindow 小部件对象创建。上面列出的一些小部件在这个主窗口中占据各自指定的位置,而其他一些小部件则使用各种布局管理器放置在中央小部件区域中。

下图显示了 QMainWindow 框架 -

qmainwindow

PyQt - Using Qt Designer

PyQt 安装程序附带了一个名为 Qt Designer 的 GUI 构建工具。利用其简单的拖放界面,可以快速构建 GUI 界面而无需编写代码。然而,它不是像 Visual Studio 这样的 IDE。因此,Qt Designer 没有调试和构建应用程序的功能。

使用 Qt Designer 创建 GUI 界面始于为应用程序选择一个顶级窗口。

qt designer1

然后,您可以从左侧窗格中的小部件框中拖放所需の小部件。您还可以将值分配给布置在窗体上的小部件的属性。

qt designer2

设计好的窗体将另存为 demo.ui。此 ui 文件包含设计中对应小部件及其属性的 XML 表示。使用 pyuic4 命令行实用程序将此设计转换为 Python 等效项。此实用程序是 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 脚本以显示以下对话框 −

dialog box

用户可以在输入字段中输入数据,但单击“添加”按钮不会生成任何操作,因为它不与任何函数关联。对用户生成的响应作出反应被称为 event handling

PyQt - Signals & Slots

与按顺序执行的控制台模式应用程序不同,基于 GUI 的应用程序是事件驱动的。函数或方法会执行响应用户的操作,例如单击按钮、从集合中选择一个项目,或鼠标单击等,称为 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)

Example

在以下示例中,两个 QPushButton 对象(b1 和 b2)添加到 QDialog 窗口中。我们希望分别在单击 b1 和 b2 时调用函数 b1_clicked() 和 b2_clicked()。

当单击 b1 时,clicked() 信号连接到 b1_clicked() 函数

b1.clicked.connect(b1_clicked())

当单击 b2 时,clicked() 信号连接到 b2_clicked() 函数

QObject.connect(b2, SIGNAL("clicked()"), b2_clicked)

Example

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()

上述代码生成以下输出 -

signals and slots output

Output

Button 1 clicked
Button 2 clicked

PyQt - Layout Management

可以通过指定 GUI 小组件绝对坐标来将其放置在容器窗口中,坐标以像素为单位进行测量。坐标相对于 setGeometry() 方法定义的窗口维度。

setGeometry() syntax

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 不合适,原因如下 -

  1. 即使调整了窗口的大小,小组件的位置也不会改变。

  2. 在具有不同分辨率的不同显示设备上,外观可能不统一。

  3. 布局中的修改比较困难,因为它可能需要重新设计整个表单。

original resized window

PyQt API 提供布局类,可以更优雅地管理容器内小组件的位置。相对于绝对定位,布局管理器的优点是 -

  1. 窗口中的小组件自动调整大小。

  2. 确保在不同分辨率的显示设备上一致的外观。

  3. 添加或删除小组件的动态性无需重新设计。

以下是我们将在本章中依次讨论的类列表。

Sr.No.

Classes & Description

1

QBoxLayout QBoxLayout 类可垂直或水平排列小组件。它的派生类是 QVBoxLayout(用于垂直排列小组件)和 QHBoxLayout(用于水平排列小组件)。

2

QGridLayout A GridLayout 类对象呈现一个按行和列排列的网格单元格。该类包含 addWidget() 方法。可以通过指定单元格的行数和列数来添加任何小组件。

3

QFormLayout QFormLayout 是创建两列表单的便捷方式,其中每行都包含一个与标签相关联的输入字段。根据惯例,左列包含标签,右列包含输入字段。

PyQt - Basic Widgets

以下是我们将在本章中依次讨论的小组件列表。

Sr.No

Widgets & Description

1

QLabel A QLabel 对象用作显示不可编辑文本或图像、或动画 GIF 视频的占位符。它还可以用作其他小组件的助记键。

2

QLineEdit QLineEdit 对象是使用最广泛的输入字段。它提供了一个可以输入一行文本的框。为了输入多行文本,需要 QTextEdit 对象。

3

QPushButton 在 PyQt API 中,QPushButton 类对象呈现一个按钮,单击时可对其进行编程以调用某个函数。

4

QRadioButton A QRadioButton 类对象呈现一个带有文本标签的可选择按钮。用户可以选择表单上显示的众多选项之一。该类派生自 QAbstractButton 类。

5

QCheckBox 当将 QCheckBox 对象添加到父窗口时,会在文本标签前出现一个矩形框。就像 QRadioButton,它也是一个可选择按钮。

6

QComboBox A QComboBox 对象呈现一个可以从中进行选择的项目下拉列表。它在表单上占用最小的屏幕空间,仅显示当前选定的项目。

7

QSpinBox A QSpinBox 对象为用户提供一个文本框,其中显示带有向上/向下按钮的整数。

8

QSlider Widget & Signal QSlider 类对象向用户呈现一条槽,手柄可以在其上移动。这是一个经典的小部件,可控制有界值。

9

QMenuBar, QMenu & QAction QMainWindow 对象标题栏正下方的一条水平 QMenuBar 专门用于显示 QMenu 对象。

10

QToolBar QToolBar 小部件是一个可移动的面板,由文本按钮、带图标的按钮或其他小部件组成。

11

QInputDialog 这是一个预配置对话框,其中包含一个文本字段和两个按钮“确定”和“取消”。在用户单击“确定”按钮或按 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 小部件是一个有用的日期选择器控件。它提供基于月份的视图。用户可以使用鼠标或键盘选择日期,默认日期为今天的日期。

PyQt - QDialog Class

QDialog 小部件提供顶层窗口,主要用于收集用户的响应。可以将其配置为 Modal (它会阻止其父窗口)或 Modeless (可以绕过该对话框窗口)。

PyQt API 具有许多预配置的 Dialog 小部件,例如 InputDialog、FileDialog、FontDialog 等。

Example

在以下示例中,Dialog 窗口的 WindowModality 特性决定它是否是模式对话框还是非模式对话框。可以将对话框上的任意一个按钮设置为默认按钮。当用户按下 Escape 键时,通过 QDialog.reject() 方法放弃该对话框。

当顶层 QWidget 窗口上的 PushButton 被单击时,会生成一个 Dialog 窗口。Dialog 框的标题栏上没有最小化和最大化控件。

用户无法将此对话框窗口置于后台,因为其 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()

上述代码生成以下输出 -

qdialog class output

PyQt - QMessageBox

QMessageBox 是一个常用的模态对话框,用于显示一些信息消息,还可以让用户通过点击其上的任意一个标准按钮进行响应。每个标准按钮都有一个预定义的标题、一个角色,并返回一个预定义的十六进制数。

与 QMessageBox 类相关的重要方法和枚举在下表中给出−

Sr.No.

Methods & Description

1

setIcon() 显示与消息的严重性相对应的预定义图标,例如 Question Information Warning Critical

2

setText() 设置要显示的主消息的文本

3

setInformativeText() Displays additional information

4

setDetailText() 对话框显示一个“详细信息”按钮。这个文本会在此按钮被点击时出现

5

setTitle() 显示对话框的自定义标题

6

setStandardButtons() 要显示的标准按钮列表。每个按钮都与以下相关联QMessageBox.Ok 0x00000400QMessageBox.Open 0x00002000QMessageBox.Save 0x00000800QMessageBox.Cancel 0x00400000QMessageBox.Close 0x00200000QMessageBox.Yes 0x00004000QMessageBox.No 0x00010000QMessageBox.Abort 0x00040000QMessageBox.Retry 0x00080000QMessageBox.Ignore 0x00100000

7

setDefaultButton() 将按钮设为默认按钮。如果按下 Enter,它会发出 clicked 信号

8

setEscapeButton() 将按钮设置为在按下 Escape 键时视为已单击

Example

在以下示例中,点击顶层窗口上的按钮信号,连接的函数将显示消息框对话框。

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()

上述代码生成以下输出 -

qmessagebox output1
qmessagebox output2

PyQt - Multiple Document Interface

典型的 GUI 应用程序可能有多个窗口。标签式和小部件可随时激活一个这样的窗口。但是,很多时候此方法可能没有用,因为其他窗口的视图被隐藏了。

同时显示多个窗口的一种方法是将它们创建为独立窗口。这称为 SDI(单文档界面)。这需要更多的内存资源,因为每个窗口可能都有自己的菜单系统、工具栏等。

MDI(多文档界面)应用程序消耗更少的内存资源。子窗口相对于彼此放置在主容器中。容器小部件称为 QMdiArea

QMdiArea 小部件通常占据 QMainWondow 对象的中央小部件。此区域中的子窗口是 QMdiSubWindow 类的实例。可以将任何 QWidget 设置为子窗口对象的内部小部件。MDI 区域中的子窗口可以以层叠或平铺方式排列。

下表列出了 QMdiArea 类和 QMdiSubWindow 类的重要方法 -

Sr.No.

Methods & Description

1

addSubWindow() 将窗口小部件添加为 MDI 区域中的一个新子窗口

2

removeSubWindow() 移除作为子窗口的内部窗口窗口小部件

3

setActiveSubWindow() Activates a subwindow

4

cascadeSubWindows() 以级联方式排列 MDiArea 中的子窗口

5

tileSubWindows() 以平铺方式排列 MDiArea 中的子窗口

6

closeActiveSubWindow() Closes the active subwindow

7

subWindowList() 返回 MDI 区域中的子窗口列表

8

setWidget() 设置一个 QWidget 作为 QMdiSubwindow 实例的内部窗口小部件

QMdiArea 对象发出 subWindowActivated() 信号,而 QMdisubWindow 对象发出 windowStateChanged() 信号。

Example

在以下示例中,包含 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()

上述代码生成以下输出 -

multiple document interface output1
multiple document interface output2
multiple document interface output3

PyQt - Drag & Drop

提供 drag and drop 对用户来说非常直观。它存在于许多桌面应用程序中,用户可以在其中将对象从一个窗口复制或移动到另一个窗口。

基于 MIME 的拖放数据传输基于 QDrag 类。 QMimeData 对象将数据与其对应的 MIME 类型相关联。它存储在剪贴板上,然后用于拖放过程。

以下 QMimeData 类函数允许方便地检测和使用 MIME 类型。

Tester

Getter

Setter

MIME Types

hasText()

text()

setText()

text/plain

hasHtml()

html()

setHtml()

text/html

hasUrls()

urls()

setUrls()

text/uri-list

hasImage()

imageData()

setImageData()

image/ *

hasColor()

colorData()

setColorData()

application/x-color

许多 QWidget 对象支持拖放活动。允许拖拽其数据的对象已设置 setDragEnabled(),它必须设置为 true。另一方面,部件应响应拖放事件,以存储拖到其中的数据。

  1. DragEnterEvent 提供一个事件,该事件会在拖拽操作进入目标部件时发送给目标部件。

  2. 在拖放操作进行中时,将使用 DragMoveEvent

  3. 当拖放操作离开部件时,将生成 DragLeaveEvent

  4. 另一方面, DropEvent 发生在放置完成后。可以有条件地接受或拒绝事件的提议操作。

Example

在以下代码中,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()

上述代码生成以下输出 -

drag and drop output

PyQt - Database Handling

PyQt API 包含一个精密的类系统,用于与许多基于 SQL 的数据库通信。其 QSqlDatabase 通过连接对象提供访问权限。以下是当前可用的 SQL 驱动程序的列表:

Sr.No.

Driver Type & Description

1

QDB2 IBM DB2

2

QIBASE Borland InterBase Driver

3

QMYSQL MySQL Driver

4

QOCI Oracle Call Interface Driver

5

QODBC ODBC 驱动程序(包括 Microsoft SQL Server)

6

QPSQL PostgreSQL Driver

7

QSQLITE SQLite 3 或更高版本

8

QSQLITE2 SQLite version 2

Example

与 SQLite 数据库的连接是使用静态方法建立的:

db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sports.db')

QSqlDatabase 类的其他方法如下:

Sr.No.

Methods & Description

1

setDatabaseName() 设置需要建立连接的数据库的名称

2

setHostName() 设置安装数据库的主机的名称

3

setUserName() 指定用于连接的用户名

4

setPassword() 设置连接对象的密码(如果存在)

5

commit() 提交事务并在成功时返回 true

6

rollback() 回滚数据库事务

7

close() Closes the connection

QSqlQuery 类具有执行和处理 SQL 命令的功能。可以执行 DDL 和 DML 两种类型的 SQL 查询。类中最重要的一个方法是 exec_(), 它将一个包含要执行的 SQL 语句的字符串作为参数。

query = QtSql.QSqlQuery()
query.exec_("create table sportsmen(id int primary key,
   " "firstname varchar(20), lastname varchar(20))")

下面的脚本创建了一个 sports.db SQLite 数据库,其中包含一个有五条记录填充的 sportsperson 表。

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()

PyQt 中的 QSqlTableModel 类是一种高级接口,它为读取和写入一张表中的记录提供可编辑数据模型。此模型用于填充一个 QTableView 对象。它向用户展示一个可滚动的可编辑视图,该视图可以放在任何顶层窗口上。

一个 QTableModel 对象按如下方式声明 −

model = QtSql.QSqlTableModel()

可以将其编辑策略设置为下列任意一项 −

QSqlTableModel.OnFieldChange

所有更改都将立即应用

QSqlTableModel.OnRowChange

当用户选择不同的行时将应用更改

QSqlTableModel.OnManualSubmit

所有更改在调用 submitAll() 或 revertAll() 之前都会缓存起来

Example

在以下示例中,sportsperson 表用作模型,并且策略设置为 −

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 窗口。add 按钮的 clicked() 信号连接到 addrow(),后者对模型表格执行 insertRow()。

button.clicked.connect(addrow)
def addrow():
   print model.rowCount()
   ret = model.insertRows(model.rowCount(), 1)
   print ret

与删除按钮相关联的槽执行一个删除行的 lambda 函数,该行由用户选择。

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_())

上述代码生成以下输出 -

database handling output

PyQt - Drawing API

PyQt 中的所有 QWidget 类都是从 QPaintDevice 类派生的子类。 QPaintDevice 对可以通过 QPainter 绘图的二维空间进行抽象。画图设备的尺寸以从左上角开始的像素为单位进行测量。

QPainter 类对窗口小部件和打印机等其他可画图设备执行低级绘图。通常,它在窗口小部件的绘制事件中使用。 QPaintEvent 每当窗口小部件的外观更新时就会发生。

通过调用 begin() 方法激活绘图器,而 end() 方法将其停用。在两者之间,使用下表中所列的适当方法绘制所需的图案。

Sr.No.

Methods & Description

1

begin() 开始在目标设备上绘制

2

drawArc() 在起始角和结束角之间绘制弧形

3

drawEllipse() 在矩形内绘制椭圆

4

drawLine() 绘制带有指定端点的线

5

drawPixmap() 从图像文件中提取位图并将其显示在指定位置

6

drwaPolygon() 利用坐标阵列绘制多边形

7

drawRect() 从左上角坐标处绘制给定宽和高的矩形

8

drawText() 在给定坐标处显示文本

9

fillRect() 用 QColor 变量填充矩形

10

setBrush() 设置笔刷样式以进行绘制

11

setPen() 设置用于绘制的笔的颜色、大小和样式

PyQt - BrushStyle Constants

Predefined QColor Styles

Qt.NoBrush

No brush pattern

Qt.SolidPattern

Uniform color

Qt.Dense1Pattern

Extremely dense brush pattern

Qt.HorPattern

Horizontal lines

Qt.VerPattern

Vertical lines

Qt.CrossPattern

交叉水平线和垂直线

Qt.BDiagPattern

Backward diagonal lines

Qt.FDiagPattern

Forward diagonal lines

Qt.DiagCrossPattern

Crossing diagonal lines

Predefined QColor Objects

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 值选择自定义颜色。

Example

以下示例实现了上述某些方法。

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()

上述代码生成以下输出 -

brushstyle constants output

PyQt - QClipboard

QClipboard 类提供对系统范围剪贴板的访问,提供在应用程序之间拷贝/粘贴数据的简洁机制。它的操作类似于 QDrag 类,使用类似的数据类型。

QApplication 类有一个静态方法 clipboard(),它返回对剪贴板对象的引用。可以将任何类型的 MimeData 复制到剪贴板或从剪贴板粘贴。

以下是一些常用的剪贴板类的方法: -

Sr.No.

Methods & Description

1

clear() Clears clipboard contents

2

setImage() Copies QImage into clipboard

3

setMimeData() 将 MIME 数据设置到剪贴板

4

setPixmap() 在剪贴板中复制 Pixmap 对象

5

setText() Copies QString in clipboard

6

text() Retrieves text from clipboard

与剪贴板对象关联的信号是 -

Sr.No.

Method & Description

1

dataChanged() Whenever clipboard data changes

Example

在以下示例中,两个 TextEdit 对象和两个 Pushbutton 被添加到一个顶级窗口。

首先,实例化剪贴板对象。textedit 对象的 Copy() 方法将数据复制到系统剪贴板。当按下粘贴按钮时,它会获取剪贴板数据并将其粘贴到另一个 textedit 对象。

qclipboard output1
qclipboard output2
qclipboard output3

PyQt - QPixmap Class

QPixmap 类提供图像的非屏幕表示。它可以用作 QPaintDevice 对象,也可以加载到另一个小部件,通常是标签或按钮。

Qt API 还有另一个相似的类 QImage,针对 I/O 和其他像素操作进行了优化。另一方面,Pixmap 针对在屏幕上显示进行了优化。这两种格式可以互相转换。

可以读入 QPixmap 中的图像文件类型如下 -

BMP

Windows Bitmap

GIF

Graphic Interchange Format (optional)

JPG

Joint Photographic Experts Group

JPEG

Joint Photographic Experts Group

PNG

Portable Network Graphics

PBM

Portable Bitmap

PGM

Portable Graymap

PPM

Portable Pixmap

XBM

X11 Bitmap

XPM

X11 Pixmap

以下方法对于处理 QPixmap 对象很有用 -

Sr.No.

Methods & Description

1

copy() 从 QRect 对象复制像素图数据

2

fromImage() 将 QImage 对象转换为 QPixmap

3

grabWidget() 从给定小部件创建像素图

4

grabWindow() 创建窗口中数据的像素图

5

Load() 将图像文件加载为像素图

6

save() 保存 QPixmap 对象为文件

7

toImage 将 QPixmap 转换为 QImage

QPixmap 最常见的用途是在标签/按钮上显示图像。

Example

以下示例展示了使用 setPixmap() 方法在 QLabel 上显示图像。完整的代码如下 -

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()

上述代码生成以下输出 -

qpixmap class output