- PyQt Tutorial
- PyQt - Home
- PyQt - Introduction
- PyQt - Hello World
- PyQt - Major Classes
- PyQt - Using Qt Designer
- PyQt - Signals and Slots
- PyQt - Layout Management
- PyQt - Basic Widgets
- PyQt - QDialog Class
- PyQt - QMessageBox
- PyQt - Multiple Document Interface
- PyQt - Drag and Drop
- PyQt - Database Handling
- PyQt - Drawing API
- PyQt - BrushStyle Constants
- PyQt - QClipboard
- PyQt - QPixmap Class
- PyQt Useful Resources
- PyQt - Quick Guide
- PyQt - Useful Resources
- PyQt - Discussion
PyQt - 快速指南
PyQt - 简介
PyQt 是一个 GUI 小部件工具包。它是Qt的 Python 接口,Qt 是最强大、最流行的跨平台 GUI 库之一。PyQt由RiverBankComputing Ltd开发。最新版本的PyQt可以从其官方网站下载 - Riverbankcomputing.com
PyQt API 是一组包含大量类和函数的模块。虽然QtCore模块包含用于处理文件和目录等的非 GUI 功能,但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 二进制文件
PyQt4-4.11.4-gpl-Py3.4-Qt4.8.7-x64.exe | Windows 64 位安装程序 |
PyQt4-4.11.4-gpl-Py3.4-Qt4.8.7-x32.exe | Windows 32 位安装程序 |
PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x64.exe | Windows 64 位安装程序 |
PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x32.exe | Windows 32 位安装程序 |
PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x64.exe | Windows 64 位安装程序 |
PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe | Windows 32 位安装程序 |
PyQt5 Windows 二进制文件
PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x64.exe | Windows 64 位安装程序 |
PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x32.exe | Windows 32 位安装程序 |
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、PyQt4 的 UNIX 源代码 |
PyQt-gpl-5.5.tar.gz | PyQt5 的 Linux、UNIX、MacOS/X 源 |
MacOS
PyQtX 项目 ( http://sourceforge.net/projects/pyqtx/ ) 托管 PyQt for Mac 的二进制文件。按照以下命令使用 Homebrew 安装程序 -
brew install pyqt
PyQt - 你好世界
使用 PyQt 创建一个简单的 GUI 应用程序涉及以下步骤 -
导入 QtGui 模块。
创建一个应用程序对象。
QWidget 对象创建顶级窗口。在其中添加 QLabel 对象。
将标签的标题设置为“hello world”。
通过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 - 主要类
PyQt API是一个类和方法的大型集合。这些类在 20 多个模块中定义。以下是一些常用模块 -
先生。 | 模块和描述 |
---|---|
1 |
QtCore 其他模块使用的核心非 GUI 类 |
2 |
QtGUI 图形用户界面组件 |
3 |
Qt多媒体 低级多媒体编程类 |
4 |
Qt网络 网络编程类 |
5 |
QtOpenGL OpenGL 支持类 |
6 |
Qt脚本 用于评估 Qt 脚本的类 |
7 |
QtSql 使用 SQL 进行数据库集成的类 |
8 |
QtSvg 用于显示 SVG 文件内容的类 |
9 |
QtWebKit 用于渲染和编辑 HTML 的类 |
10 |
QtXml 用于处理 XML 的类 |
11 |
Qt助手 支持在线帮助 |
12 |
Qt设计器 用于扩展 Qt Designer 的类 |
PyQt API 包含 400 多个类。QObject类位于类层次结构的顶部。它是所有 Qt 对象的基类。此外,QPaintDevice类是所有可绘制对象的基类。
QApplication类管理 GUI 应用程序的主要设置和控制流程。它包含主事件循环,在其中处理和调度由窗口元素和其他源生成的事件。它还处理系统范围和应用程序范围的设置。
QWidget类派生自 QObject 和 QPaintDevice 类,是所有用户界面对象的基类。QDialog和QFrame类也派生自 QWidget 类。他们有自己的子类系统。
下图描述了其层次结构中的一些重要类。
以下是常用小部件的选择列表 -
下面给出了常用的 Widget。
先生。 | 小部件和描述 |
---|---|
1 |
Q标签 用于显示文本或图像 |
2 |
QLine编辑 允许用户输入一行文本 |
3 |
QText编辑 允许用户输入多行文本 |
4 |
Q按钮 用于调用操作的命令按钮 |
5 |
Q单选按钮 允许从多个选项中选择一个 |
6 |
Q复选框 允许选择多个选项 |
7 |
QSpinBox 允许增加/减少整数值 |
8 |
Q滚动条 允许访问显示孔径之外的小部件的内容 |
9 |
Q滑块 能够线性改变界限值。 |
10 |
QComboBox 提供可供选择的项目的下拉列表 |
11 |
Q菜单栏 包含 QMenu 对象的单杠 |
12 |
Q状态栏 通常在 QMainWindow 的底部,提供状态信息。 |
13 |
Q工具栏 通常位于 QMainWindow 的顶部或浮动。包含操作按钮 |
14 |
QListView 以 ListMode 或 IconMode 提供可选择的项目列表 |
15 |
Q像素图 用于在 QLabel 或 QPushButton 对象上显示的离屏图像表示 |
16 |
QDialog 可以向父窗口返回信息的模态或非模态窗口 |
典型的基于 GUI 的应用程序的顶级窗口是由QMainWindow小部件对象创建的。上面列出的一些小部件在此主窗口中占据指定位置,而其他小部件则使用各种布局管理器放置在中央小部件区域中。
下图显示了 QMainWindow 框架 -
PyQt - 使用 Qt 设计器
PyQt 安装程序附带一个名为Qt Designer 的GUI 构建工具。使用其简单的拖放界面,可以快速构建 GUI 界面,而无需编写代码。但是,它不是 Visual Studio 等 IDE。因此,Qt Designer 不具备调试和构建应用程序的功能。
使用 Qt Designer 创建 GUI 界面首先要为应用程序选择一个顶级窗口。
然后,您可以从左侧窗格的小部件框中拖放所需的小部件。您还可以为表单上放置的小部件的属性分配值。
设计好的表单保存为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 脚本以显示以下对话框 -
用户可以在输入字段中输入数据,但单击“添加”按钮不会生成任何操作,因为它不与任何功能关联。对用户生成的响应做出反应称为事件处理。
PyQt - 信号和槽
与以顺序方式执行的控制台模式应用程序不同,基于 GUI 的应用程序是事件驱动的。函数或方法的执行是为了响应用户的操作,例如单击按钮、从集合中选择项目或单击鼠标等,称为事件。
用于构建 GUI 界面的小部件充当此类事件的源。每个 PyQt 小部件都派生自 QObject 类,旨在发出“信号”以响应一个或多个事件。该信号本身不执行任何操作。相反,它“连接”到“插槽”。该槽可以是任何可调用的 Python 函数。
在 PyQt 中,信号和槽之间的连接可以通过不同的方式实现。以下是最常用的技术 -
QtCore.QObject.connect(widget, QtCore.SIGNAL(‘signalname’), slot_function)
当小部件发出信号时,调用 slot_function 的更方便的方法如下 -
widget.signal.connect(slot_function)
假设单击按钮时是否要调用一个函数。在这里,单击的信号将连接到可调用的函数。它可以通过以下两种技术中的任何一种来实现 -
QtCore.QObject.connect(button, QtCore.SIGNAL(“clicked()”), slot_function)
或者
button.clicked.connect(slot_function)
例子
在下面的示例中,两个 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)
例子
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
PyQt - 布局管理
通过指定以像素为单位的绝对坐标,可以将 GUI 小部件放置在容器窗口内。坐标与 setGeometry() 方法定义的窗口尺寸相关。
setGeometry() 语法
QWidget.setGeometry(xpos, ypos, width, height)
在以下代码片段中,尺寸为 300 x 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 像素的位置。
然而,由于以下原因,这种绝对定位并不合适 -
即使调整窗口大小,小部件的位置也不会改变。
在具有不同分辨率的不同显示设备上,外观可能不统一。
布局的修改很困难,因为可能需要重新设计整个表单。
PyQt API 提供布局类,以便更优雅地管理容器内小部件的定位。布局管理器相对于绝对定位的优点是 -
窗口内的小部件会自动调整大小。
确保不同分辨率的显示设备上的外观一致。
无需重新设计即可动态添加或删除小部件。
这是我们将在本章中一一讨论的类列表。
先生。 | 类别和描述 |
---|---|
1 | QBox布局
QBoxLayout 类垂直或水平排列小部件。它的派生类是QVBoxLayout(用于垂直排列小部件)和QHBoxLayout(用于水平排列小部件)。 |
2 | QGrid布局
GridLayout 类对象呈现按行和列排列的单元格网格。该类包含 addWidget() 方法。可以通过指定单元格的行数和列数来添加任何小部件。 |
3 | QForm布局
QFormLayout 是创建两列表单的便捷方法,其中每行包含一个与标签关联的输入字段。按照惯例,左列包含标签,右列包含输入字段。 |
PyQt - 基本小部件
这是我们将在本章中一一讨论的小部件列表。
先生编号 | 小部件和描述 |
---|---|
1 | Q标签
QLabel 对象充当占位符来显示不可编辑的文本或图像,或者动画 GIF 的电影。它还可以用作其他小部件的助记键。 |
2 | QLine编辑
QLineEdit对象是最常用的输入字段。它提供了一个可以在其中输入一行文本的框。为了输入多行文本,需要 QTextEdit 对象。 |
3 | Q按钮
在 PyQt API 中,QPushButton 类对象呈现一个按钮,单击该按钮时可以对其进行编程以调用特定功能。 |
4 | Q单选按钮
QRadioButton 类对象提供带有文本标签的可选按钮。用户可以选择表单上呈现的众多选项之一。该类派生自 QAbstractButton 类。 |
5 | Q复选框
当 QCheckBox 对象添加到父窗口时,文本标签之前会出现一个矩形框。就像QRadioButton一样,它也是一个可选择的按钮。 |
6 | QComboBox
QComboBox 对象呈现一个可供选择的项目的下拉列表。仅显示当前选定的项目所需的表单上所需的最小屏幕空间。 |
7 | QSpinBox
QSpinBox 对象向用户呈现一个文本框,该文本框显示一个整数,右侧带有向上/向下按钮。 |
8 | QSlider 小部件和信号
QSlider 类对象向用户提供了一个可以在其上移动手柄的凹槽。它是一个控制有界值的经典小部件。 |
9 | QMenuBar、QMenu 和 QAction
QMainWindow 对象标题栏正下方的水平 QMenuBar 保留用于显示 QMenu 对象。 |
10 | Q工具栏
QToolBar 小部件是一个可移动面板,由文本按钮、带有图标的按钮或其他小部件组成。 |
11 | Q输入对话框
这是一个预配置的对话框,带有一个文本字段和两个按钮:“确定”和“取消”。用户单击“确定”按钮或按 Enter 键后,父窗口会收集文本框中的输入。 |
12 | Q字体对话框
另一个常用的对话框,字体选择器小部件是 QDialog 类的视觉外观。该对话框的结果是一个 Qfont 对象,可以由父窗口使用。 |
13 | Q文件对话框
该小部件是一个文件选择器对话框。它使用户能够浏览文件系统并选择要打开或保存的文件。该对话框可以通过静态函数或通过调用对话框对象上的 exec_() 函数来调用。 |
14 | Q选项卡
如果表单有太多字段无法同时显示,则可以将它们排列在位于选项卡式小部件的每个选项卡下的不同页面中。QTabWidget 提供了一个选项卡栏和一个页面区域。 |
15 | Q堆叠
QStackedWidget 的功能与 QTabWidget 类似。它还有助于有效地使用窗口的客户区。 |
16 | QSplitter
如果表单有太多字段无法同时显示,则可以将它们排列在位于选项卡式小部件的每个选项卡下的不同页面中。QTabWidget 提供了一个选项卡栏和一个页面区域。 |
17 号 | QDock
可停靠窗口是可以保持浮动状态或可以附加到主窗口指定位置的子窗口。QMainWindow 类的主窗口对象有一个为可停靠窗口保留的区域。 |
18 | Q状态栏
QMainWindow对象在底部保留一个水平条作为状态栏。它用于显示永久或上下文状态信息。 |
19 | 问题列表
QListWidget 类是一个基于项目的接口,用于从列表中添加或删除项目。列表中的每个项目都是一个 QListWidgetItem 对象。ListWidget 可以设置为多选。 |
20 | Q滚动条
滚动条控件使用户能够访问文档中可视区域之外的部分。它提供当前位置的视觉指示器。 |
21 | QC日历
QCalendar 小部件是一个有用的日期选择器控件。它提供了基于月份的视图。用户可以通过使用鼠标或键盘来选择日期,默认为今天的日期。 |
PyQt - QDialog 类
QDialog小部件提供了一个顶级窗口,主要用于收集用户的响应。它可以配置为模态(阻止其父窗口)或无模式(可以绕过对话框窗口)。
PyQt API 有许多预配置的对话框小部件,例如 InputDialog、FileDialog、FontDialog 等。
例子
在下面的示例中,Dialog 窗口的 WindowModality 属性决定它是模态还是非模态。对话框上的任何一个按钮都可以设置为默认按钮。当用户按下 Escape 键时,QDialog.reject() 方法将丢弃该对话框。
单击顶级 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()
上面的代码产生以下输出 -
PyQt-QMessageBox
QMessageBox是一种常用的模式对话框,用于显示一些信息性消息,并可选择要求用户通过单击其上的任何一个标准按钮进行响应。每个标准按钮都有一个预定义的标题、一个角色并返回一个预定义的十六进制数字。
下表给出了与 QMessageBox 类相关的重要方法和枚举 -
先生。 | 方法与说明 |
---|---|
1 |
设置图标() 显示与消息严重性相对应的预定义图标 问题 信息 警告 批判的 |
2 |
设置文本() 设置要显示的主要消息的文本 |
3 |
设置信息文本() 显示附加信息 |
4 |
设置详细信息文本() 对话框显示“详细信息”按钮。单击该文本后会出现该文本 |
5 |
设置标题() 显示对话框的自定义标题 |
6 |
设置标准按钮() 要显示的标准按钮列表。每个按钮都与 QMessageBox.确定0x00000400 QMessageBox.打开0x00002000 QMessageBox.保存0x00000800 QMessageBox.取消0x00400000 QMessageBox.关闭0x00200000 QMessageBox.是0x00004000 QMessageBox.No 0x00010000 QMessageBox.中止0x00040000 QMessageBox.重试0x00080000 QMessageBox.忽略0x00100000 |
7 |
设置默认按钮() 将按钮设置为默认值。如果按下 Enter 键,它会发出单击信号 |
8 |
设置退出按钮() 如果按下退出键,则将按钮设置为单击 |
例子
在下面的示例中,单击顶层窗口上的按钮信号,连接的函数将显示消息框对话框。
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()
上面的代码产生以下输出 -
PyQt - 多文档界面
典型的 GUI 应用程序可能有多个窗口。选项卡式和堆叠式小部件允许一次激活一个这样的窗口。然而,很多时候这种方法可能没有用,因为其他窗口的视图被隐藏了。
同时显示多个窗口的一种方法是将它们创建为独立的窗口。这称为 SDI(单文档接口)。这需要更多的内存资源,因为每个窗口可能有自己的菜单系统、工具栏等。
MDI(多文档界面)应用程序消耗更少的内存资源。子窗口相对于彼此放置在主容器内。容器小部件称为QMdiArea。
QMdiArea小部件通常占据QMainWondow对象的中央小部件。该区域中的子窗口是 QMdiSubWindow 类的实例。可以将任何 QWidget 设置为 subWindow 对象的内部小部件。MDI 区域中的子窗口可以按级联或平铺方式排列。
下表列出了 QMdiArea 类和 QMdiSubWindow 类的重要方法 -
先生。 | 方法与说明 |
---|---|
1 |
添加子窗口() 在 MDI 区域中添加一个小部件作为新的子窗口 |
2 |
移除子窗口() 删除属于子窗口内部小部件的小部件 |
3 |
设置活动子窗口() 激活子窗口 |
4 |
级联子窗口() 以级联方式排列 MDiArea 中的子窗口 |
5 |
瓦片子窗口() 以平铺方式排列 MDiArea 中的子窗口 |
6 |
关闭活动子窗口() 关闭活动子窗口 |
7 |
子窗口列表() 返回MDI区域中的子窗口列表 |
8 |
设置小部件() 将 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()
上面的代码产生以下输出 -
PyQt - 拖放
拖放功能对于用户来说非常直观。它存在于许多桌面应用程序中,用户可以将对象从一个窗口复制或移动到另一个窗口。
基于 MIME 的拖放数据传输基于 QDrag 类。QMimeData对象将数据与其相应的 MIME 类型相关联。它存储在剪贴板上,然后在拖放过程中使用。
下面的QMimeData类函数可以方便地检测和使用MIME类型。
测试员 | 吸气剂 | 塞特 | MIME 类型 |
---|---|---|---|
有文本() | 文本() | 设置文本() | 文本/纯文本 |
hasHtml() | html() | 设置Html() | 文本/html |
hasUrls() | 网址() | 设置网址() | 文本/uri-列表 |
有图像() | 图像数据() | 设置图像数据() | 图像/ * |
有颜色() | 颜色数据() | 设置颜色数据() | 应用程序/x-颜色 |
许多 QWidget 对象支持拖放活动。那些允许拖动数据的 setDragEnabled() 必须设置为 true。另一方面,小部件应该响应拖放事件,以便存储拖入其中的数据。
DragEnterEvent提供了一个事件,当拖动操作进入目标窗口小部件时,该事件会发送到目标窗口小部件。
DragMoveEvent在拖放操作正在进行时使用。
当拖放操作离开小部件时,会生成DragLeaveEvent 。
另一方面,DropEvent在放置完成时发生。事件提议的行动可以有条件地接受或拒绝。
例子
在以下代码中,DragEnterEvent 验证事件的 MIME 数据是否包含文本。如果是,则接受事件建议的操作,并将文本作为新项目添加到组合框中。
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 - 数据库处理
PyQt API 包含一个精心设计的类系统,用于与许多基于 SQL 的数据库进行通信。它的 QSqlDatabase 通过 Connection 对象提供访问。以下是当前可用的 SQL 驱动程序的列表 -
先生。 | 驱动程序类型和描述 |
---|---|
1 | QDB2 IBM DB2 |
2 | 启基数据库 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 类的其他方法如下 -
先生。 | 方法与说明 |
---|---|
1 |
设置数据库名称() 设置寻求连接的数据库的名称 |
2 |
设置主机名() 设置安装数据库的主机的名称 |
3 |
设置用户名() 指定连接的用户名 |
4 |
设置密码() 设置连接对象的密码(如果有) |
5 |
犯罪() 提交交易,如果成功则返回 true |
6 |
回滚() 回滚数据库事务 |
7 |
关闭() 关闭连接 |
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))")
以下脚本创建一个 SQLite 数据库 sports.db,其中包含一个填充有 5 条记录的运动员表。
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() |
例子
在以下示例中,使用运动员表作为模型,策略设置为 -
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
与删除按钮关联的槽执行 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_())
上面的代码产生以下输出 -
PyQt - 绘图 API
PyQt 中的所有QWidget类都是 QPaintDevice 类的子类。QPaintDevice是二维空间的抽象,可以使用 QPainter 进行绘制。绘画设备的尺寸从左上角开始以像素为单位进行测量。
QPainter 类在小部件和其他可绘制设备(例如打印机)上执行低级绘制。通常,它用在小部件的绘制事件中。每当窗口部件的外观更新时,QPaintEvent就会发生。
画家通过调用 begin() 方法来激活,而 end() 方法则将其停用。其间,通过下表中列出的适当方法绘制所需的图案。
先生。 | 方法与说明 |
---|---|
1 |
开始() 开始在目标设备上绘画 |
2 |
绘制弧线() 在起始角度和结束角度之间绘制圆弧 |
3 |
画椭圆() 在矩形内绘制椭圆 |
4 |
画线() 绘制一条指定端点坐标的线 |
5 |
绘制像素图() 从图像文件中提取pixmap并将其显示在指定位置 |
6 |
drwaPolygon() 使用坐标数组绘制多边形 |
7 |
绘制矩形() 从左上角坐标开始绘制一个具有给定宽度和高度的矩形 |
8 |
绘制文本() 在给定坐标处显示文本 |
9 |
填充矩形() 使用 QColor 参数填充矩形 |
10 |
设置画笔() 设置绘画的画笔样式 |
11 |
设置笔() 设置用于绘图的笔的颜色、大小和样式 |
PyQt - BrushStyle 常量
预定义的 QColor 样式
Qt.NoBrush | 无画笔图案 |
Qt.SolidPattern | 颜色均匀 |
Qt.Dense1Pattern | 极其密集的笔刷图案 |
Qt.HorPattern | 水平线 |
Qt.VerPattern | 垂直线 |
Qt.CrossPattern | 跨越水平线和垂直线 |
Qt.BDiagPattern | 向后对角线 |
Qt.FDiagPattern | 向前对角线 |
Qt.DiagCrossPattern | 穿过对角线 |
预定义的 QColor 对象
怀特Qt |
Qt.black |
红Qt |
Qt.深红 |
Qt绿色 |
Qt.深绿 |
Qt.蓝 |
青色Qt |
洋红Qt |
黄Qt |
Qt.暗黄 |
Qt.格雷 |
可以通过指定 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()
上面的代码产生以下输出 -
PyQt - QClipboard
QClipboard类提供对系统范围剪贴板的访问,该剪贴板提供了在应用程序之间复制和粘贴数据的简单机制。它的操作与 QDrag 类类似,并且使用类似的数据类型。
QApplication类有一个静态方法clipboard(),它返回对剪贴板对象的引用。任何类型的 MimeData 都可以复制到剪贴板或从剪贴板粘贴。
以下是常用的剪贴板类方法 -
先生。 | 方法与说明 |
---|---|
1 |
清除() 清除剪贴板内容 |
2 |
设置图像() 将 QImage 复制到剪贴板 |
3 |
设置MimeData() 将 MIME 数据设置到剪贴板 |
4 |
设置像素图() 复制剪贴板中的 Pixmap 对象 |
5 |
设置文本() 复制剪贴板中的 QString |
6 |
文本() 从剪贴板检索文本 |
与剪贴板对象关联的信号是 -
先生。 | 方法及说明 |
---|---|
1 |
数据改变() 每当剪贴板数据发生变化时 |
例子
在以下示例中,两个 TextEdit 对象和两个按钮被添加到顶级窗口。
首先实例化剪贴板对象。textedit 对象的 Copy() 方法将数据复制到系统剪贴板。单击“粘贴”按钮时,它会获取剪贴板数据并将其粘贴到其他文本编辑对象中。
PyQt - QPixmap 类
QPixmap类提供图像的离屏表示。它可以用作 QPaintDevice 对象,也可以加载到另一个小部件中,通常是标签或按钮。
Qt API 有另一个类似的类 QImage,它针对 I/O 和其他像素操作进行了优化。另一方面,像素图针对在屏幕上显示进行了优化。两种格式可以相互转换。
可以读入 QPixmap 对象的图像文件类型如下 -
骨形态发生蛋白 | 窗口位图 |
动图 | 图形交换格式(可选) |
JPG | 联合摄影专家组 |
JPEG | 联合摄影专家组 |
巴布亚新几内亚 | 便携式网络图形 |
药物管理 | 便携式位图 |
铂族金属 | 便携式灰度图 |
生产计划管理 | 便携式像素图 |
XBM | X11 位图 |
XPM | X11 像素图 |
以下方法在处理 QPixmap 对象时很有用 -
先生。 | 方法与说明 |
---|---|
1 |
复制() 从 QRect 对象复制像素图数据 |
2 |
从图像() 将 QImage 对象转换为 QPixmap |
3 |
抓取Widget() 从给定的小部件创建像素图 |
4 |
抓取窗口() 在窗口中创建数据的像素图 |
5 |
加载() 将图像文件加载为像素图 |
6 |
节省() 将 QPixmap 对象保存为文件 |
7 |
印象 将 QPixmap 转换为 QImage |
QPixmap 最常见的用途是在标签/按钮上显示图像。
例子
以下示例显示了使用 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()
上面的代码产生以下输出 -