赞
踩
在第《第三十一章、containers容器类部件QDockWidget停靠窗功能介绍》详细介绍了QDockWidget的属性、方法和信号,并介绍了利用QMainWindow的splitDockWidget和tabifyDockWidget等方法实现基于主窗口布局的方法。本节将利用相关方法实现一个简单的人机对话应用:笨笨机器人。
笨笨机器人是老猿测试QDockWidget的一个测试程序,其运行界面如图所示:
可以看到,该测试程序实现了一个简单的人机对话(机器应答是在设定应答语句中随机挑选一个),可以设置对话双方的名字,可以设置聊天信息的字体和颜色。
要实现这个简单应用,有很多种方法,本次测试是为了使用QDockWidget,因此通过QMainWindow和QDockWidget配套实现。
由于QDockWidget本身的内容区域(内容)也是一个QWidget对象,要实现在QMainWindow上放置多个停靠窗、每个停靠窗要放置对应的内容子部件对象、并对停靠窗进行排列布局操作,在Designer中进行UI设计反而比通过代码实现麻烦很多,因此整体UI布局大部分都是通过代码实现的,在Designer中只实现了昵称配置信息窗口的界面和主窗口QMainWindow的主窗口基本界面。
昵称设置设计界面如下:
其中两个输入框的名称分别为myName和robertName。
ui设计后将其生成代码模块文件ui_configWin.py,然后派生类,只实现构造方法,其他都不进行处理。
class configWin(ui_configWin.Ui_configWin,QtWidgets.QWidget):
def __init__(self,parent=None):
super().__init__(parent)
self.setupUi(self)
主窗口基本界面就是一个mainWindow,没有放置任何子部件,名称也是mainWindow,设置了标题信息为:“老猿Python:DockWidget测试 网址:https://blog.csdn.net/LaoYuanPython”。生成代码后存放在模块文件ui_mainWin.py中。
主窗口派生类及构造方法代码如下:
class mainWin(QtWidgets.QMainWindow,ui_mainWin.Ui_mainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.robertColor = Qt.black #设置机器人对话字体初始颜色
self.myColor = Qt.blue #设置输入对话字体初始颜色
self.setDockNestingEnabled(True) #让主窗口支持停靠窗嵌套
w = self.takeCentralWidget() #移除中央窗口部件,请参见第三十一章的介绍
self.initDock() #进行停靠窗生成及排列
对话显示框dialogDisplay 为一个QTextEdit对象,将其作为dialogDisplayDock停靠窗的内容部件,将其放置在主窗口中央部件区域。
self.dialogDisplay = QtWidgets.QTextEdit()
self.dialogDisplayDock = QtWidgets.QDockWidget("对话记录", self)
self.dialogDisplayDock.setWidget(self.dialogDisplay)#将对话窗作为对话停靠窗的内容部件
self.setCentralWidget(self.dialogDisplayDock)
输入部件input 为一个QLineEdit对象,将其作为inputDock 停靠窗的内容部件,在代码中设置了输入部件的宽度。由于部件是代码创建,因此信号与槽方法的连接关系必须代码实现,在此将输入部件按下回车键作为消息发送的信号连接到主窗口的槽方法inputEnd。
self.input = QtWidgets.QLineEdit()
self.input.geometry().setWidth(200)
self.input.returnPressed.connect(self.inputEnd)
self.inputDock = QtWidgets.QDockWidget("对话输入(回车键发送):", self)
self.inputDock.setWidget(self.input)#将输入部件input作为inputDock停靠窗的内容部件
字体选择停靠窗fontDock包含标题和一个设置字体的按钮,按钮点击后能触发字体选择。
self.fontDock = QtWidgets.QDockWidget('字体设置',self)
fontButton = QtWidgets.QPushButton('点此设置字体',self.fontDock)
setFontSizeColor(fontButton,QtGui.QPalette.ButtonText,Qt.red,10)#设置按钮文字的颜色和大小
fontButton.clicked.connect(self.getFont)
self.fontDock.setWidget(fontButton)#将fontButton作为fontDock停靠窗的内容部件
机器人对话文本颜色停靠窗robertFontColorDock用于设置输入文字在对话窗中显示的颜色、发言人对话文本颜色停靠窗myFontColorDock用于设置机器人应答文字在对话窗中显示的颜色,二者的实现与fontDock类似,只是按钮连接的槽方法不同,设置的按钮颜色不同。在此不详细介绍,大家可参考附件代码。
昵称设置停靠窗configDock包含内容部件configWin,configWin是一个单独的ui设计模块派生的类,用于设置输入者昵称和机器人昵称,其ui设计界面如下:
在构建configDock时,将configWin作为其内容部件。
将所有停靠窗对象及对应内容部件对象都创建后,接下来需要在QMainWindow中排列这些窗口,最终程序运行后的初始排列效果如下:
要实现停靠窗的排列,需要分如下两步进行:
按照上图的排列,dialogDisplayDock在嘴上,输入框在左边,昵称配置窗在右边,其他在最下面,按此规则使用如下语句将停靠窗加入到主窗口:
self.addDockWidget(QtCore.Qt.TopDockWidgetArea, self.dialogDisplayDock)
self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.inputDock)
self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.configDock)
self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.fontDock)
self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.robertFontColorDock)
self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.myFontColorDock)
self.configDock.setMinimumWidth(320) #设置配置窗最小宽度
上图不是我们要的效果,此时需要使用splitDockWidget来调整这些窗口的排列。首先将昵称配置窗调整到输入框右边,然后将字体设置窗调整到输入框下边,最后将两个颜色设置框与字体设置框进行选项卡化。使用如下代码:
self.splitDockWidget(self.inputDock, self.configDock, Qt.Horizontal) #昵称配置窗调整到输入框右边
self.splitDockWidget(self.inputDock,self.fontDock, Qt.Vertical) #将字体设置窗调整到输入框下边
self.tabifyDockWidget(self.fontDock, self.myFontColorDock) #将输入文字颜色设置框与字体设置框进行选项卡化
self.tabifyDockWidget(self.fontDock, self.robertFontColorDock) #将机器人文字颜色设置框与字体设置框进行选项卡化
大家结合上章介绍的内容理解一下splitDockWidget和tabifyDockWidget的作用。
发现达到了想要的效果。
在槽方法内需要设置输入消息的字体颜色并显示输入信息,同时调用机器人应答方法输出机器人应答消息。
def inputEnd(self):
if self.myColor: self.dialogDisplay.setTextColor(self.myColor)
self.dialogDisplay.append(self.configWin.myName.text()+': '+ self.input.text())
self.input.clear()
self.robertAnswer() #输出机器人应答消息
getFont方法调用字体设置对话框来获取需要设置的字体,对话框原字体作为字体设置对话窗的初始字体。
def getFont(self):#,visible):
font = self.dialogDisplay.font() #取现有字体
font,changed = QtWidgets.QFontDialog.getFont(font,self,"字体设置")
if changed: self.dialogDisplay.setFont(font)
getFontColor方法需要判断信号发射对象是来自输入文字颜色设置按钮还是机器人应答消息颜色按钮,然后根据不同取不同的初始颜色,并调用颜色选择对话窗选择颜色,并将颜色记录后,将对应按钮的文字颜色设置文新的颜色。相关代码与设置字体类似,在此就不介绍了。
经过以上步骤,一个比较完整的人机对话简单应用就构建完了。
老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只需要9.9元,该部分与第十五章的内容基本对应,但同样内容在付费专栏上总体来说更详细、案例更多。本节内容对应付费专栏的《第三十二章、使用splitDockWidget和tabifyDockWidget嵌套布局QDockWidget的PyQt人机对话案例》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。