认识PyQt窗口界面
对于Python GUI库,你可以有很多的选择(十几种),比如自带的Tkinter(上手简单,但是界面不是很美观)亦或者是wxPython,但本文讲述PyQt。
Qt是一个跨平台框架,使用C ++编写。这是一个非常全面的库。它包含许多工具和API,被广泛应用于许多行业,并涵盖了众多平台。而且它有布局插件(Qt Designer),使得复杂的结构布局简单化。
Qt从1991年开发至今,经历迭代了很多版本,示例使用的是PyQt5。
一、认识PyQt基础窗口操作
1、示例
直接上例子代码,难点后面解释。
# 导入组件
from PyQt5.QtWidgets import QApplication,QLineEdit,QVBoxLayout,QWidget,QTextBrowser,QLabel
# 导入UI
from PyQt5.QtGui import QIcon,QPixmap
from PyQt5.QtCore import Qt
from math import *
class Expression_Calculate(QWidget):
def __init__(self):
super().__init__()
self.myui()
def myui(self):
self.le = QLineEdit(self)
self.le.setPlaceholderText("输入表达式回车")
self.le.selectAll()
self.tb = QTextBrowser(self)# 一个只读的多行文本框
# 布局使用盒布局
vbox = QVBoxLayout()
vbox.addWidget(self.tb)
vbox.addWidget(self.le)
self.setLayout(vbox)
self.le.setFocus()# 让光标从单行编辑器开始
self.le.returnPressed.connect(self.updateUI)# 单行编译框当按下回车时绑定自定义函数
self.setGeometry(300,300,400,300)
self.setWindowTitle("表达式计算")
self.setWindowIcon(QIcon(r"C:\Users\admin\Desktop\python\图标\计算器.png"))
def updateUI(self):
text = self.le.text()
try:
self.tb.append("%s = <b>%s</b>" % (text,eval(text)))# eval 计算字符串中的表达式并返回结果
except:
self.tb.append("<font color=red>%s is Invalid!</font>" %text)
def keyPressEvent(self, e):# 快捷见退出程序
if e.key() == Qt.Key_Q:
self.close()
if __name__ == "__main__":
app = QApplication([])
ec = Expression_Calculate()
ec.show()
app.exec_()
2、讲解
加载需要的库和组件这里不再说明,但是要是从头开始学,个人建议还是需要什么组件导入什么组件,而不是导入全部(from PyQt5.QtWidgets import *),一方面可以掌握pyqt包含的组件,另一方面可以对各个组件在那个库有一个初步的认识。
def __init__(self):
super().__init__()
self.myui()
初始化类,申明继承以及变量等,super()超类初始化,也就是继承父类的init方法,self.myui()就是调用编写的ui界面函数。
self.le = QLineEdit(self)
self.le.setPlaceholderText("输入表达式回车")
self.le.selectAll()
self.tb = QTextBrowser(self)# 一个只读的多行文本框
定义单行编辑框和只读的多行文本框,并且配置单行编辑框提示字符以及选择所有的内容
self.setGeometry(300,300,400,300)
self.setWindowTitle("表达式计算")
self.setWindowIcon(QIcon(r"C:\Users\admin\Desktop\python\图标\计算器.png"))
设置主窗口的位置大小,setGeometry(x,y,w,h),设置窗口的标题,设置窗口的图标,图标使用QIcon转化。
# 布局使用盒布局
vbox = QVBoxLayout()
vbox.addWidget(self.tb)
vbox.addWidget(self.le)
self.setLayout(vbox)
定义纵向盒布局,然后把之前的组件放在盒布局之内,最后设置窗口的布局按纵向盒布局布局,啰嗦一句,布局时一件很复杂且很费精力的事,所以后面一般都是使用插件(Qt Designer)完成。
self.le.returnPressed.connect(self.updateUI)# 单行编译框当按下回车时绑定自定义函数
这里就是信号与槽机制,给单行编辑框绑定操作函数。这里指定的触发条件是当按下回车时执行自定义函数,具体的组件有具体的触发机制,比如PushButton的clicked等,后面慢慢掌握。
def updateUI(self):
text = self.le.text()
try:
self.tb.append("%s = <b>%s</b>" % (text,eval(text)))# eval 计算字符串中的表达式并返回结果
except:
self.tb.append("<font color=red>%s is Invalid!</font>" %text)
首先使用self.le.text()获取单行编辑框的内容,再通过self.tb.append()把单行编辑框的内容追加在只读文本框中,"%s = %s" % (text,eval(text))这是富文本编辑,给定显示的格式等。
def keyPressEvent(self, e):# 快捷见退出程序
if e.key() == Qt.Key_Q:
self.close()
内置函数,键盘事件,这里指定当按下Q键时,程序退出。
if __name__ == "__main__":
app = QApplication([])
ec = Expression_Calculate()
ec.show()
app.exec_()
程序从这里开始,首先app = QApplication([]),窗口开始循环,接着实例化编写的ui,在通过.show()显示,app.exec_()关闭程序,它的存在使得,软件不会闪退。为什么会这样,是因为app.exec_()的含义是,最后一个窗口关闭后,程序才停止。
二、菜单栏、状态栏
1、示例
示例代码:
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QMenu
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.statusBar()# 创建状态栏
menubar = self.menuBar()# 创建菜单栏
fileMenu = menubar.addMenu('&File')# 在菜单栏添加菜单
editMenu = menubar.addMenu('&Edit')# 在菜单栏添加菜单
viewMenu = menubar.addMenu('&View')# 在菜单栏添加菜单
helpMenu = menubar.addMenu('&Help')# 在菜单栏添加菜单
#
exitAct = QAction('&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(lambda:self.close())#
fileMenu.addAction(exitAct)
# 增加其他菜单
# 增加子菜单
about = helpMenu.addMenu("&About")
self.setGeometry(300, 300, 400, 300)
self.setWindowTitle('Simple menu')
self.setWindowIcon(QIcon('ui图标.png'))
self.show()
def contextMenuEvent(self, event):
cmenu = QMenu(self)
newAct = cmenu.addAction("New")
opnAct = cmenu.addAction("Open")
quitAct = cmenu.addAction("Quit")
action = cmenu.exec_(self.mapToGlobal(event.pos()))
if action == quitAct:
self.close()
"""
mapToGlobal()方法把当前组件的相对坐标转换为窗口(window)的绝对坐标。
"""
if __name__ == '__main__':
app = QApplication([])
ex = Example()
app.exec_()
2、讲解
exitAct = QAction('&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(lambda:self.close())#
fileMenu.addAction(exitAct)
定义动作,并命名为Exit,这里& 时产生首字某下划线,然后绑定快捷键、以及绑定鼠标移动上去时状态栏提示信息,最后给动作绑定触发的函数self.close(),关闭窗口,再把动作添加到菜单栏
# 增加子菜单
about = helpMenu.addMenu("&About")
增加二级菜单,以此类推。
def contextMenuEvent(self, event):
cmenu = QMenu(self)
newAct = cmenu.addAction("New")
opnAct = cmenu.addAction("Open")
quitAct = cmenu.addAction("Quit")
action = cmenu.exec_(self.mapToGlobal(event.pos()))
if action == quitAct:
self.close()
开启右键菜单,event.pos() 获取右键点击时的相对于窗口的坐标位置,mapToGlobal()把相对于窗口的位置变成整个屏幕的坐标。这个pos的坐标和后面要讲的move()布局时的坐标一致。
图解如下:
三、工具栏
1、示例
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtGui import QIcon
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 工具栏图标,快捷键、动作绑定
exitAct = QAction(QIcon('Exit.png'), 'Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.triggered.connect(lambda:self.close())
# 运行工具栏图标、快捷键、动作绑定
editAct = QAction(QIcon('Edit.png'), 'Edit', self)
editAct.setShortcut('Ctrl+E')
# 编辑工具栏
self.toolbar = self.addToolBar('Edit')
self.toolbar.addAction(editAct)
# 退出工具栏
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAct)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Toolbar')
self.show()
if __name__ == '__main__':
app = QApplication([])
ex = Example()
app.exec_()
2、讲解
这里动作编辑和菜单栏的一样,不多做解释。
# 编辑工具栏
self.toolbar = self.addToolBar('Edit')
self.toolbar.addAction(editAct)
工具栏添加工具并绑定动作
讲解到这里,估计对PyQt算是有个大概的认识了,持续更新中…
说明的一点是我没放效果图,是希望学习的友友能自己运行查看效果,不仅可以让你印象深刻,还可以是你动手练习,可以根据自己想要的效果改动。