PyQt的各类窗口
前面的内容带大家感受认识了PyQt,对于各种组件、布局应该有了自己的理解,今天就阐述组件以及布局的画布----窗口。
PyQt的窗口可以大致的份三类,也可以理解成两类,即主窗口(QMainWindow),一般窗口(QWidget),还有就是对话窗口(QDialog),当然这是我的叫法和理解。在这里可以把QWidget生成的窗口理解成主窗口,这里就介绍两类窗口。
一、主窗口(QMainWindow)
QMainWindow窗口可以包含菜单栏、工具栏、状态栏、标题栏等,是最常见的窗口形式,也就是常说的GUI程序主窗口。
1、窗口样式
1、PyQt的基本窗口类型
- Qt.Widget:默认窗口,有最小化、最大化、关闭按钮。
- Qt.Window:普通窗口,有最小化、最大化、关闭按钮。
- Qt.Dialog:对话窗口,有问号和关闭按钮。
- Qt.Popup:弹出窗口,窗口无边框(无法关闭,请指点)。
- Qt.ToolTip:提示窗口,窗口无边框,无任务栏。
- Qt.SplashScreen:闪屏,窗口无边框,无任务栏。
- Qt.SubWindow:子窗口,窗口无按钮,但有标题。
2、自定义窗口类型
- Qt.MSWindowsFixedSizeDialogHint:窗口无法调整大小。
- Qt.FramelessWindowHint:窗口无边框。
- Qt.CustomizeWindowHint:有边框但无标题栏和按钮,不能移动和拖动
- Qt.WindowTitleHint:添加标题栏和一个关闭按钮,但关闭按钮未激活。
- Qt.WindowSystemMenuHint:添加系统目录和一个关闭按钮,但关闭按钮未激活。
- Qt.WindowMaximizeButtonHint:激活最大化按钮,禁止最小化和关闭按钮。
- Qt.WindowMinimizeButtonHint:激活最小化按钮,禁止最大化和关闭按钮。
- Qt.WindowMinMaxButtonsHint:激活最小化、最大化按钮,相当于
Qt.WindowMaximizeButtonHint|Qt.WindowMinimizeButtonHint - Qt.WindowCloseButtonHint:添加一个关闭按钮。
- Qt.WindowContextHelpButtonHint:添加问号和一个关闭按钮,但关闭按钮未激活。
- Qt.WindowStaysOnTopHint:窗口始终处于顶层位置。
- Qt.WindowStaysOnBottomHint:窗口始终处于底层位置。
示例代码:
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QToolTip, QPushButton)
from PyQt5.QtGui import QIcon, QFont
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtWidgets import QDesktopWidget
from PyQt5.QtCore import Qt
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
QToolTip.setFont(QFont('SansSerif', 10))
self.setToolTip('This is a <b>QWidget</b> widget')
btn = QPushButton('Button',self)
btn.setToolTip('This is a <b>QPushButton</b> widget')
btn.resize(btn.sizeHint())
btn.move(50, 50)# 调整按钮位置
self.setGeometry(400,300,500,500)
self.center()
self.setWindowTitle("Icon")
self.setWindowFlags(Qt.WindowStaysOnBottomHint)
btn.clicked.connect(lambda:self.close())
def closeEvent(self,event):
reply = QMessageBox.question(self,"message",
"are you sure to quit?",QMessageBox.Yes | QMessageBox.No,
QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
QToolTip.setFont(QFont('SansSerif', 10))
self.setToolTip('This is a <b>QWidget</b> widget')
设置提示框的字体以及显示样式。
self.center()
窗口居中,即窗口在屏幕的中间,这里使用的是自定义的方法,具体讲解如下。
def center(self):
qr = self.frameGeometry()# 获得主窗口所在的框架。
cp = QDesktopWidget().availableGeometry().center()#获取显示器的分辨率,然后得到屏幕中间点的位置。
qr.moveCenter(cp)#然后把主窗口框架的中心点放置到屏幕的中心位置。
self.move(qr.topLeft())#然后通过move函数把主窗口的左上角移动到其框架的左上角,这样就把窗口居中了。
btn.clicked.connect(lambda:self.close())
给按钮绑定关闭程序代码,主要是测试没有按钮的几个样式时,防止卡死。
self.setWindowFlags(Qt.WindowStaysOnBottomHint)
设置窗口样式代码,需要先导入Qt模块,导入方法是 from PyQt5.QtCore import Qt。
2、窗口模态
这里说的窗口模态和上面讲的窗口样式是不一样的,窗口样式是窗口的展现效果,而这里的模态是指窗口相对于主窗口的模式,所以模态应用于子窗口,具体的模态介绍如下:
- Qt.NonModal:非模态,可以和程序的其他窗口进行交互。
- Qt.WindowModal:窗口模态,程序在未处理完当前对话框时,将阻止和对话框的父窗口进行交互。
- Qt.ApplicationModal:应用程序模态,阻止和任何其他窗口进行交互。
资料上是上述这个说法,但我实际测试Qt.NonModal和Qt.ApplicationModal都会阻止和主窗口交互,只有Qt.WindowModal可以和主窗口交互,不知是不是我设置的问题,请大佬指点。
示例如下:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 放置出现对话框的按钮
self.btn = QPushButton("会话框",self)
self.btn.move(50,50)
self.btn.clicked.connect(self.updateui)
self.setWindowTitle("对话框的使用")
self.setGeometry(300,300,400,300)
def updateui(self):
dialog = QDialog()
btn = QPushButton("OK",dialog)
btn.clicked.connect(dialog.close)
btn.move(50,50)
dialog.setWindowTitle("这是个对话框")
dialog.setWindowModality(Qt.NonModal)
dialog.exec_()
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
dialog.setWindowModality(Qt.NonModal)
设置窗口的模态。
二、对话窗口(QDialog)
QDialog窗口是对话类窗口,主要就是与用户产生交互,比如我们常用的文件窗口、提示窗口、配置窗口等。
1、消息窗口 QMessageBox
QMessageBox是一种通用的弹出式对话框,用于显示消息,允许用户通过单击不同的标准按钮对消息进行反馈。
QMessageBox类提供了如:提示、警告、错误、问询、关于等对话框(它们的区别在于图标和声音不一样)。
示例代码:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MyWindow(QWidget):
def __init__(self,parent=None):
super(MyWindow,self).__init__(parent)
self.setWindowTitle("弹出式对话框例子")
self.resize(400,200)
self.btn1=QPushButton(self)
self.btn1.setText("消息框")
self.btn1.clicked.connect(self.msg1)
layout=QVBoxLayout()
self.btn2=QPushButton(self)
self.btn2.setText("问答对话框")
self.btn2.clicked.connect(self.msg2)
self.btn3=QPushButton()
self.btn3.setText("警告对话框")
self.btn3.clicked.connect(self.msg3)
self.btn4=QPushButton()
self.btn4.setText("严重错误对话框")
self.btn4.clicked.connect(self.msg4)
self.btn5=QPushButton()
self.btn5.setText("关于对话框")
self.btn5.clicked.connect(self.msg5)
layout.addWidget(self.btn1)
layout.addWidget(self.btn2)
layout.addWidget(self.btn3)
layout.addWidget(self.btn4)
layout.addWidget(self.btn5)
self.setLayout(layout)
def msg1(self):
#使用infomation信息框
msg = QMessageBox.information(self,"标题","消息正文",QMessageBox.Yes|QMessageBox.No,QMessageBox.Yes)
def msg2(self):
QMessageBox.question(self,"标题","问答消息正文",QMessageBox.Yes|QMessageBox.No,QMessageBox.Yes)
def msg3(self):
QMessageBox.warning(self,"标题","警告消息正文",QMessageBox.Yes|QMessageBox.No,QMessageBox.Yes)
def msg4(self):
QMessageBox.critical(self,"标题","严重错误消息正文",QMessageBox.Yes|QMessageBox.No,QMessageBox.Yes)
def msg5(self):
QMessageBox.about(self,"标题","关于消息正文")
if __name__=="__main__":
app=QApplication([])
win=MyWindow()
win.show()
app.exec_()
2、输入窗口 QInputDialog
QImputDialog控件是一个标准对话框,由一个文本框和两个按钮(OK按钮和Cancel按钮)组成。当用户单击OK按钮或按Enter键后,在父窗口可以收集通过QInputDialog 控件输入的信息。QInputDialog控件是QDialog标准对话框的一部分。
在QInputDialog控件中可以输入数字、字符串或列表中的选项。标签用于提示必要的信息。
- getInt():从控件获取标准整数输入。
- getDouble():从控件获取标准浮点数输入。
- getText():从控件获取标准字符串输入。
- getItem():从控件获取列表里的选项输入。
示例代码:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 表格布局
form = QFormLayout()
self.lb = QLineEdit()
self.lb.setPlaceholderText('字符串')
form.addRow("姓名:",self.lb)
self.lb1 = QLineEdit()
self.btn = QPushButton("获取数据")
form.addRow(self.btn,self.lb1)
self.btn.clicked.connect(self.updateUI)
self.setLayout(form)
self.setWindowTitle("输入框的使用")
self.setGeometry(300,300,400,300)
def updateUI(self):
items = ["C","C++","Python","JAVA"]
item,ok = QInputDialog.getItem(self,"select Input Dialog",
"语言列表",items,0,False)
if ok and item:
self.lb1.setText(item)
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
3、字体窗口 QFontDialog
QFontDialog控件是一个常用的字体选择对话框,可以让用户选择所显示文本的字号大小、样式和格式。QFontDialog是QDialog标准对话框的一部分。使用QFontDialog类的静态方法getFont0,可以从字体选择对话框中选择文本的显示字号大小、样式和格式。
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
layout = QVBoxLayout()
self.btn = QPushButton("选择字体")
self.font_edit = QLabel()
self.font_edit.setText("演示文字,请查验!")
layout.addWidget(self.btn)
layout.addWidget(self.font_edit)
self.btn.clicked.connect(self.update)
self.setLayout(layout)
self.setGeometry(300,300,400,300)
self.setWindowTitle("字体框的使用")
def update(self):
font,ok = QFontDialog.getFont()
if ok:
self.font_edit.setFont(font)
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
4、文件窗口 QFileDialog
QFileDialog是用于打开和保存文件的标准对话框。QFileDialog类继承自QDialog类。
QFileDialog在打开文件时使用了文件过滤器,用于显示指定扩展名的文件。也可以设置使用QFileDialog打开文件时的起始目录和指定扩展名的文件。
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import pandas as pd
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
layout = QVBoxLayout()
self.btn = QPushButton("选择图片")
self.btn2 = QPushButton("选择文本文件")
self.piclb = QLabel()
self.txt = QTextEdit()
layout.addWidget(self.btn)
layout.addWidget(self.piclb)
layout.addWidget(self.btn2)
layout.addWidget(self.txt)
self.btn.clicked.connect(self.loadpic)
self.btn2.clicked.connect(self.loadtxt)
self.setLayout(layout)
self.setGeometry(300,300,400,300)
self.setWindowTitle("文件框的使用")
def loadpic(self):
# 返回一个元组,文件路径在第一个参数,所以用一个占位符
# 关于参数,第二个是对话框标题,第三个是起始路径,第四个是文件类型,注意是空格隔开,不选是全部文件
pic,_ = QFileDialog.getOpenFileName(self,"OPen pic",".\\","(*.png *.jpg *.gif)")
self.piclb.setPixmap(QPixmap(pic))
def loadtxt(self):
file_path = QFileDialog.getOpenFileName(self,"OPen pic",".\\")
data = pd.read_excel(file_path[0])
# self.txt.setText 接受的参数是字符串型,所以要把DataFrame转换
self.txt.setText(str(data.head(20)))
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
QFileDialog.getOpenFileName(self,"OPen pic",".\\")
QFileDialog.getExistingDirectory(self)
第一个是打开并获取文件路径;第二个是打开并获取文件夹路径,后面参数指定具体格式,没有参数则为全部格式。
PyQt中的Dialog有很多现有的窗口模块,诸如上述几种,当需要的窗口没有时,就需要自己定义自己的需求窗口,就会用到开头讲的窗口的样式和子窗口的模态选择。
讲解到这里,估计对PyQt的窗口有了一定的理解,持续更新中…
👊🙈 …