从Qt到PyQt
Hello World
PyQt与Qt具有极其相似的类族和API,而且不再使用qmake系统和Q_OBJECT宏使得PyQt在没有编译链接时频繁的错误而且代码更加友好。
from PyQt4 import QtCore, QtGui
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv);
mainWindow = QtGui.QMainWindow();
mainWindow.setWindowTitle('Hello World from PyQt')
mainWindow.show()
label = QtGui.QLabel('Hello World', mainWindow)
label.show()
sys.exit(app.exec_())
将项目中所有文件均放入工作目录下,使用python
或pythonw
命令执行入口文件,即可启动PyQt应用。
可视化组件
PyQt的可视化组件依旧以QtGui.QWidget作为基类,与Qt的API非常类似。更多信息参见
布局使用示例:
from PyQt4 import QtCore, QtGui
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv);
# init Gui
mainWindow = QtGui.QMainWindow();
mainWindow.setWindowTitle('Hello World from PyQt')
button = QtGui.QPushButton('quit',mainWindow)
# set layout
mainLayout = QtGui.QVBoxLayout(mainWindow)
mainLayout.addWidget(button)
mainWindow.setLayout(mainLayout)
# show GUI
mainWindow.show()
button.show()
# init Signal-Slot , Run App
QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), app, QtCore.SLOT('quit()'))
# QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), app.quit)
sys.exit(app.exec_())
使用Qt Designer
Qt Designer 依旧生成.ui后缀名的xml文件保存界面设计,pyuic4工具可以将.ui格式编译为.py格式的Python类。
确保pyuic4命令所目录在path中,执行:pyuic4 firstDesign.ui > ui_firstDesign.py
,
可以得到文件 ui_firstDesign.py:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'firstDesign.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(800, 600)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
# ...
# something has been deleted
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.pushButton.setText(_translate("MainWindow", "OK", None))
导入ui_firstDesign
模块,调用Ui_MainWindow.setupUi()
方法建立UI:
#main.pyw
import sys
from PyQt4 import QtCore, QtGui
from ui_firstDesign import Ui_MainWindow
class MyForm(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self,parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
form = MyForm()
form.show()
sys.exit(app.exec_())
运行:
使用Python标准库
PyQt包含以下模块:
- QtCore
核心非GUI组件,包括QObject,事件与信号槽,数据流等。
- QtGui
可视化组件与绘图系统。
- QtOpenGL
OpenGL 支持并与QtGui 结合
- QtSvg
提供对可缩放矢量图(SVG)的支持。
- QtNetwork
提供IP,TCP,UDP协议套接字支持,可以开发简单客户端与服务器。
- QtXml
提供DOM与SAX两种xml解析
- QtSql
提供对Sql的支持
与C++不同,Python标准库具有很多方便使用的功能。在使用C++/Qt时作笔者选择使用QString取代std::string,并使用Qt库提供的网络操作,多任务模型,数据库模块等。
在使用PyQt时可以使用标准的Python 网络,多任务和数据库模块。PyQt的QThread具有支持Qt的事件循环,在需要事件驱动机制可以使用,但无法避开GIL造成性能损失。
信号槽与事件
信号槽
PyQt中绝大多数类均继承了QObject类,QtCore.QObject与QtCore提供了一系列方法进行信号槽操作:
- QtCore.pyqtSignal()
用于定义信号对象:signalObj = QtCore.pyqtSignal(*args)
- @QtCore.pyqtSlot()
使用装饰器将一个函数对象装饰为槽函数:
from PyQt4 import QtGui, QtCore
class MainWidget(QtGui.QWidget):
def __init__():
pass
@QtCore.pyqtSlot()
def onClicked(self):
QtGui.QMessageBox.information(self, u"Message", u"Get a Signal")
- QtCore.SIGNAL() 与 QtCore.SLOT()
将代表函数签名的字符串转化为信号槽,与Qt中的SIGNAL()和SLOT宏功能相同。
- QObject.connect()
connect具有两种常用方式,即槽可以使用Python函数对象或者@QtCore.pyqtSlot()修饰的PyQt槽。
QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), app, QtCore.SLOT('quit()'))
或者:
QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), app.quit)
- QObject.emit()
QObject.emit()用于发送信号,与Qt中的emit关键字功能相同。
class MyWidget(QtGui.QWidget):
def emitSignal(self):
self.emit(QtCore.SIGNAL('onClicked()'))
或者
class MyWidget(QtGui.QWidget):
def emitSignal(self):
self.mySignal = QtCore.pyqtSignal();
emit的可选参数可以发送带参数的信号:
self.emit(QtCore.SIGNAL('myClicked(QString)'), 'hello')
示例:
from PyQt4 import QtCore, QtGui
import sys
class MyButton(QtGui.QPushButton):
def __init__(self, *args, **kwargs):
QtGui.QPushButton.__init__(self, *args, **kwargs)
self.connect(self, QtCore.SIGNAL("clicked()"), self.emitSignal)
def emitSignal(self):
self.emit(QtCore.SIGNAL('myClicked(QString)'), 'hello')
app = QtGui.QApplication(sys.argv);
mainWindow = QtGui.QMainWindow();
@QtCore.pyqtSlot()
def showMsg(sig):
QtGui.QMessageBox.information(mainWindow, "Msg", "Siganl Received:" + sig)
if __name__ == '__main__':
#my Signal
button = MyButton('emit signal',mainWindow)
mainWindow.connect(button,QtCore.SIGNAL('myClicked(QString)'), showMsg)
#quit button
quitButton = QtGui.QPushButton('quit', mainWindow)
quitButton.move(0,40)
QtCore.QObject.connect(quitButton, QtCore.SIGNAL('clicked()'), app, QtCore.SLOT('quit()'))
# Start App
mainWindow.show()
button.show()
sys.exit(app.exec_())
event()事件处理机制
QObject.event()是PyQt中处理处理事件的另一个机制, 继承QObject()的类都可以重写event系列方
系列实现事件处理。
event()方法进行事件分发一般不直接处理事件,类族中event()链式调用可以方便的自定义事件处理。
一个事件将从最末端派生类的event函数开始处理,当一个事件被处理后调用QObject.accept()方法通知Qt结束该事件处理过程;;若该事件未被处理,Qt将会把该事件交由其父类的event函数处理。
bool QOject::isAccepted()
函数将返回代表事件是否被处理的逻辑值。
若在事件处理过程中,调用了QObject::ignore()
方法,Qt将会终止事件向上递归,即忽略事件直接终止事件处理过程.忽略事件是危险的,尽量不要这么做。
示例,自定义事件处理:
from PyQt4 import QtCore, QtGui
import sys
class MyWidget():
def event(self,event):
if(event.type() == QtCore.QEvent.KeyPress):
if (event.key() == QtCore.Qt.Key_Escape):
self.emit(QtCore.SIGNAL("escapePressed()"))
event.accept()
return True
return super(MyWidget, self).event(event)
重写键盘事件处理keyReleaseEvent()与绘图paintEvent()等方法可以方便的处理按键或者绘制界面。以及内置的计时系统timerEvent()。
注意必须设置位置参数event:def keyPressEvent(self, event):
示例,[ESC]键退出应用:
# !/usr/bin/python
import sys
from PyQt4 import QtGui, QtCore
class Escape(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle('escape')
self.resize(250, 150)
self.connect(self, QtCore.SIGNAL('closeEmitApp()'),
QtCore.SLOT('close()'))
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
self.close()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
qb = Escape()
qb.show()
sys.exit(app.exec_())
绘图系统
因为不需要Q_PROPERTY所以使用更加方便。
QAnimation示例:
from PyQt4 import QtCore, QtGui
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QMainWindow()
mainWindow.resize(400, 400)
mainWindow.show()
label = QtGui.QLabel('Animated Button', mainWindow)
label.show()
# Animation
animation = QtCore.QPropertyAnimation(label, 'geometry', mainWindow)
animation.setDuration(10 * 1000)
animation.setKeyValueAt(0.5, QtCore.QRect(125, 250, 100, 30))
animation.setEndValue(QtCore.QRect(250, 0, 100, 30))
animation.start()
#Run event loop
sys.exit(app.exec_())
Graphics View示例:
from PyQt4 import QtCore, QtGui
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QMainWindow()
mainWindow.resize(300, 200)
mainWindow.show()
# Graphics View
scene = QtGui.QGraphicsScene(mainWindow)
scene.addText('Graphics View Rotate')
view =QtGui.QGraphicsView(scene,mainWindow)
view.resize(200,150)
view.rotate(+45)
view.show()
#Run event loop
sys.exit(app.exec_())
从Qt到PyQt的更多相关文章
- Qt与PyQT中设置ToolBar在AllowedArea的显示
因为个人对传统的软件GUI界面不是太喜欢,最近又在学习Qt和PyQt5,所以就有了设置ToolBar在窗口的不同地方的想法,经过浪里淘沙,最终在Qt官网里找到了,原来再添加toolBar的时候是由设置 ...
- 痞子衡嵌入式:超级好用的可视化PyQt GUI构建工具(Qt Designer)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是PyQt GUI构建工具Qt Designer. 痞子衡开博客至今已有好几年,一直以嵌入式开发相关主题的文章为主线,偶尔穿插一些其他技术 ...
- 第15.38节 PyQt(Python+Qt)入门学习:containers容器类部件QDockWidget停靠窗功能详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QDockWidget类提供了一个可以停靠在QMainWin ...
- PyQt(Python+Qt)学习随笔:QDockWidget停靠部件floating和features属性
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 1.floating属性 floating属性表示QDockWidge ...
- PyQt(Python+Qt)学习随笔:QTableWidget表格部件中行高和列宽的计算方式
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget表格部件中行高和列宽的计算在Qt提供的资料中内容介绍比较泛,细节说得不清楚, ...
- 第15.9节 PyQt学习入门:使用Qt Designer进行GUI设计的步骤
在使用Qt Designer进行GUI设计时,一般常规的步骤都是差不多的,主要步骤包括新建显示窗口.在窗口上按照规划的布局放置组件.设置初始化组件的属性.定义信号和槽函数的连接,一般后三步是每增加一个 ...
- Pyqt 基础功能
总结Pyqt的基础知识 1. Pyqt 设置禁止最大化及禁止拖拽窗口大小 # PyQT禁止窗口最大化按钮: self.setWindowFlags(QtCore.Qt.WindowMinimizeB ...
- Pyqt+QRcode 生成 识别 二维码
1.生成二维码 python生成二维码是件很简单的事,使用第三方库Python QRCode就可生成二维码,我用Pyqt给QRcode打个壳 一.python-qrcode介绍 python-qrco ...
- Pyqt 音视频播放器
在寻找如何使用Pyqt做一个播放器时首先找到的是openCV2 openCV2 貌似太强大了,各种关于图像处理的事情它都能完成,如 读取摄像头.图像识别.人脸识别. 图像灰度处理 . 播放视频等,强 ...
随机推荐
- VSTS 更名为 Azure DevOps
微软正式对外宣布Azure DevOps,其实就是原来的VSTS,我们来看一下Azure DevOps的介绍: 今天我们宣布Azure DevOps.与世界各地的客户和开发人员合作,很明显,DevOp ...
- ES6 学习笔记之四 对象的扩展
ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便. 一.属性的简洁表示法 当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名. 例1: , ...
- C#treeView控件单击事件选中节点滞后问题解决方法
问题描述:在treeView的Click事件中,选中的节点SelectedNode并不是您刚才点击的节点,总是上一次选中的节点,节点选中滞后的问题. 解决方案:在treeView的MouseDown事 ...
- Day 21 序列化模块_Json,Pickle,Shelve
序列化 , 数据类型,列表 元组, 字符串 只有字符串能被写入文件中. 能在网络上传输的只能是bytes - 字符串 把要传输的和要存储的内容转换成字符串. 字符串 转换回 要传输和存储的内容 序列化 ...
- iOS推送功能极光推送的介绍与实现
1.个人整理操作流程 2.官方使用说明流程 2018iOS极光推送完整流程 极光推送官网
- ModelForm错误验证自定义钩子和全局钩子
当需要对model_class中字段作进一步验证,作进一步的约束时,需要使用到钩子,即claan_xxx和clean方法.其返回的errors有点不是那么好处理.看示例. 1.Model_clas ...
- ThinkPHP5.0手把手实现手机阿里云短信验证
阿里云短信服务介绍阿里云短信服务就是以前的阿里大于,不过现在融合得到阿里云平台了.首先,你需要注册一个阿里云账号,这个自行解决. 仅用于测试使用官方送的代金券够用了.相关配置1.开通阿里云Access ...
- 日志分析与splunk浅谈
难易程度:★★★ 阅读点:linux;python;web安全;日志分析; 文章作者:xiaoye 文章来源:i春秋 关键字:网络渗透技术 前言 linux下的日志分析对企业来说非常重要,对我们分析p ...
- 前端ajax传数据成功发送,但后端接收不到
前几天遇到这样的问题,找了好久,是在ajax contentType属性设置的问题. contentType默认是application/x-www-form-urlencoded 但是 ...
- elasticsearch索引目录设置
path.data and path.logs If you are using the .zip or .tar.gz archives, the data and logs directories ...