一、引言

在第《第三十一章、containers容器类部件QDockWidget停靠窗功能介绍》详细介绍了QDockWidget的属性、方法和信号,并介绍了利用QMainWindow的splitDockWidget和tabifyDockWidget等方法实现基于主窗口布局的方法。本节将利用相关方法实现一个简单的人机对话应用:笨笨机器人。

二、案例介绍

2.1、功能介绍

笨笨机器人是老猿测试QDockWidget的一个测试程序,其运行界面如图所示:



可以看到,该测试程序实现了一个简单的人机对话(机器应答是在设定应答语句中随机挑选一个),可以设置对话双方的名字,可以设置聊天信息的字体和颜色。

2.2、实现思路

要实现这个简单应用,有很多种方法,本次测试是为了使用QDockWidget,因此通过QMainWindow和QDockWidget配套实现。

由于QDockWidget本身的内容区域(内容)也是一个QWidget对象,要实现在QMainWindow上放置多个停靠窗、每个停靠窗要放置对应的内容子部件对象、并对停靠窗进行排列布局操作,在Designer中进行UI设计反而比通过代码实现麻烦很多,因此整体UI布局大部分都是通过代码实现的,在Designer中只实现了昵称配置信息窗口的界面和主窗口QMainWindow的主窗口基本界面。

2.3、昵称设置窗实现

昵称设置设计界面如下:



其中两个输入框的名称分别为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)

2.4、主窗口基础实现

2.4.1、ui设计界面



主窗口基本界面就是一个mainWindow,没有放置任何子部件,名称也是mainWindow,设置了标题信息为:“老猿Python:DockWidget测试 网址:https://blog.csdn.net/LaoYuanPython”。生成代码后存放在模块文件ui_mainWin.py中。

2.4.2、主窗口派生类及构造方法

主窗口派生类及构造方法代码如下:

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() #进行停靠窗生成及排列
说明:
  1. 构造方法中,除了常规的UI界面类的代码外,初始化了对话文本的颜色,设置了让主窗口支持停靠窗嵌套,最后调用initDock方法进行停靠窗生成及排列;
  2. 需要关注一下setDockNestingEnabled语句,相关属性的含义可以参考《PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象dockNestingEnabled属性》。但这个属性说明的字面说明太简单,实际理解还是有些复杂。在这里通过两个截图对比说明一下:上图是主窗口允许嵌套的场景,图中所有有关闭和浮动标记的窗口都是QDockWidget对象,在允许嵌套情况下,“机器人发言字体颜色”设置窗和“本机输入发言字体颜色”两个窗口可以上下堆叠合占一个停靠位的位置。而下图是未设置dockNestingEnabled的,这两个窗口就不能纵向堆叠在一起,只能选项卡式化占用一个停靠位。



    所以嵌套是指一个停靠位的位置堆叠或水平排列了两个停靠窗,而这个位置正常情况下只能放置一个对应大小的停靠窗。
  3. takeCentralWidget作用是将主窗口中央区域部件从主窗口中移除,对象并没有删除,当中央部件没有移除时,停靠窗只能停留在中央部件四周,移除后可以停靠到整个主窗口区域,下面截图对比一下:

    同一个程序,左边是移除了中央部件,右边没有,二者的效果对比可以看出移除中央部件的效果。

    如果没有调用takeCentralWidget移除中央部件,后续调用setCentralWidget将一个停靠窗口设置为中央部件也可以实现类似的效果。

2.4.3、创建对话显示框停靠窗

对话显示框dialogDisplay 为一个QTextEdit对象,将其作为dialogDisplayDock停靠窗的内容部件,将其放置在主窗口中央部件区域。

		self.dialogDisplay = QtWidgets.QTextEdit()
self.dialogDisplayDock = QtWidgets.QDockWidget("对话记录", self)
self.dialogDisplayDock.setWidget(self.dialogDisplay)#将对话窗作为对话停靠窗的内容部件
self.setCentralWidget(self.dialogDisplayDock)

2.4.4、创建输入停靠窗

输入部件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停靠窗的内容部件

2.4.5、构建字体选择停靠窗、机器人对话文本颜色停靠窗、发言人对话文本颜色停靠窗

字体选择停靠窗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类似,只是按钮连接的槽方法不同,设置的按钮颜色不同。在此不详细介绍,大家可参考附件代码。

2.4.6、构建昵称设置停靠窗

昵称设置停靠窗configDock包含内容部件configWin,configWin是一个单独的ui设计模块派生的类,用于设置输入者昵称和机器人昵称,其ui设计界面如下:



在构建configDock时,将configWin作为其内容部件。

2.4.7、排列停靠窗

将所有停靠窗对象及对应内容部件对象都创建后,接下来需要在QMainWindow中排列这些窗口,最终程序运行后的初始排列效果如下:

要实现停靠窗的排列,需要分如下两步进行:

2.4.7.1、将所有停靠窗按一定位置加到主窗口

按照上图的排列,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) #设置配置窗最小宽度
运行后效果:

2.4.7.2、使用splitDockWidget和tabifyDockWidget调整窗口位置

上图不是我们要的效果,此时需要使用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的作用。

运行效果:

发现达到了想要的效果。

2.4.8、实现对话窗发送消息后的响应槽方法inputEnd

在槽方法内需要设置输入消息的字体颜色并显示输入信息,同时调用机器人应答方法输出机器人应答消息。

    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() #输出机器人应答消息

2.4.9、实现设置字体的槽方法getFont

getFont方法调用字体设置对话框来获取需要设置的字体,对话框原字体作为字体设置对话窗的初始字体。

    def getFont(self):#,visible):
font = self.dialogDisplay.font() #取现有字体
font,changed = QtWidgets.QFontDialog.getFont(font,self,"字体设置") if changed: self.dialogDisplay.setFont(font)

2.4.10、实现设置输入文字或机器人应答文字颜色的槽方法getFontColor

getFontColor方法需要判断信号发射对象是来自输入文字颜色设置按钮还是机器人应答消息颜色按钮,然后根据不同取不同的初始颜色,并调用颜色选择对话窗选择颜色,并将颜色记录后,将对应按钮的文字颜色设置文新的颜色。相关代码与设置字体类似,在此就不介绍了。

经过以上步骤,一个比较完整的人机对话简单应用就构建完了。

广告

老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只需要9.9元,该部分与第十五章的内容基本对应,但同样内容在付费专栏上总体来说更详细、案例更多。本节内容对应付费专栏的《第三十二章、使用splitDockWidget和tabifyDockWidget嵌套布局QDockWidget的PyQt人机对话案例》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

老猿Python,跟老猿学Python!

第15.39节、splitDockWidget和tabifyDockWidget嵌套布局QDockWidget的PyQt人机对话案例:笨笨机器人的更多相关文章

  1. 第三十二章、使用splitDockWidget和tabifyDockWidget嵌套布局QDockWidget的PyQt人机对话案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 在第<第三十一章.containers容器类部件QDo ...

  2. 第15.40节、PyQt(Python+Qt)实战:moviepy实现MP4视频转gif动图的工具

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 在写<第15.39节.splitDockWidget和 ...

  3. 第15.38节 PyQt(Python+Qt)入门学习:containers容器类部件QDockWidget停靠窗功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QDockWidget类提供了一个可以停靠在QMainWin ...

  4. Android零基础入门第39节:ListActivity和自定义列表项

    原文:Android零基础入门第39节:ListActivity和自定义列表项 相信通过前两期的学习,以及会开发最简单的一些列表界面了吧,那么本期接着来学习更多方法技巧. 一.使用ListActivi ...

  5. 第15.9节 PyQt学习入门:使用Qt Designer进行GUI设计的步骤

    在使用Qt Designer进行GUI设计时,一般常规的步骤都是差不多的,主要步骤包括新建显示窗口.在窗口上按照规划的布局放置组件.设置初始化组件的属性.定义信号和槽函数的连接,一般后三步是每增加一个 ...

  6. 第15.48节、PyQt显示部件:TextBrowser、CalendarWidget、LCDNumber、ProgressBar、Label、HorizontalLine和VerticalLine简

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 在Designer中,显示部件有Labe ...

  7. 第15.44节、PyQt输入部件:QAbstractSlider派生类QScrollBar滚动条、QSlider滑动条、QDial刻度盘功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.引言 Designer中的输入部件Horizo ...

  8. 第15.37节 PyQt(Python+Qt)入门学习:containers容器类部件QMdiArea多文档界面部件详解及编程开发案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 老猿在前期学习PyQt相关知识时,对每个组件的属性及方法都研 ...

  9. 第15.30节 PyQt编程实战:通过eventFilter监视QScrollArea的widget()的Paint消息画出scrollAreaWidgetContents的范围矩形

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 在<PyQt(Python+Qt)学习随笔:QScrollArea滚动区域详解> ...

随机推荐

  1. R语言factor类型转numeric

    R 语言中为了进行数据分析,比如回归分析,这时候对于数据表格中的factor类型的数据会带来弊端,比如对因子的每一个数据都进行一次回归,这样就显得很复杂,且违背了我们的初衷,需要把factor转换为n ...

  2. SU模型叠加实景三维模型 用它就可以实现了

    草图大师SketchUp是一套直接面向设计方案创作过程的设计软件,使用SketchUp规划设计师可以从潦草的平面草图开始,创建出想像的任何东西 .虽然市面软件众多,也不能取代SketchUp独有的位置 ...

  3. Scanner对象

    Scanner对象 通过Scanner类来获取用户的输入. 使用需导入 java.util.Scanner 包. 基本语法: Scanner s = new Scanner(System.in); n ...

  4. GDT,LDT,GDTR,LDTR (转 侵删)

    一.引入 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成 段描述符寄存器: 存储段描述符 选择器:存储段描述符的索引 段寄存器(16位选择子,64为隐藏信息) 原先实模式下 ...

  5. linux系统中离线安装python3.7过程记录

    最近公司新弄来一台linux  redhat 4.4.7服务器,准备在上面离线安装python3.7,安装过程中出现一些问题,特此记录下来. 首先在python官网上下载了 Python-3.7.3. ...

  6. Java基础 之一 基本知识

    Java基础 之一 基本知识 1.数据类型 Java有8种基本数据类型 int.short .long.byte.float.double.char.boolean 先说明以下单位之间的关系 1位 = ...

  7. IDEA 2019.3.3 + Pycharm 2020.2.1 安装包及破解步骤

    IDEA IDEA的破解流程就不用再说了,免费试用,添加VMOptions参数,选择破解jar的路径,重启IDEA. 下载地址:链接:https://pan.baidu.com/s/1aTRATVTL ...

  8. java面试必问:多线程的实现和同步机制,一文帮你搞定多线程编程

    前言 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线 ...

  9. QBXT 提高组储备营 2020.夏 游记

    DAY 1 是第一天呐!老师好强!讲得好仔细!连我都全懂了![doge] 突然对后面几天充满了期待-- 复习内容:二分,排序,贪心,搜索(好评) 新知识:Huffman树及Huffman编码,对拍,二 ...

  10. Matlab 画图2

    fplot函数 plot函数的缺点:在实际应用中,函数随着自变量的变化趋势是未知的,如果自变量的离散区间不合理,则无法反应函数的变化趋势. fplot的作用:通过自适应算法,解决上述问题. fplot ...