自定义对话框与布局详解
我们以最常用的对话框(QDialog)为例讲解QT中的自定义窗口。在QT中也内置了许多的对话框,如博客之前提到的QColorDialog,QFileDialog等等,实用性非常强。缺点是他们往往不够灵活。
对话框:
-
模式对话框:模式对话框在对话时主界面不可操作,通过调用exec()来显示
-
非模式对话框,非模式对话框在对话时主界面可以操作,通过调用show()来显示
我们今天就从基类QDialog来自定义一个设置
对话框。
from PySide2.QtWidgets import QDialog
from PySide2.QtWidgets import QVBoxLayout
from PySide2.QtWidgets import QHBoxLayout
from PySide2.QtWidgets import QLabel
from PySide2.QtWidgets import QPushButton
from PySide2.QtWidgets import QComboBox
from PySide2.QtGui import QIcon
# 继承于QDialog
class SettingDialog(QDialog):
# 构造函数
def __init__(self, parent=None):
# 调用父类构造函数
QDialog.__init__(self, parent)
# 设置窗口名称与窗口图标
self.setWindowTitle("设置")
self.setWindowIcon(QIcon("../source/icon/settings.png"))
# 横向布局 【XXX:】+【组合框】
# new一个横向布局,无需指明父类,因为它将被放于纵向布局中,而纵向布局拥有父类
settingLayout = QHBoxLayout()
# new一个label,无需指明父类理由同上
label = QLabel()
label.setText("XXX:")
# 设置最小宽度,这里是为了与下面对齐
label.setMinimumSize(150,0)
settingLayout.addWidget(label)
# new一个不可修改的组合框
combox = QComboBox()
combox.setEditable(False)
# 向组合框中加两项
combox.addItem("A")
combox.addItem("B")
settingLayout.addWidget(combox)
# 横向布局 【XXX:】+【组合框】,同上不赘述
settingLayout1 = QHBoxLayout()
label1 = QLabel()
label1.setText("XX模式:")
label1.setMinimumSize(150,0)
settingLayout1.addWidget(label1)
combox1 = QComboBox()
combox1.setEditable(False)
# 这里传入了两个量,这就是QT的设计思想之一:“显示与数据分离”
# “否”是显示文本(Text),而0则是程序数据(Data)
combox1.addItem("否",0)
combox1.addItem("是",1)
settingLayout1.addWidget(combox1)
# 横向布局 【确认】+【取消】
settingLayout2 = QHBoxLayout()
button = QPushButton()
button.setText("确定")
settingLayout2.addWidget(button)
button1 = QPushButton()
button1.setText("取消")
settingLayout2.addWidget(button1)
# 纵向布局 将三个横向布局连起来
settingLayout3 = QVBoxLayout()
settingLayout3.addLayout(settingLayout)
settingLayout3.addLayout(settingLayout1)
settingLayout3.addLayout(settingLayout2)
self.buttonOk = button
self.buttonCancel = button1
self.comboxAlg = combox
self.comboxMode = combox1
# 按钮信号槽
self.buttonOk.clicked.connect(self.onButtonOk)
self.buttonCancel.clicked.connect(self.onButtonCancel)
self.setLayout(settingLayout3)
self.D3Mode = 0
self.alg = "A"
self.JudgeList=["否","是"]
# 信号槽函数
def onButtonOk(self):
# 调接受函数,表示用户接受自己的设置
self.accept()
# 信号槽函数
def onButtonCancel(self):
# 调拒绝函数,表示用户取消本次设置
self.reject()
# 显示函数,主界面通过调用这个函数来显示对话框,并获取信息
def getSettings(self):
# 模式对话框显示方式
ret = self.exec_()
# ret = self.show() 非模式对话框显示方式
# QDialog.Accepted是QT内设常量
if ret == QDialog.Accepted:
self.alg = self.comboxAlg.currentText()
self.D3Mode = self.comboxMode.currentData()
return True
# 用户拒绝,还原combox
else:
# currentText()获取显示文本
if self.alg != self.comboxAlg.currentText():
self.comboxAlg.setCurrentText(self.alg) # 组合框当前显示文本与其下拉文本不
# currentData()获取显示文本所关联的数据
if self.D3Mode !=self.comboxMode.currentData():
self.comboxMode.setCurrentText(self.JudgeList[self.D3Mode])
return False
需要注意的是,组合框的currentText()并不是其包含项的Text,而是本身显示的内容。
其次,Data与Text是两个概念,Data一般是程序运行所需的数据,而Text则是用户所见的数据