写点什么

Python Qt GUI 设计:QMainWindow、QWidget 和 QDialog 窗口类(基础篇—10)

  • 2021 年 11 月 18 日
  • 本文字数:7034 字

    阅读完需:约 23 分钟

Python Qt GUI设计:QMainWindow、QWidget和QDialog窗口类(基础篇—10)

QMainWindow、QWidget 和 QDialog 三个类都是用来创建窗口的,可以直接使用,也可以继承后再使用,在 Qt Designer 创建 UI 文件可以选择这三种窗口类型。

如果是主窗口,就使用 QMainWindow 类,如果是对话框,就使用 QDialog 类,如果不确定,或者有可能作为顶层窗口,也有可能嵌入到其他窗口中,那么就使用 QWidget 类。

让我们看看具体区别吧~

1、 QMainWindow 窗口

QMainWindow 主窗口为用户提供一个应用程序框架,它有自己的布局,可以在布局中添加控件。在主窗口中可以添加控件,比如将工具栏、菜单栏和状态栏等添加到布局管理器中。

QMainWindow 类中比较重要的方法如下表所示:

QMainWindow 有自己的布局不能设置布局(使用 setLayout()方法)。

聊一个实用功能,当主窗口打开运行后,实现默认电脑屏幕居中,效果如下所示:

实现代码如下所示:

 from PyQt5.QtWidgets import QDesktopWidget, QApplication ,QMainWindowimport sys      class Winform( QMainWindow):         def __init__(self, parent=None):        super( Winform, self).__init__(parent)                  self.setWindowTitle('主窗口放在屏幕中间例子')          self.resize(370,  250)          self.center()                def center(self):          screen = QDesktopWidget().screenGeometry()          size = self.geometry()                self.move((screen.width() - size.width()) / 2,  (screen.height() - size.height()) / 2)    if __name__ == "__main__":     app = QApplication(sys.argv)       win = Winform()      win.show()      sys.exit(app.exec_())  
复制代码

以下语句用来设置 QWidget 窗口的大小,宽度为 370 像素,高度为 250 像素。

self.resize(370,  250)  
复制代码

以下语句用来计算显示屏幕的大小:(screen.width()*screen.height()),其中 QDesktopWidget 是描述显示屏幕的类,通过 QDesktopWidget().screenGeometry()来获得屏幕的大小。

screen = QDesktopWidget().screenGeometry()
复制代码

以下语句用来获取 QWidget 窗口的大小:(size.width()*size.heiget())。

size = self.geometry() 
复制代码

以下语句将窗口移动到屏幕中间。

self.move((screen.width() - size.width()) / 2,  (screen.height() - size.height()) / 2)  
复制代码

2、QWidget 窗口

基础窗口控件 QWidget 类是所有用户界面对象的基类,所有的窗口和控件都直接或间接继承自 QWidget 类。

窗口控件(Widget,简称“控件”)是在 PyQt 中建立界面的主要元素。在 PyQt 中把没有嵌入到其他控件中的控件称为窗口,一般窗口都有边框、标题栏。窗口是指程序的整体界面,可以包含标题栏、菜单栏、工具栏、关闭按钮、最小化按钮、最大化按钮等;控件是指按钮、复选框、文本框、表格、进度条等这些组成程序的基本元素。一个程序可以有多个窗口,一个窗口也可以有多个控件。

在 Qt 官方提供的帮助文档中:“Qt 5.14 Qt Widgets Window and Dialog Widgets”,可见 QWidget 几何结构如下所示:

从上图可以看出,这些成员函数分为三类:

  • QWidget 直接提供的成员函数: x()、y()获得窗口左上角的坐标,width()、 height()获得客户区的宽度和高度;

  • QWidget 的 geometry()提供的成员函数:x()、y()获得客户区左上角的坐标,width()、 height()获得客户区的宽度和高度;

  • Widget 的 frameGeometry()提供的成员函数:x()、y()获得窗口左上角的坐标,width()、 height()获得包含客户区、标题栏和边框在内的整个窗口的宽度和高度。

而且可以知道 QWidget 有两种常用的几何结构:

  • 不包含外边各种边框的几何结构;

  • 包含外边各种边框的几何结构。

1、QWidget 不包含边框的常用函数

一般情况下,不包含边框的部分是客户区,这里面就是我们正常操作的地方,可以添加子控件。这部分是一个长方形,会有大小和位置。大小就是指宽度(width)和高度(height);位置就是指这个长方形在屏幕上的位置。在 Qt 中保存这个长方形使用的是 QRect 类,这个类也有自己的大小和位置。要改变其大小和位置,可以使用如下几个函数:

  • 改变客户区的面积

以下两个函数改变了长方形的大小,其中第一个参数是宽度,第二个参数是高度。设置了大小的窗口,还可以用鼠标来改变它的大小。

QWidget.resize(width,height) QWidget.resize(QSize)
复制代码
  • 获得客户区的大小

Qwidget.size()
复制代码
  • 获得客户区的宽度和高度

QWidget.width() QWidget.height()
复制代码
  • 设置客户区的宽度和高度

使用这个函数,客户区的高度就是固定的,不可以改变,只可以改变宽度。

QWidget.setFixedWidth(int width)
复制代码

这时候宽度就是固定的,不可以改变,但是可以改变高度。

QWidget.setFixedHeight(int height)
复制代码

以下这两个函数,高度和宽度都是固定的,不可以通过鼠标来改变窗口的宽度和高度。

QWidget.setFixedSize(QSize size) QWidget.setFixedSize(int width,int height)
复制代码

如果要同时改变客户区的大小和位置,需要用到以下函数。

QWidget.setGeometry(int x, int y,int width,int height) Widget.setGeometry(QRect rect)
复制代码

x 和 y 对应的就是 x 和 y 坐标,也可以不单独设置 x 和 y 坐标。

2、QWidget 包含边框的常用函数

QWidget 包含边框,这个边框有大小和位置,是窗口在屏幕上显示的整个区域。

这里没有设置这个边框大小的函数,因为通过上面不包含边框函数的设置,就可以设置包含边框的大小了。通过下面的函数,可以获得整个窗口的位置和大小。

  • 获得窗口的大小和位置

QWidget.frameGeometry()
复制代码
  • 设置窗口的位置

QWidget.move(int x,int y) QWidget.move(QPoint point)
复制代码
  • 获得窗口左上角的坐标

QWidget.pos()
复制代码

最后将上述函数 API 整合成一个示例,获取 QWidget 控件在屏幕上的坐标,效果如下所示:

实现代码如下所示:

from PyQt5.QtWidgets import QApplication  ,QWidget  ,QPushButtonimport sys                app = QApplication(sys.argv)widget = QWidget()btn = QPushButton( widget )btn.setText("Button")#以QWidget左上角为(0, 0)点btn.move(20, 20)   #不同操作系统可能对窗口最小宽度有规定,若设置宽度小于规定值,则会以规定值进行显示widget.resize(300, 200) #以屏幕左上角为(0, 0)点widget.move(250, 200) widget.setWindowTitle('PyQt坐标系统例子')widget.show()print("#1 QWidget")print("widget.x()=%d" % widget.x() )print("widget.y()=%d" % widget.y() )print("widget.width()=%d" % widget.width() )print("widget.height()=%d" % widget.height() ) print("#2 QWidget.geometry")print("widget.geometry().x()=%d" %  widget.geometry().x() )print("widget.geometry().y()=%d" %  widget.geometry().y() )print("widget.geometry().width()=%d" %  widget.geometry().width() )print("widget.geometry().height()=%d" %  widget.geometry().height() )print("widget.size().width() =%d" %  widget.size().width() )print("widget.size().height() =%d" %  widget.size().height() ) print("#3 QWidget.frameGeometry")print("widget.frameGeometry().width()=%d" %  widget.frameGeometry().width() )print("widget.frameGeometry().height()=%d" %  widget.frameGeometry().height() )print("widget.pos().x()=%d" %  widget.pos().x() )print("widget.pos().y()=%d" %  widget.pos().y() ) sys.exit(app.exec_())  
复制代码

3、QDialog 窗口

为了更好地实现人机交互,比如 Windows 及 Linux 等系统均会提供一系列的标准对话框来完成特定场景下的功能,如选择字号大小、字体颜色等。在 PyQt 5 中定义了一系列的标准对话框类,让使用者能够方便和快捷地通过各个类完成字号大小、字体颜色以及文件的选择等。

QDialog 是对话框窗口的基类,对话框主要用来执行短期任务,或者与用户进行互动,它可以是模态的,也可以是非模态的。QDialog 窗口没有菜单栏、工具栏、状态栏等。

QDialog 类中的常用方法如下表所示:

来看一个 QDialog 窗口的例子,在这个例子中,Dialog 窗口的 WindowModality 属性决定是否为模态或非模态。单击 QWidget 窗口中的 PushButton 按钮时,将生成一个对话框窗口。在对话框窗口的标题栏上没有最小化和最大化控件。代码中将给按钮的 clicked 信号添加槽函数 showdialog()。当用户按下 Esc 键时,对话框窗口将会默认调用 QDialog.reject()方法,然后关闭对话框窗口。效果如下所示:

实现代码如下所示:

 import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import * class DialogDemo( QMainWindow ): 	def __init__(self, parent=None):		super(DialogDemo, self).__init__(parent) 				self.setWindowTitle("Dialog 例子")		self.resize(350,300)    		self.btn = QPushButton( self)		self.btn.setText("弹出对话框")  		self.btn.move(50,50)				self.btn.clicked.connect(self.showdialog)                  	def showdialog(self ):		dialog = QDialog()		btn = QPushButton("ok", dialog )		btn.move(50,50)		dialog.setWindowTitle("Dialog")		dialog.setWindowModality(Qt.ApplicationModal)		dialog.exec_() if __name__ == '__main__':	app = QApplication(sys.argv)	demo = DialogDemo()	demo.show()	sys.exit(app.exec_())
复制代码

QDialog 类的子类主要有 QMessageBox、QlnputDialog、QFontDialog、QFileDialog 等。来看看它们的特性吧~

3.1、QMessageBox 窗口

QMessageBox 是一种通用的弹出式对话框,用于显示消息,允许用户通过单击不同的标准按钮对消息进行反馈。每个标准按钮都有一个预定义的文本、角色和十六进制数。

QMessageBox 类提供了许多常用的弹出式对话框,如提示、警告、错误、询问、关于等对话框。这些不同类型的 QMessageBox 对话框只是显示时的图标不同,其他功能是—样的。

QMessageBox 类中的常用方法如下表所示:

QMessageBox 的标准按钮类型如下表所示:

5 种常用的消息对话框及其显示效果如下表所示:

以下示例就是 QMessageBox 的典型应用,效果如下所示:

实现代码如下所示:

 import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import * class WinForm( QWidget):  	def __init__(self):  		super(WinForm,self).__init__()  		self.setWindowTitle("QMessageBox 例子")  		self.resize(300, 100)              		self.myButton = QPushButton(self)    		self.myButton.setText("点击弹出消息框")  		self.myButton.clicked.connect(self.msg)   	def msg(self):          # 使用infomation信息框  		reply = QMessageBox.information(self, "标题", "对话框消息正文", QMessageBox.Yes | QMessageBox.No ,  QMessageBox.Yes )  		print( reply )		if __name__ == '__main__':	app= QApplication(sys.argv)    	demo = WinForm()  	demo.show() 	sys.exit(app.exec_())
复制代码

3.2、QInputDialog 窗口

QInputDialog 控件是一个标准对话框,由一个文本框和两个按钮(OK 按钮和 Cancel 按钮)组成。当用户单击 OK 按钮或按 Enter 键后,在父窗口可以收集通过 QInputDialog 控件输入的信息。

QInputDialog 控件是 QDialog 标准对话框的一部分,在 QlnputDialog 控件中可以输入数字、字符串或列表中的选项,标签用于提示必要的信息。

QlnputDialog 类中的常用方法如下表所示:

以下示例就是 QFileDialog 的典型应用,效果如下所示:




实现代码如下所示:

 import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import * class InputdialogDemo(QWidget):	def __init__(self, parent=None):		super(InputdialogDemo, self).__init__(parent)		layout = QFormLayout()		self.btn1 = QPushButton("获得列表里的选项")		self.btn1.clicked.connect(self.getItem)		self.le1 = QLineEdit()		layout.addRow(self.btn1,self.le1) 		self.btn2 = QPushButton("获得字符串")		self.btn2.clicked.connect(self.getIext)		self.le2 = QLineEdit()		layout.addRow(self.btn2,self.le2) 		self.btn3 = QPushButton("获得整数")		self.btn3.clicked.connect(self.getInt)		self.le3 = QLineEdit()		layout.addRow(self.btn3,self.le3)		self.setLayout(layout)		self.setWindowTitle("Input Dialog 例子")			def getItem(self):		items = ("C", "C++", "Java", "Python")		item, ok = QInputDialog.getItem(self, "select input dialog",		"语言列表", items, 0, False)		if ok and item:			self.le1.setText(item)		def getIext(self):			text, ok = QInputDialog.getText(self, 'Text Input Dialog', '输入姓名:')		if ok:			self.le2.setText(str(text))  	def getInt(self):		num,ok = QInputDialog.getInt(self,"integer input dualog","输入数字")		if ok:			self.le3.setText(str(num))					if __name__ == '__main__':	app = QApplication(sys.argv)	demo = InputdialogDemo()	demo.show()	sys.exit(app.exec_())
复制代码

3.3、QFontDialog 窗口

FontDialog 控件是一个常用的字体选择对话框,可以让用户选择所显示文本的字号大小、样式和格式。

QFontDialog 是 QDialog 标准对话框的一部分,使用 QFontDialog 类的静态方法 getFont(),可以从字体选择对话框中选择文本的显示字号大小、样式和格式。

以下示例就是 QFontDialog 的典型应用,效果如下所示:

在这个例子中,通过字体选择对话框选择相应的字体,并且所选择字体的效果显示在 QLineEdit 的文本上。 实现代码如下所示:

import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import * class FontDialogDemo(QWidget):	def __init__(self, parent=None):		super(FontDialogDemo, self).__init__(parent)         #创建QVBoxLayout布局,在垂直布局管理器中添加fontButton 和fontLineEdit组件,并按照相应的位置添加到栅格布局中。		layout = QVBoxLayout()        		self.fontButton  = QPushButton("choose font")         #当单击fontButton按钮时,将clicked信号发送到槽函数getFont()中。		self.fontButton .clicked.connect(self.getFont)         #实例化fontButton和fontLineEdit对象,并将fontButton的clicked信号和槽函数getFont()绑定在一起。		layout.addWidget(self.fontButton )		self.fontLineEdit  = QLabel("Hello,测试字体例子")		layout.addWidget(self.fontLineEdit )		self.setLayout(layout)		self.setWindowTitle("Font Dialog 例子")	    #自定义槽函数,选择字体,并将字体效果设置到fontLineEdit中。getFont()方法返回的为元组类型,同时返回所选择的字体和函数执行的状态。	def getFont(self):		font, ok = QFontDialog.getFont()		if ok:			self.fontLineEdit .setFont(font)					if __name__ == '__main__':	app = QApplication(sys.argv)	demo = FontDialogDemo()	demo.show()	sys.exit(app.exec_())
复制代码

3.4、QFileDialog 窗口

QFileDialog 是用于打开和保存文件的标准对话框,QFileDialog 类继承自 QDialog 类。

QFileDialog 在打开文件时使用了文件过滤器,用于显示指定扩展名的文件,也可以设置使用 QFileDialog 打开文件时的起始目录和指定扩展名的文件。

QFileDialog 类中的常用方法如下表所示:

以下示例就是 QFileDialog 的典型应用,效果如下所示:

在这个例子中,通过文件对话框来选择文件,其中第一个文件对话框只允许打开图片文件,并把所加载的图片显示在标签(QLabel)中;第二个文件对话框只允许打开文本文件,并把文本内容显示在文本框(QTextEdit)内。 实现代码如下所示:

import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import * class filedialogdemo(QWidget):	def __init__(self, parent=None):		super(filedialogdemo, self).__init__(parent) 		layout = QVBoxLayout()        #第一个按钮使用QFileDialog.getOpenFileNam(),调用文件对话框来显示图像,并显示在一个标签控件中。它负责打开C盘目录下的文件。		self.btn = QPushButton("加载图片")		self.btn.clicked.connect(self.getfile) 		layout.addWidget(self.btn)		self.le = QLabel("")		layout.addWidget(self.le)         #第二个按钮使用文件对话框(QFileDialog)对象的exec_()方法来选择文件,并把所选文件的内容显示在文本编辑控件中。		self.btn1 = QPushButton("加载文本文件")		self.btn1.clicked.connect(self.getfiles)		layout.addWidget(self.btn1)		self.contents = QTextEdit()		layout.addWidget(self.contents)		self.setLayout(layout)		self.setWindowTitle("File Dialog 例子") 	def getfile(self):		fname, _  = QFileDialog.getOpenFileName(self, 'Open file', 'c:\\',"Image files (*.jpg *.gif)")		self.le.setPixmap(QPixmap(fname))		def getfiles(self):		dlg = QFileDialog()		dlg.setFileMode(QFileDialog.AnyFile)		dlg.setFilter( QDir.Files  )			if dlg.exec_():			filenames= dlg.selectedFiles()			f = open(filenames[0], 'r')             			with f:				data = f.read()				self.contents.setText(data) 					if __name__ == '__main__':	app = QApplication(sys.argv)	ex = filedialogdemo()	ex.show()	sys.exit(app.exec_())
复制代码


发布于: 2021 年 11 月 18 日阅读数: 6
用户头像

【研究方向】物联网、嵌入式、AI、Python 2018.02.09 加入

【公众号】美男子玩编程,关注获取海量资源~

评论

发布
暂无评论
Python Qt GUI设计:QMainWindow、QWidget和QDialog窗口类(基础篇—10)