找回密码
 会员注册
查看: 36|回复: 0

python全系列官方中文文档,python帮助文档中文版

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
71769
发表于 2024-9-6 19:43:52 | 显示全部楼层 |阅读模式
大家好,小编来为大家解答以下问题,python全系列官方中文文档,python帮助文档中文版,现在让我们一起来看看吧!本篇文章给大家谈谈python全系列官方中文文档,以及python帮助文档中文版,希望对各位有所帮助,不要忘了收藏本站喔python三国源码。本文档来源:PyQt5中文开发文档环境安装本文环境安装于Win10,Vscode,Anaconda4.13.0。安装前请注意保持网络畅通,并且关闭VPN利用python简易的画一个雪人。condacreate-nPyQt5python=3.8condaactivatePyQt5pipinstallPyQt5安装完成后请将vscode的解释器改为此环境的解释器。所有代码的调试均用vscode 目录环境安装HelloWorld Ex1.1简单的窗口绘制执行结果Ex1.2带窗口图标执行结果Ex1.3提示框执行结果Ex1.4关闭窗口执行结果Ex1.5消息盒子 执行结果​Ex1.6窗口居中执行结果菜单和工具栏Ex2.1状态栏执行结果Ex2.2菜单栏执行结果Ex2.3子菜单执行结果 Ex2.4勾选菜单执行结果Ex2.5右键菜单执行结果Ex2.6工具栏 执行结果Ex2.7主窗口执行结果布局管理Ex3.1绝对定位执行结果Ex3.2盒布局执行结果Ex3.3栅格布局执行结果 Ex3.4制作提交反馈信息的布局执行结果事件和信号事件Ex4.1Signals&slots执行结果Ex4.2重构事件处理器 执行结果Ex4.3事件对象 执行结果Ex4.4事件发送 执行结果 Ex4.5信号发送执行结果 对话框Ex5.1输入文字执行结果Ex5.2选取颜色 执行结果Ex5.3选择字体  执行结果  Ex5.4选择文件 执行结果 控件(1) Ex6.1QCheckBox执行结果Ex6.2切换按钮 执行结果Ex6.3滑块 执行结果 Ex6.4进度条执行结果Ex6.5日历 执行结果控件(2)Ex7.1图片执行结果Ex7.2行编辑 执行结果Ex7.3QSplitter 执行结果Ex7.4下拉选框 执行结果拖拽Ex8.1简单的拖放执行结果Ex8.2拖放按钮组件 执行结果绘图Ex9.1文本涂鸦执行结果Ex9.2点的绘画 执行结果Ex9.3颜色执行结果Ex9.4QPen 执行结果Ex9.5QBrush执行结果Ex9.6贝塞尔曲线 执行结果自定义组件Ex10.1Burningwidget执行结果HelloWorld Ex1.1简单的窗口绘制 这个简单的小例子展示的是一个小窗口。但是我们可以在这个小窗口上面做很多事情,改变大小,最大化,最小化等,这需要很多代码才能实现。这在很多应用中很常见,没必要每次都要重写这部分代码,Qt已经提供了这些功能。PyQt5是一个高级的工具集合,相比使用低级的工具,能省略上百行代码。#引入PyQt5.QtWidgets模块,这个模块包含基本的组件importsysfromPyQt5.QtWidgetsimportQApplication,QWidgetif__name__=='__main__':#每个PyQt5应用都必须创建一个应用对象。是一组命令行参数的列表。使得Python脚本可以在shell里运行,这个参数提供对脚本控制的功能。app=QApplication()#QWidge控件是一个用户界面的基本控件,也被称为窗口(window)控件。w=QWidget()#resize()方法表示鼠标能改变控件的大小,这里的意思是窗口默认大小为宽250px,高150px。w.resize(250,150)#move()方法表示鼠标能改变控件的位置,这里的意思是窗口默认位置在(300,300)。注:屏幕坐标系的原点是屏幕的左上角。w.move(300,300)#给窗口添加w.setWindowTitle('Simple')#show()能让控件在桌面上显示出来w.show()#最后,我们进入了应用的主循环中,事件处理器这个时候开始工作。主循环从窗口上接收事件,并把事件派发到应用控件里。#当调用exit()方法或直接销毁主控件时,主循环就会结束。()方法能确保主循环安全退出。外部环境会收到主控件如何结束的信息。(app.exec_())执行结果Ex1.2带窗口图标窗口图标通常是显示在窗口的左上角,栏的最左边。下面的例子就是怎么用PyQt5创建一个这样的窗口。importsysfromPyQt5.QtWidgetsimportQApplication,QWidgetfromPyQt5.QtGuiimportQIcon#这个类继承自QWidgetclassExample(QWidget):def__init__(self):#继承类的初始化写法super().__init__()#使用initUI()方法创建一个GUI。self.initUI()definitUI(self):#下面的三个方法都继承自QWidget类。#setGeometry()有两个作用:把窗口放到屏幕上并且设置窗口大小。参数分别代表屏幕坐标的x、y和窗口大小的宽、高。也就是说这个方法是resize()和move()的合体。#第二个方法还是给窗口添加#最后一个方法是给窗口添加了图标。先创建一个QIcon对象,然后接受一个路径作为参数显示图标。self.setGeometry(300,300,300,220)self.setWindowTitle('Icon')self.setWindowIcon(QIcon(''))()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex1.3提示框importsysfromPyQt5.QtWidgetsimport(QWidget,QToolTip,QPushButton,QApplication)fromPyQt5.QtGuiimportQFontclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#设置了提示框的字体,我们使用了10px的SansSerif字体。QToolTip.setFont(QFont('SansSerif',10))#setTooltip()创建提示框,鼠标悬停在相应控件时会显示提示信息self.setToolTip('ThisisaQWidgetwidget')#创建一个按钮,并且为按钮添加了一个提示框btn=QPushButton('Button',self)btn.setToolTip('ThisisaQPushButtonwidget')#调整按钮大小,并让按钮在屏幕上显示出来,sizeHint()方法提供了一个默认的按钮大小。btn.resize(btn.sizeHint())(50,50)self.setGeometry(300,300,300,200)self.setWindowTitle('Tooltips')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex1.4关闭窗口关闭一个窗口最直观的方式就是点击栏的那个叉,这个例子里,我们展示的是如何用程序关闭一个窗口。这里我们将接触到一点single和slots的知识。本例使用的是QPushButton组件类。创建了一个点击之后就退出窗口的按钮。QPushButton(stringtext,QWidgetparent=None)text参数是想要显示的按钮名称,parent参数是放在按钮上的组件,在我们的例子里,这个参数是QWidget。应用中的组件都是一层一层继承而来的,在这个层里,大部分的组件都有自己的父级,没有父级的组件,是顶级的窗口。 importsysfromPyQt5.QtWidgetsimportQWidget,QPushButton,QApplicationfromPyQt5.QtCoreimportQCoreApplication#程序需要QtCore对象classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#创建一个继承自QPushButton的按钮。第一个参数是按钮的文本('Quit'),第二个参数是按钮的父级组件(按钮需要操作的组件),这个例子中,父级组件就是我们创建的继承自Qwidget的Example类。#这样就能实现Quit按钮对Example组件的操作qbtn=QPushButton('Quit',self)#事件传递系统在PyQt5内建的single和slot机制里面。#点击按钮之后,信号会被捕捉并给出既定的反应。本例是点击后,会直接链接QCore的quit方法,实现对父级组件的退出#QCoreApplication包含了事件的主循环,它能添加和删除所有的事件,instance()创建了一个它的实例。#QCoreApplication是在QApplication里创建的。点击事件和能终止进程并退出应用的quit函数绑定在了一起。在发送者和接受者之间建立了通讯,发送者就是按钮,接受者就是应用对象。qbtn.clicked.connect(QCoreApplication.instance().quit)qbtn.resize(qbtn.sizeHint())(50,50)self.setGeometry(300,300,250,150)self.setWindowTitle('Quitbutton')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex1.5消息盒子 默认情况下,我们点击栏的×按钮,QWidget就会关闭。但是有时候,我们修改默认行为。比如,如果我们打开的是一个文本编辑器,并且做了一些修改,我们就会想在关闭按钮的时候让用户进一步确认操作。importsysfromPyQt5.QtWidgetsimportQWidget,QMessageBox,QApplicationclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,250,150)self.setWindowTitle('Messagebox')()#如果关闭QWidget,就会产生一个QCloseEvent,并且把它传入到closeEvent函数的event参数中。改变控件的默认行为,就是替换掉默认的事件处理。defcloseEvent(self,event):#我们创建了一个消息框,上面有俩按钮:Yes和No.#第一个字符串显示在消息框的栏,第二个字符串显示在对话框,第三个参数是消息框的俩按钮,最后一个参数是默认按钮,这个按钮是默认选中的。返回值在变量reply里。reply=QMessageBox.question(self,'Message',"Areyousuretoquit?",|,)ifreply==:event.accept()else:event.ignore()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex1.6窗口居中importsysfromPyQt5.QtWidgetsimportQWidget,QDesktopWidget,QApplicationclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.resize(500,500)self.center()#这个方法是调用我们下面写的,实现对话框居中的方法。self.setWindowTitle('Center')()defcenter(self):#获得主窗口所在的框架qr=self.frameGeometry()#获取显示器的分辨率,然后得到屏幕中间点的位置。cp=QDesktopWidget().availableGeometry().center()#然后把主窗口框架的中心点放置到屏幕的中心位置qr.moveCenter(cp)#然后通过move函数把主窗口的左上角移动到其框架的左上角,这样就把窗口居中了。(qr.topLeft())if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果菜单和工具栏这个章节,我们会创建状态栏、菜单和工具栏。菜单是一组位于菜单栏的命令。工具栏是应用的一些常用工具按钮。状态栏显示一些状态信息,通常在应用的底部。Ex2.1状态栏状态栏是用来显示应用的状态信息的组件。importsysfromPyQt5.QtWidgetsimportQMainWindow,QApplicationclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):#调用QtGui.QMainWindow类的statusBar()方法,创建状态栏。第一次调用会创建一个状态栏,而再次调用会返回一个状态栏对象。showMessage()方法在状态栏上显示一条信息。self.statusBar().showMessage('Ready')self.setGeometry(300,300,250,150)self.setWindowTitle('Statusbar')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex2.2菜单栏菜单栏是非常常用的。是一组命令的集合(MacOS下状态栏的显示不一样,为得到最相似的外观,我们可以增加一行语句menubar.setNativeMenuBar(False))。 在下面的示例中,我们创建了只有一个命令的菜单栏,这个命令就是终止应用。同时也创建了一个状态栏。而且还能使用快捷键Ctrl+Q退出应用。importsysfromPyQt5.QtWidgetsimportQMainWindow,QAction,qApp,QApplicationfromPyQt5.QtGuiimportQIconclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):#QAction是菜单栏、工具栏或者快捷键的动作的组合。#上面三行中,前两行创建了一个图标、一个exit的标签和一个快捷键组合,都执行了一个动作;#第三行,创建了一个状态栏,当鼠标悬停在菜单栏的时候,能显示当前状态。exitAct=QAction(QIcon(''),'&Exit',self)exitAct.setShortcut('Ctrl+Q')exitAct.setStatusTip('Exitapplication')#当执行这个指定的动作时,就触发了一个事件。这个事件跟QApplication的quit()行为相关联,所以这个动作就能终止这个应用。exitAct.triggered.connect()#创建状态栏self.statusBar()#创建菜单栏#menuBar()创建菜单栏。这里创建了一个菜单栏,并用addMenu()在上面添加了一个File菜单,用addAction()关联了点击退出应用的事件。menubar=self.menuBar()fileMenu=menubar.addMenu('&File')fileMenu.addAction(exitAct)self.setGeometry(300,300,300,200)self.setWindowTitle('Simplemenu')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex2.3子菜单子菜单是嵌套在菜单里面的二级或者三级等的菜单。importsysfromPyQt5.QtWidgetsimportQMainWindow,QAction,QMenu,QApplicationclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):menubar=self.menuBar()fileMenu=menubar.addMenu('File')#使用QMenu创建一个新菜单impMenu=QMenu('Import',self)#使用addAction()添加一个动作。impAct=QAction('Importmail',self)impMenu.addAction(impAct)newAct=QAction('New',self)fileMenu.addAction(newAct)fileMenu.addMenu(impMenu)self.setGeometry(300,300,300,200)self.setWindowTitle('Submenu')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果  这个例子里,有两个子菜单,一个在File菜单下面,一个在File的Import下面。Ex2.4勾选菜单本例创建了一个行为菜单。这个行为/动作能切换状态栏显示或者隐藏。importsysfromPyQt5.QtWidgetsimportQMainWindow,QAction,QApplicationclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):self.statusbar=self.statusBar()Message('Ready')menubar=self.menuBar()viewMenu=menubar.addMenu('View')#用checkable选项创建一个能选中的菜单。viewStatAct=QAction('Viewstatusbar',self,checkable=True)viewStatAct.setStatusTip('Viewstatusbar')#默认设置为选中状态。viewStatAct.setChecked(True)viewStatAct.triggered.connect(self.toggleMenu)viewMenu.addAction(viewStatAct)self.setGeometry(300,300,300,200)self.setWindowTitle('Checkmenu')()#依据选中状态切换状态栏的显示与否deftoggleMenu(self,state):ifstate)else)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex2.5右键菜单 右键菜单也叫弹出框,是在某些场合下显示的一组命令。例如,Opera浏览器里,网页上的右键菜单里会有刷新,返回或者查看页面源代码。如果在工具栏上右键,会得到一个不同的用来管理工具栏的菜单。importsysfromPyQt5.QtWidgetsimportQMainWindow,qApp,QMenu,QApplicationclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,300,200)self.setWindowTitle('Contextmenu')()defcontextMenuEvent(self,event):cmenu=QMenu(self)#使用exec_()方法显示菜单。从鼠标右键事件对象中获得当前坐标。mapToGlobal()方法把当前组件的相对坐标转换为窗口(window)的绝对坐标。newAct=cmenu.addAction("New")opnAct=cmenu.addAction("Open")quitAct=cmenu.addAction("Quit")action=cmenu.exec_(self.mapToGlobal(()))#如果右键菜单里触发了事件,也就触发了退出事件,执行关闭菜单行为。ifaction==quitAct)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex2.6工具栏 菜单栏包含了所有的命令,工具栏就是常用的命令的集合。importsysfromPyQt5.QtWidgetsimportQMainWindow,QAction,qApp,QApplicationfromPyQt5.QtGuiimportQIconclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):#和上面的菜单栏差不多,这里使用了一个行为对象,这个对象绑定了一个标签,一个图标和一个快捷键。这些行为被触发的时候,会调用QtGui.QMainWindow的quit方法退出应用。exitAct=QAction(QIcon(''),'Exit',self)exitAct.setShortcut('Ctrl+Q')exitAct.triggered.connect()#用addToolBar()创建工具栏,并用addAction()将动作对象添加到工具栏。self.toolbar=self.addToolBar('Exit')self.toolbar.addAction(exitAct)self.setGeometry(300,300,300,200)self.setWindowTitle('Toolbar')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果创建了一个工具栏。这个工具栏只有一个退出应用的动作Ex2.7主窗口主窗口就是上面三种栏目的总称,现在我们把上面的三种栏在一个应用里展示出来。上面的代码创建了一个很经典的菜单框架,有右键菜单,工具栏和状态栏。importsysfromPyQt5.QtWidgetsimportQMainWindow,QTextEdit,QAction,QApplicationfromPyQt5.QtGuiimportQIconclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):#这里创建了一个文本编辑区域,并把它放在QMainWindow的中间区域。这个组件会占满所有剩余的区域。textEdit=QTextEdit()self.setCentralWidget(textEdit)exitAct=QAction(QIcon(''),'Exit',self)exitAct.setShortcut('Ctrl+Q')exitAct.setStatusTip('Exitapplication')exitAct.triggered.connect(self.close)self.statusBar()menubar=self.menuBar()fileMenu=menubar.addMenu('&File')fileMenu.addAction(exitAct)toolbar=self.addToolBar('Exit')toolbar.addAction(exitAct)self.setGeometry(300,300,350,250)self.setWindowTitle('Mainwindow')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果布局管理在一个GUI程序里,布局是一个很重要的方面。布局就是如何管理应用中的元素和窗口。有两种方式可以搞定:绝对定位和PyQt5的layout类 Ex3.1绝对定位每个程序都是以像素为单位区分元素的位置,衡量元素的大小。所以我们完全可以使用绝对定位搞定每个元素和窗口的位置。但是这也有局限性:元素不会随着我们更改窗口的位置和大小而变化。不能适用于不同的平台和不同分辨率的显示器更改应用字体大小会破坏布局如果我们决定重构这个应用,需要全部计算一下每个元素的位置和大小importsysfromPyQt5.QtWidgetsimportQWidget,QLabel,QApplicationclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#这个元素的左上角就在这个程序的左上角开始的(15,10)的位置。lbl1=QLabel('Zetcode',self)(15,10)lbl2=QLabel('tutorials',self)(35,40)lbl3=QLabel('forprogrammers',self)(55,70)self.setGeometry(300,300,250,150)self.setWindowTitle('Absolute')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果我们使用move()方法定位了每一个元素,使用x、y坐标。x、y坐标的原点是程序的左上角。Ex3.2盒布局使用盒布局能让程序具有更强的适应性。这个才是布局一个应用的更合适的方式。QHBoxLayout和QVBoxLayout是基本的布局类,分别是水平布局和垂直布局。如果我们需要把两个按钮放在程序的右下角,创建这样的布局,我们只需要一个水平布局加一个垂直布局的盒子就可以了。再用弹性布局增加一点间隙。importsysfromPyQt5.QtWidgetsimport(QWidget,QPushButton,QHBoxLayout,QVBoxLayout,QApplication)classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#创建了两个按钮okButton=QPushButton("OK")cancelButton=QPushButton("Cancel")#创建一个水平布局,并增加弹性空间和两个按钮。stretch函数在两个按钮前面增加了一块弹性空间,它会将按钮挤到窗口的右边hbox=QHBoxLayout()hbox.addStretch(1)hbox.addWidget(okButton)hbox.addWidget(cancelButton)#为了布局需要,我们把这个水平布局放到了一个垂直布局盒里面。弹性元素会把水平布局挤到窗口的下边。vbox=QVBoxLayout()vbox.addStretch(1)vbox.addLayout(hbox)self.setLayout(vbox)self.setGeometry(300,300,300,150)self.setWindowTitle('Buttons')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果完成了在应用的右下角放了两个按钮的需求。当改变窗口大小的时候,它们能依然保持在相对的位置。我们同时使用了QHBoxLayout和QVBoxLayout。Ex3.3栅格布局最常用的还是栅格布局了。这种布局是把窗口分为行和列。创建和使用栅格布局,需要使用QGridLayout模块。importsysfromPyQt5.QtWidgetsimport(QWidget,QGridLayout,QPushButton,QApplication)classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#创建一个QGridLayout实例,并把它放到程序窗口里grid=QGridLayout()self.setLayout(grid)#我们将要使用的按钮的名称。names=['Cls','Bck','','Close','7','8','9','/','4','5','6','*','1','2','3','-','0','.','=','+']#创建按钮位置列表positions=[(i,j)foriinrange(5)forjinrange(4)]#创建按钮,并使用addWidget()方法把按钮放到布局里面。forposition,nameinzip(positions,names):ifname=='':continuebutton=QPushButton(name)grid.addWidget(button,*position)(300,150)self.setWindowTitle('Calculator')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果 创建了栅格化的按钮。Ex3.4制作提交反馈信息的布局组件能跨列和跨行展示,这个例子里,我们就试试这个功能。importsysfromPyQt5.QtWidgetsimport(QWidget,QLabel,QLineEdit,QTextEdit,QGridLayout,QApplication)classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):title=QLabel('Title')author=QLabel('Author')review=QLabel('Review')titleEdit=QLineEdit()authorEdit=QLineEdit()reviewEdit=QTextEdit()#创建标签之间的空间grid=QGridLayout()grid.setSpacing(10)grid.addWidget(title,1,0)grid.addWidget(titleEdit,1,1)grid.addWidget(author,2,0)grid.addWidget(authorEdit,2,1)#指定组件的跨行和跨列的大小。这里我们指定这个元素跨5行显示grid.addWidget(review,3,0)grid.addWidget(reviewEdit,3,1,5,1)self.setLayout(grid)self.setGeometry(300,300,350,300)self.setWindowTitle('Review')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果我们创建了一个有三个标签的窗口。两个行编辑和一个文版编辑,这是用QGridLayout模块搞定的。事件和信号事件signalsandslots被其他人翻译成信号和槽机制,(⊙o⊙)…我这里还是不翻译好了。所有的应用都是事件驱动的。事件大部分都是由用户的行为产生的,当然也有其他的事件产生方式,比如网络的连接,窗口管理器或者定时器等。调用应用的exec_()方法时,应用会进入主循环,主循环会监听和分发事件。在事件模型中,有三个角色:事件源事件事件目标事件源就是发生了状态改变的对象。事件是这个对象状态改变的内容。事件目标是事件想作用的目标。事件源绑定事件处理函数,然后作用于事件目标身上。PyQt5处理事件方面有个signalandslot机制。Signalsandslots用于对象间的通讯。事件触发的时候,发生一个signal,slot是用来被Python调用的(相当于一个句柄?这个词也好恶心,就是相当于事件的绑定函数)slot只有在事件触发的时候才能调用。Ex4.1Signals&slotsimportsysfromPyQt5.QtCoreimportQtfromPyQt5.QtWidgetsimport(QWidget,QLCDNumber,QSlider,QVBoxLayout,QApplication)classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#QtGui.QLCDNumber和QtGui.QSlider模块lcd=QLCDNumber(self)sld=QSlider(Qt.Horizontal,self)vbox=QVBoxLayout()vbox.addWidget(lcd)vbox.addWidget(sld)self.setLayout(vbox)#这里是把滑块的变化和数字的变化绑定在一起。sld.valueChanged.connect(lcd.display)self.setGeometry(300,300,250,150)self.setWindowTitle('Signalandslot')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果下面的例子中,显示了QtGui.QLCDNumber和QtGui.QSlider模块,我们能拖动滑块让数字跟着发生改变。事件源:滑块sender事件:改变数字slot事件目标:LCD数字变化receiversender是信号的发送者,receiver是信号的接收者,slot是对这个信号应该做出的反应。Ex4.2重构事件处理器在PyQt5中,事件处理器经常被重写(也就是用自己的覆盖库自带的)importsysfromPyQt5.QtCoreimportQtfromPyQt5.QtWidgetsimportQWidget,QApplicationclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,250,150)self.setWindowTitle('Eventhandler')()#此时如果按下ESC键程序就会退出。defkeyPressEvent(self,e):ife.key()==Qt.Key_Escape:self.close()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_()) 执行结果这个例子中,我们替换了事件处理器函数keyPressEvent()此时如果按下ESC键程序就会退出。Ex4.3事件对象 事件对象是用python来描述一系列的事件自身属性的对象。importsysfromPyQt5.QtCoreimportQtfromPyQt5.QtWidgetsimportQWidget,QApplication,QGridLayout,QLabelclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):grid=QGridLayout()grid.setSpacing(10)x=0y=0#XY坐标显示在QLabel组件里="x:{0},y:{1}".format(x,y)self.label=QLabel(,self)grid.addWidget(self.label,0,0,Qt.AlignTop)#事件追踪默认没有开启,当开启后才会追踪鼠标的点击事件。self.setMouseTracking(True)self.setLayout(grid)self.setGeometry(300,300,350,200)self.setWindowTitle('Eventobject')()#e代表了事件对象。里面有我们触发事件(鼠标移动)的事件对象。x()和y()方法得到鼠标的x和y坐标点,然后拼成字符串输出到QLabel组件里。defmouseMoveEvent(self,e):x=e.x()y=e.y()text="x:{0},y:{1}".format(x,y)self.label.setText(text)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果我们在一个组件里显示鼠标的X和Y坐标Ex4.4事件发送  有时候我们会想知道是哪个组件发出了一个信号,PyQt5里的sender()方法能搞定这件事。importsysfromPyQt5.QtWidgetsimportQMainWindow,QPushButton,QApplicationclassExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):btn1=QPushButton("Button1",self)(30,50)btn2=QPushButton("Button2",self)(150,50)#两个按钮都和同一个slot绑定。btn1.clicked.connect(self.buttonClicked)btn2.clicked.connect(self.buttonClicked)self.statusBar()self.setGeometry(300,300,290,150)self.setWindowTitle('Eventsender')()#我们用调用sender()方法的方式决定了事件源。状态栏显示了被点击的按钮。defbuttonClicked(self):sender=self.sender()self.statusBar().showMessage(()+'waspressed')if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果  这个例子里有俩按钮,buttonClicked()方法决定了是哪个按钮能调用sender()方法。Ex4.5信号发送QObject实例能发送事件信号。下面的例子是发送自定义的信号importsysfromPyQt5.QtCoreimportpyqtSignal,QObjectfromPyQt5.QtWidgetsimportQMainWindow,QApplication#Communicate类创建了一个pyqtSignal()属性的信号。classCommunicate(QObject):closeApp=pyqtSignal()classExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):##closeApp信号QMainWindow的close()方法绑定self.c=Communicate()self.c.closeApp.connect(self.close)self.setGeometry(300,300,290,150)self.setWindowTitle('Emitsignal')()#点击窗口的时候,发送closeApp信号,程序终止defmousePressEvent(self,event))if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果 我们创建了一个叫closeApp的信号,这个信号会在鼠标按下的时候触发,事件与QMainWindow绑定。对话框对话框是一个现代GUI应用不可或缺的一部分。对话是两个人之间的交流,对话框就是人与电脑之间的对话。对话框用来输入数据,修改数据,修改应用设置等等。Ex5.1输入文字 QInputDialog提供了一个简单方便的对话框,可以输入字符串,数字或列表。fromPyQt5.QtWidgetsimport(QWidget,QPushButton,QLineEdit,QInputDialog,QApplication)importsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):=QPushButton('Dialog',self)(20,20).clicked.connect(Dialog)=QLineEdit(self)(130,22)self.setGeometry(300,300,290,150)self.setWindowTitle('Inputdialog')()defshowDialog(self):#这是显示一个输入框的代码。第一个参数是输入框的,第二个参数是输入框的占位符。对话框返回输入内容和一个布尔值,如果点击的是OK按钮,布尔值就返回Truetext,ok=QInputDialog.getText(self,'InputDialog','Enteryourname:')#把得到的字符串放到输入框里ifok:.setText(str(text))if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果这个示例有一个按钮和一个输入框,点击按钮显示对话框,输入的文本会显示在输入框里。 Ex5.2选取颜色 QColorDialog提供颜色的选择。fromPyQt5.QtWidgetsimport(QWidget,QPushButton,QFrame,QColorDialog,QApplication)fromPyQt5.QtGuiimportQColorimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#初始化QtGui.QFrame的背景颜色col=QColor(0,0,0)=QPushButton('Dialog',self)(20,20).clicked.connect(Dialog)=QFrame(self).setStyleSheet("QWidget{background-color:%s}"%()).setGeometry(130,22,100,100)self.setGeometry(300,300,250,180)self.setWindowTitle('Colordialog')()defshowDialog(self):#弹出一个QColorDialog对话框。col=QColorDialog.getColor()#我们可以预览颜色,如果点击取消按钮,没有颜色值返回,如果颜色是我们想要的,就从取色框里选择这个颜色。ifcol.isValid():.setStyleSheet("QWidget{background-color:%s}"%())if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果例子里有一个按钮和一个QFrame,默认的背景颜色为黑色,我们可以使用QColorDialog改变背景颜色Ex5.3选择字体  QFontDialog能做字体的选择。 fromPyQt5.QtWidgetsimport(QWidget,QVBoxLayout,QPushButton,QSizePolicy,QLabel,QFontDialog,QApplication)importsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):vbox=QVBoxLayout()btn=QPushButton('Dialog',self)btn.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)(20,20)vbox.addWidget(btn)btn.clicked.connect(Dialog)=QLabel('Knowledgeonlymatters',self)(130,20)vbox.addWidget()self.setLayout(vbox)self.setGeometry(300,300,250,180)self.setWindowTitle('Fontdialog')()defshowDialog(self):#弹出一个字体选择对话框。getFont()方法返回一个字体名称和状态信息。状态信息有OK和其他两种。font,ok=QFontDialog.getFont()#如果点击OK,标签的字体就会随之更改ifok:.setFont(font)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果  创建了一个有一个按钮和一个标签的QFontDialog的对话框,我们可以使用这个功能修改字体样式。Ex5.4选择文件 QFileDialog给用户提供文件或者文件夹选择的功能。能打开和保存文件。fromPyQt5.QtWidgetsimport(QMainWindow,QTextEdit,QAction,QFileDialog,QApplication)fromPyQt5.QtGuiimportQIconimportsys#这里设置了一个文本编辑框,文本编辑框是基于QMainWindow组件的。classExample(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):Edit=QTextEdit()self.setCentralWidget(Edit)self.statusBar()openFile=QAction(QIcon(''),'Open',self)openFile.setShortcut('Ctrl+O')openFile.setStatusTip('OpennewFile')openFile.triggered.connect(Dialog)menubar=self.menuBar()fileMenu=menubar.addMenu('&File')fileMenu.addAction(openFile)self.setGeometry(300,300,350,300)self.setWindowTitle('Filedialog')()defshowDialog(self):#弹出QFileDialog窗口。getOpenFileName()方法的第一个参数是说明文字,第二个参数是默认打开的文件夹路径。默认情况下显示所有类型的文件。fname=QFileDialog.getOpenFileName(self,'Openfile','.\\')#读取选中的文件,并显示在文本编辑框内(但是打开HTML文件时,是渲染后的结果,汗)。iffname[0]:f=open(fname[0],'r')withf:data=f.read()Edit.setText(data)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果 本例中有一个菜单栏,一个置中的文本编辑框,一个状态栏。点击菜单栏选项会弹出一个QtGui.QFileDialog对话框,在这个对话框里,你能选择文件,然后文件的内容就会显示在文本编辑框里。 控件(1) 控件就像是应用这座房子的一块块砖。PyQt5有很多的控件,比如按钮,单选框,滑动条,复选框等等。在本章,我们将介绍一些很有用的控件:QCheckBox,ToggleButton,QSlider,QProgressBar和QCalendarWidget。Ex6.1QCheckBoxQCheckBox组件有俩状态:开和关。通常跟标签一起使用,用在激活和关闭一些选项的场景。fromPyQt5.QtWidgetsimportQWidget,QCheckBox,QApplicationfromPyQt5.QtCoreimportQtimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#这个是QCheckBox的构造器cb=QCheckBox('Showtitle',self)(20,20)#要设置窗口,我们就要检查单选框的状态。默认情况下,窗口没有,单选框未选中cb.toggle()#把changeTitle()方法和stateChanged信号关联起来。这样,changeTitle()就能切换窗口了cb.stateChanged.connect(self.changeTitle)self.setGeometry(300,300,250,150)self.setWindowTitle('QCheckBox')()#控件的状态是由changeTitle()方法控制的,如果空间被选中,我们就给窗口添加一个,如果没被选中,就清空。defchangeTitle(self,state):ifstate==Qt.Checked:self.setWindowTitle('QCheckBox')else:self.setWindowTitle('')if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果这个例子中,有一个能切换窗口的单选框Ex6.2切换按钮  切换按钮就是QPushButton的一种特殊模式。它只有两种状态:按下和未按下。我们在点击的时候切换两种状态,有很多场景会使用到这个功能fromPyQt5.QtWidgetsimport(QWidget,QPushButton,QFrame,QApplication)fromPyQt5.QtGuiimportQColorimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#设置颜色为黑色=QColor(0,0,0)#创建一个QPushButton,然后调用它的setCheckable()的方法就把这个按钮编程了切换按钮redb=QPushButton('Red',self)redb.setCheckable(True)(10,10)#把点击信号和我们定义好的函数关联起来,这里是把点击事件转换成布尔值redb.clicked[bool].connect(self.setColor)greenb=QPushButton('Green',self)greenb.setCheckable(True)(10,60)greenb.clicked[bool].connect(self.setColor)blueb=QPushButton('Blue',self)blueb.setCheckable(True)(10,110)blueb.clicked[bool].connect(self.setColor)self.square=QFrame(self)self.square.setGeometry(150,20,100,100)self.square.setStyleSheet("QWidget{background-color:%s}"%())self.setGeometry(300,300,280,170)self.setWindowTitle('Togglebutton')()defsetColor(self,pressed):#获取被点击的按钮source=self.sender()ifpressed:val=255else:val=0#如果是标签为“red”的按钮被点击,就把颜色更改为预设好的对应颜色。if()=="Red":.setRed(val)elif()=="Green":.setGreen(val)else:.setBlue(val)#使用样式表(就是CSS的SS)改变背景色self.square.setStyleSheet("QFrame{background-color:%s}"%())if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果 我们创建了一个切换按钮和一个QWidget,并把QWidget的背景设置为黑色。点击不同的切换按钮,背景色会在红、绿、蓝之间切换(而且能看到颜色合成的效果,而不是单纯的颜色覆盖)Ex6.3滑块 QSlider是个有一个小滑块的组件,这个小滑块能拖着前后滑动,这个经常用于修改一些具有范围的数值,比文本框或者点击增加减少的文本框(spinbox)方便多了。本例用一个滑块和一个标签展示。标签为一个图片,滑块控制标签(的值)。先准备四个分别表示静音、小音量、中音量、大音量的图标,文件名分别叫,,,。fromPyQt5.QtWidgetsimport(QWidget,QSlider,QLabel,QApplication)fromPyQt5.QtCoreimportQtfromPyQt5.QtGuiimportQPixmapimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#创建一个水平的QSlidersld=QSlider(Qt.Horizontal,self)sld.setFocusPolicy(Qt.NoFocus)sld.setGeometry(30,40,100,30)#把valueChanged信号跟changeValue()方法关联起来sld.valueChanged[int].connect(self.changeValue)#创建一个QLabel组件并给它设置一个静音图标。self.label=QLabel(self)self.label.setPixmap(QPixmap(''))self.label.setGeometry(160,40,80,30)self.setGeometry(300,300,280,170)self.setWindowTitle('QSlider')()defchangeValue(self,value):#根据音量值的大小更换标签位置的图片。这段代码是:如果音量为0,就把图片换成ifvalue==0:self.label.setPixmap(QPixmap(''))elifvalue>0andvalue30andvalue=100).setText('Finished')return=+1.setValue()#里面的doAction()方法是用来控制开始和停止的。defdoAction(self):ifself.timer.isActive()).setText('Start')else:#调用start()方法加载一个时间事件。这个方法有两个参数:过期时间和事件接收者。self.timer.start(100,self).setText('Stop')if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex6.5日历 QCalendarWidget提供了基于月份的日历插件,十分简易而且直观。 fromPyQt5.QtWidgetsimport(QWidget,QCalendarWidget,QLabel,QApplication,QVBoxLayout)fromPyQt5.QtCoreimportQDateimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):vbox=QVBoxLayout(self)#创建一个QCalendarWidgetcal=QCalendarWidget(self)cal.setGridVisible(True)#选择一个日期时,QDate的点击信号就触发了,把这个信号和我们自己定义的showDate()方法关联起来。cal.clicked[QDate].connect(Date)vbox.addWidget(cal)=QLabel(self)date=cal.selectedDate().setText(date.toString())vbox.addWidget()self.setLayout(vbox)self.setGeometry(300,300,350,300)self.setWindowTitle('Calendar')()defshowDate(self,date):#使用selectedDate()方法获取选中的日期,然后把日期对象转成字符串,在标签里面显示出来。.setText(date.toString())if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果这个例子有日期组件和标签组件组成,标签显示被选中的日期。控件(2)本章我们继续介绍PyQt5控件。这次的有QPixmap,QLineEdit,QSplitter,和QComboBox。Ex7.1图片QPixmap是处理图片的组件。本例中,我们使用QPixmap在窗口里显示一张图片。fromPyQt5.QtWidgetsimport(QWidget,QHBoxLayout,QLabel,QApplication)fromPyQt5.QtGuiimportQPixmapimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):hbox=QHBoxLayout(self)#创建一个QPixmap对象,接收一个文件作为参数。pixmap=QPixmap("")#把QPixmap实例放到QLabel组件里。lbl=QLabel(self)lbl.setPixmap(pixmap)hbox.addWidget(lbl)self.setLayout(hbox)(300,200)self.setWindowTitle('RedRock')()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果Ex7.2行编辑 QLineEdit组件提供了编辑文本的功能,自带了撤销、重做、剪切、粘贴、拖拽等功能。importsysfromPyQt5.QtWidgetsimport(QWidget,QLabel,QLineEdit,QApplication)classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):=QLabel(self)#创建一个QLineEdit对象。qle=QLineEdit(self)(60,100)(60,40)##如果输入框的值有变化,就调用onChanged()方法qle.textChanged[str].connect(self.onChanged)self.setGeometry(300,300,280,170)self.setWindowTitle('QLineEdit')()#在onChanged()方法内部,我们把文本框里的值赋值给了标签组件,然后调用adjustSize()方法让标签自适应文本内容。defonChanged(self,text):.setText(text).adjustSize()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果例子中展示了一个编辑组件和一个标签,我们在输入框里键入的文本,会立即在标签里显示出来。Ex7.3QSplitter QSplitter组件能让用户通过拖拽分割线的方式改变子窗口大小的组件。本例中我们展示用两个分割线隔开的三个QFrame组件。fromPyQt5.QtWidgetsimport(QWidget,QHBoxLayout,QFrame,QSplitter,QStyleFactory,QApplication)fromPyQt5.QtCoreimportQtimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):hbox=QHBoxLayout(self)#为了更清楚的看到分割线,我们使用了设置好的子窗口样式。topleft=QFrame(self)topleft.setFrameShape(QFrame.StyledPanel)topright=QFrame(self)topright.setFrameShape(QFrame.StyledPanel)bottom=QFrame(self)bottom.setFrameShape(QFrame.StyledPanel)#创建一个QSplitter组件,并在里面添加了两个框架。splitter1=QSplitter(Qt.Horizontal)splitter1.addWidget(topleft)splitter1.addWidget(topright)#也可以在分割线里面再进行分割。splitter2=QSplitter(Qt.Vertical)splitter2.addWidget(splitter1)splitter2.addWidget(bottom)hbox.addWidget(splitter2)self.setLayout(hbox)self.setGeometry(300,300,300,200)self.setWindowTitle('QSplitter')()defonChanged(self,text):.setText(text).adjustSize()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果三个窗口和两个分割线的布局创建完成了,但是要注意,有些主题下,分割线的显示效果不太好。Ex7.4下拉选框  QComboBox组件能让用户在多个选择项中选择一个。fromPyQt5.QtWidgetsimport(QWidget,QLabel,QComboBox,QApplication)importsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):=QLabel("Ubuntu",self)#创建一个QComboBox组件和五个选项。combo=QComboBox(self)combo.addItem("Ubuntu")combo.addItem("Mandriva")combo.addItem("Fedora")combo.addItem("Arch")combo.addItem("Gentoo")(50,50)(50,150)#在选中的条目上调用onActivated()方法。combo.activated[str].connect(self.onActivated)self.setGeometry(300,300,300,200)self.setWindowTitle('QComboBox')()#在方法内部,设置标签内容为选定的字符串,然后设置自适应文本大小。defonActivated(self,text):.setText(text).adjustSize()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果本例包含了一个QComboBox和一个QLabel。下拉选择框有五个选项,都是Linux的发行版名称,标签内容为选定的发行版名称。拖拽在GUI里,拖放是指用户点击一个虚拟的对象,拖动,然后放置到另外一个对象上面的动作。一般情况下,需要调用很多动作和方法,创建很多变量。拖放能让用户很直观的操作很复杂的逻辑。一般情况下,我们可以拖放两种东西:数据和图形界面。把一个图像从一个应用拖放到另外一个应用上的实质是操作二进制数据。把一个表格从Firefox上拖放到另外一个位置的实质是操作一个图形组。Ex8.1简单的拖放本例使用了QLineEdit和QPushButton。把一个文本从编辑框里拖到按钮上,更新按钮上的标签(文字)。fromPyQt5.QtWidgetsimport(QPushButton,QWidget,QLineEdit,QApplication)importsys#为了完成预定目标,我们要重构一些方法。首先用QPushButton上构造一个按钮实例。classButton(QPushButton):def__init__(self,title,parent):super().__init__(title,parent)#激活组件的拖拽事件self.setAcceptDrops(True)defdragEnterEvent(self,e):#首先,我们重构了dragEnterEvent()方法。设定好接受拖拽的数据类型(plaintext)ife.mimeData().hasFormat('text/plain'):e.accept()else:e.ignore()#然后重构dropEvent()方法,更改按钮接受鼠标的释放事件的默认行为defdropEvent(self,e):self.setText(e.mimeData().text())classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#QLineEdit默认支持拖拽操作,所以我们只要调用setDragEnabled()方法使用就行了。edit=QLineEdit('',self)edit.setDragEnabled(True)(30,65)button=Button("Button",self)(190,65)self.setWindowTitle('Simpledraganddrop')self.setGeometry(300,300,300,150)if__name__=='__main__':app=QApplication()ex=Example()()app.exec_()执行结果Ex8.2拖放按钮组件 这个例子展示怎么拖放一个button组件。 fromPyQt5.QtWidgetsimportQPushButton,QWidget,QApplicationfromPyQt5.QtCoreimportQt,QMimeDatafromPyQt5.QtGuiimportQDragimportsys#从QPushButton继承一个Button类,然后重构QPushButton的两个方法:mouseMoveEvent()和mousePressEvent().mouseMoveEvent()是拖拽开始的事件。classButton(QPushButton):def__init__(self,title,parent):super().__init__(title,parent)defmouseMoveEvent(self,e):#我们只劫持按钮的右键事件,左键的操作还是默认行为。ife.buttons()!=Qt.RightButton:return#创建一个QDrag对象,用来传输MIME-based数据。mimeData=QMimeData()drag=QDrag(self)drag.setMimeData(mimeData)drag.setHotSpot(e.pos()-().topLeft())#拖放事件开始时,用到的处理函数式start().dropAction=drag.exec_(Qt.MoveAction)#左键点击按钮,会在控制台输出“press”。注意,我们在父级上也调用了mousePressEvent()方法,不然的话,我们是看不到按钮按下的效果的。defmousePressEvent(self,e):super().mousePressEvent(e)ife.button()==Qt.LeftButton:print('press')classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setAcceptDrops(True)self.button=Button('Button',self)(100,65)self.setWindowTitle('ClickorMove')self.setGeometry(300,300,280,150)defdragEnterEvent(self,e):e.accept()defdropEvent(self,e):#在dropEvent()方法里,我们定义了按钮按下后和释放后的行为,获得鼠标移动的位置,然后把按钮放到这个地方。position=e.pos()(position)#指定放下的动作类型为moveAction。e.setDropAction(Qt.MoveAction)e.accept()if__name__=='__main__':app=QApplication()ex=Example()()app.exec_()执行结果上面的例子中,窗口上有一个QPushButton组件。左键点击按钮,控制台就会输出press。右键可以点击然后拖动按钮绘图PyQt5绘图系统能渲染矢量图像、位图图像和轮廓字体文本。一般会使用在修改或者提高现有组件的功能,或者创建自己的组件。使用PyQt5的绘图API进行操作。绘图由paintEvent()方法完成,绘图的代码要放在QPainter对象的begin()和end()方法之间。是低级接口。Ex9.1文本涂鸦我们从画一些Unicode文本开始。importsysfromPyQt5.QtWidgetsimportQWidget,QApplicationfromPyQt5.QtGuiimportQPainter,QColor,QFontfromPyQt5.QtCoreimportQtclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):="ЛевНиколаевичТолстой\nАннаКаренина"self.setGeometry(300,300,280,170)self.setWindowTitle('Drawingtext')()#在绘画事件内完成绘画动作defpaintEvent(self,event):#QPainter是低级的绘画类。所有的绘画动作都在这个类的begin()和end()方法之间完成,绘画动作都封装在drawText()内部了qp=QPainter()qp.begin(self)self.drawText(event,qp)()defdrawText(self,event,qp):#为文字绘画定义了笔和字体。qp.setPen(QColor(168,34,3))qp.setFont(QFont('Decorative',10))#drawText()方法在窗口里绘制文本,rect()方法返回要更新的矩形区域。qp.drawText((),Qt.AlignCenter,)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果 写了一些文本上下居中对齐的俄罗斯Cylliric语言的文字Ex9.2点的绘画 点是最简单的绘画了。fromPyQt5.QtWidgetsimportQWidget,QApplicationfromPyQt5.QtGuiimportQPainterfromPyQt5.QtCoreimportQtimportsys,randomclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,300,190)self.setWindowTitle('Points')()defpaintEvent(self,e):qp=QPainter()qp.begin(self)self.drawPoints(qp)()defdrawPoints(self,qp):#设置笔的颜色为红色,使用的是预定义好的颜色。qp.setPen()#每次更改窗口大小,都会产生绘画事件,从size()方法里获得当前窗口的大小,然后把产生的点随机的分配到窗口的所有位置上。size=()foriinrange(1000):x=random.randint(1,size.width()-1)y=random.randint(1,size.height()-1)#drawPoint()方法绘图。qp.drawPoint(x,y)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果我们在窗口里随机的画出了1000个点。Ex9.3颜色颜色是一个物体显示的RGB的混合色。RBG值的范围是0255。我们有很多方式去定义一个颜色,最常见的方式就是RGB和16进制表示法,也可以使用RGBA,增加了一个透明度的选项,透明度值的范围是01,0代表完全透明。fromPyQt5.QtWidgetsimportQWidget,QApplicationfromPyQt5.QtGuiimportQPainter,QColor,QBrushimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,350,100)self.setWindowTitle('Colours')()defpaintEvent(self,e):qp=QPainter()qp.begin(self)self.drawRectangles(qp)()defdrawRectangles(self,qp):#使用16进制的方式定义一个颜色。col=QColor(0,0,0)col.setNamedColor('#d4d4d4')qp.setPen(col)#定义了一个笔刷,并画出了一个矩形。笔刷是用来画一个物体的背景。drawRect()有四个参数,分别是矩形的x、y、w、h。然后用笔刷和矩形进行绘画。qp.setBrush(QColor(200,0,0))qp.drawRect(10,15,90,60)qp.setBrush(QColor(255,80,0,160))qp.drawRect(130,15,90,60)qp.setBrush(QColor(25,0,90,200))qp.drawRect(250,15,90,60)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果我们画出了三个颜色的矩形。Ex9.4QPen QPen是基本的绘画对象,能用来画直线、曲线、矩形框、椭圆、多边形和其他形状。fromPyQt5.QtWidgetsimportQWidget,QApplicationfromPyQt5.QtGuiimportQPainter,QPenfromPyQt5.QtCoreimportQtimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,280,270)self.setWindowTitle('Penstyles')()defpaintEvent(self,e):qp=QPainter()qp.begin(self)self.drawLines(qp)()defdrawLines(self,qp):#新建一个QPen对象,设置颜色黑色,宽2像素,这样就能看出来各个笔样式的区别。Qt.SolidLine是预定义样式的一种。pen=QPen(Qt.black,2,Qt.SolidLine)qp.setPen(pen)qp.drawLine(20,40,250,40)#这里我们自定义了一个笔的样式。#定义为Qt.CustomDashLine然后调用setDashPattern()方法。#数字列表是线的样式,要求必须是个数为奇数,奇数位定义的是空格,偶数位为线长,数字越大,空格或线长越大,比如本例的就是1像素线,4像素空格,5像素线,4像素空格。pen.setStyle(Qt.DashLine)qp.setPen(pen)qp.drawLine(20,80,250,80)pen.setStyle(Qt.DashDotLine)qp.setPen(pen)qp.drawLine(20,120,250,120)pen.setStyle(Qt.DotLine)qp.setPen(pen)qp.drawLine(20,160,250,160)pen.setStyle(Qt.DashDotDotLine)qp.setPen(pen)qp.drawLine(20,200,250,200)pen.setStyle(Qt.CustomDashLine)pen.setDashPattern([1,4,5,4])qp.setPen(pen)qp.drawLine(20,240,250,240)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果在这个例子里,我们用不同的笔画了6条直线。PyQt5有五个预定义的笔,另外一个笔的样式使我们自定义的。Ex9.5QBrushQBrush也是图像的一个基本元素。是用来填充一些物体的背景图用的,比如矩形,椭圆,多边形等。有三种类型:预定义、渐变和纹理。fromPyQt5.QtWidgetsimportQWidget,QApplicationfromPyQt5.QtGuiimportQPainter,QBrushfromPyQt5.QtCoreimportQtimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,355,280)self.setWindowTitle('Brushes')()defpaintEvent(self,e):qp=QPainter()qp.begin(self)self.drawBrushes(qp)()defdrawBrushes(self,qp):#创建了一个笔刷对象,添加笔刷样式,然后调用drawRect()方法画图。brush=QBrush(Qt.SolidPattern)qp.setBrush(brush)qp.drawRect(10,15,90,60)brush.setStyle(Qt.Dense1Pattern)qp.setBrush(brush)qp.drawRect(130,15,90,60)brush.setStyle(Qt.Dense2Pattern)qp.setBrush(brush)qp.drawRect(250,15,90,60)brush.setStyle(Qt.DiagCrossPattern)qp.setBrush(brush)qp.drawRect(10,105,90,60)brush.setStyle(Qt.Dense5Pattern)qp.setBrush(brush)qp.drawRect(130,105,90,60)brush.setStyle(Qt.Dense6Pattern)qp.setBrush(brush)qp.drawRect(250,105,90,60)brush.setStyle(Qt.HorPattern)qp.setBrush(brush)qp.drawRect(10,195,90,60)brush.setStyle(Qt.VerPattern)qp.setBrush(brush)qp.drawRect(130,195,90,60)brush.setStyle(Qt.BDiagPattern)qp.setBrush(brush)qp.drawRect(250,195,90,60)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果我们画了9个不同的矩形。Ex9.6贝塞尔曲线 可以使用PyQt5的QPainterPath创建贝塞尔曲线。绘画路径是由许多构建图形的对象,具体表现就是一些线的形状,比如矩形,椭圆,线和曲线。fromPyQt5.QtWidgetsimportQWidget,QApplicationfromPyQt5.QtGuiimportQPainter,QPainterPathfromPyQt5.QtCoreimportQtimportsysclassExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setGeometry(300,300,380,250)self.setWindowTitle('Béziercurve')()defpaintEvent(self,e):qp=QPainter()qp.begin(self)qp.setRenderHint(QPainter.Antialiasing)self.drawBezierCurve(qp)()defdrawBezierCurve(self,qp):#用QPainterPath路径创建贝塞尔曲线。使用cubicTo()方法生成,分别需要三个点:起始点,控制点和终止点。path=QPainterPath()path.moveTo(30,30)path.cubicTo(30,30,200,350,350,30)#drawPath()绘制最后的图像。qp.drawPath(path)if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果这个示例中,我们画出了一个贝塞尔曲线。自定义组件PyQt5有丰富的组件,但是肯定满足不了所有开发者的所有需求,PyQt5只提供了基本的组件,像按钮,文本,滑块等。如果你还需要其他的模块,应该尝试自己去自定义一些。自定义组件使用绘画工具创建,有两个基本方式:根据已有的创建或改进;通过自己绘图创建。Ex10.1Burningwidget这个组件我们会在Nero,K3B,或者其他CD/DVD烧录软件中见到。fromPyQt5.QtWidgetsimport(QWidget,QSlider,QApplication,QHBoxLayout,QVBoxLayout)fromPyQt5.QtCoreimportQObject,Qt,pyqtSignalfromPyQt5.QtGuiimportQPainter,QFont,QColor,QPenimportsysclassCommunicate(QObject):updateBW=pyqtSignal(int)#基于QWidget组件。classBurningWidget(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):#修改组件进度条的高度,默认的有点小。self.setMinimumSize(1,30)self.value=75=[75,150,225,300,375,450,525,600,675]defsetValue(self,value):self.value=valuedefpaintEvent(self,e):qp=QPainter()qp.begin(self)self.drawWidget(qp)()defdrawWidget(self,qp):MAX_CAPACITY=700OVER_CAPACITY=750#使用比默认更小一点的字体,这样更配。font=QFont('Serif',7,QFont.Light)qp.setFont(font)#动态的渲染组件,随着窗口的大小而变化,#这就是我们计算窗口大小的原因。最后一个参数决定了组件的最大范围,进度条的值是由窗口大小按比例计算出来的。#最大值的地方填充的是红色。注意这里使用的是浮点数,能提高计算和渲染的精度。#绘画由三部分组成,黄色或红色区域和黄色矩形,然后是分割线,最后是添上代表容量的数字。size=()w=size.width()h=size.height()step=int(round(w/10))till=int(((w/OVER_CAPACITY)*self.value))full=int(((w/OVER_CAPACITY)*MAX_CAPACITY))ifself.value>=MAX_CAPACITY:qp.setPen(QColor(255,255,255))qp.setBrush(QColor(255,255,184))qp.drawRect(0,0,full,h)qp.setPen(QColor(255,175,175))qp.setBrush(QColor(255,175,175))qp.drawRect(full,0,till-full,h)else:qp.setPen(QColor(255,255,255))qp.setBrush(QColor(255,255,184))qp.drawRect(0,0,till,h)pen=QPen(QColor(20,20,20),1,Qt.SolidLine)qp.setPen(pen)qp.setBrush(Qt.NoBrush)qp.drawRect(0,0,w-1,h-1)j=0foriinrange(step,10*step,step):qp.drawLine(i,0,i,5)#这里使用字体去渲染文本。必须要知道文本的宽度,这样才能让文本的中间点正好落在竖线上。metrics=qp.fontMetrics()fw=metrics.width(str([j]))qp.drawText(i-fw/2,h/2,str([j]))j=j+1classExample(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):OVER_CAPACITY=750sld=QSlider(Qt.Horizontal,self)sld.setFocusPolicy(Qt.NoFocus)sld.setRange(1,OVER_CAPACITY)sld.setValue(75)sld.setGeometry(30,40,150,30)self.c=Communicate()=BurningWidget()self.c.updateBW[int].connect(.setValue)sld.valueChanged[int].connect(self.changeValue)hbox=QHBoxLayout()hbox.addWidget()vbox=QVBoxLayout()vbox.addStretch(1)vbox.addLayout(hbox)self.setLayout(vbox)self.setGeometry(300,300,390,210)self.setWindowTitle('Burningwidget')()#拖动滑块的时候,调用了changeValue()方法。这个方法内部,我们自定义了一个可以传参的updateBW信号。#参数就是滑块的当前位置。这个数值之后还用来于Burning组件,然后重新渲染Burning组件。defchangeValue(self,value)value).repaint()if__name__=='__main__':app=QApplication()ex=Example()(app.exec_())执行结果  本例中,我们使用了QSlider和一个自定义组件,由进度条控制。显示的有物体(也就是CD/DVD)的总容量和剩余容量。进度条的范围是1~750。如果值达到了700(OVER_CAPACITY),就显示为红色,代表了烧毁了的意思。烧录组件在窗口的底部,这个组件是用QHBoxLayout和QVBoxLayout组成的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 13:52 , Processed in 0.991490 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表