压测工具开发实战篇(三)——开发MDI子窗口功能

在这里插入图片描述

你好,我是安然无虞。

文章目录


在这里插入图片描述

MDI 多个子窗口

QMdiArea 提供了一个主窗口区, 里面可以存放多个 QMdiSubWindow 子窗口.

如图所示:

在这里插入图片描述
QMdiSubWindow 里面的子窗口就是我们一直使用的 QMainWindow.

所以, 可以把任何前面示例给出的窗口作为 子窗口里面的内容.

比如我们已经在 Qt Designer 中构建好了QMdiArea主窗口区, 同时也构建了另外一个窗口文件(如client.ui) 用于表示client子窗口内容, 想要在代码中使用这个窗口文件, 可以先定义QMdiSubWindow子窗口, 并添加到主窗口区中.

代码示例:

class MainWindow:
	def __init__(self):
		# 一些主窗口的初始化代码
		# ...
		
		# 创建子窗口对象
		self.subWin = QtWidgets.QMdiSubWindow()
		# 从UI定义文件中加载子窗口界面
		form = uiLoader.load('./ui/client.ui')
		# 设置子窗口里面的 功能窗口
		self.subWin.setWidget(form)
		self.subWin.setAttribute(Qt.WA_DeleteOnClose)

		# 把子窗口加入到 MDI 区域
		self.ui.mdiArea.addSubWindow(self.subWin)
		# 显示子窗口
		self.subWin.show()
		# 子窗口提到最上层, 并且最大化
		self.subWin.setWindowState(Qt.WindowActive | Qt.WindowMaximized)

在本项目中我们要实现的子窗口相关的功能就是, 点击左侧侧边栏的图标时, 会自动显示对应的子窗口, 并且缺省状态是全屏的, 目前只实现点击哪个图标就会打开对应的子窗口, 功能暂不实现.

我们在原来的main.ui文件中新建一个ui文件, 并且命名为 client.ui , 然后只在其中随便加入一个控件即可.
在这里插入图片描述

这时候我们将上面提到的代码补充到项目代码中, 运行后我们看:
在这里插入图片描述
符合预期, 还需要再补充按侧边栏的图标就显示对应的子窗口的功能.

我们再来创建一个性能测试时的场景定义使用到的loadtest.ui文件, 像下面这样:
在这里插入图片描述
现在 main.ui 文件的侧边栏中有两个按钮, 分别是 btn_client和btn_loadtest, 点击之后分别显示 client子窗口和loadtest子窗口.

我们来实现上面讲述的功能:

我们可以为侧边栏按钮点击事件添加信号处理功能:

# 定义侧边栏点击事件处理
self.ui.btn_client.clicked.connect(self.load_client_sub_win)
self.ui.btn_loadtest.clicked.connect(self.load_loadtest_sub_win)

对应的加载子窗口代码就是:

def load_client_sub_win(self):
    # 创建子窗口对象
    subWin = QtWidgets.QMdiSubWindow()
    # 从UI定义文件中加载子窗口界面
    window = uiLoader.load('./ui/client.ui')
    # 设置子窗口里面的 功能窗口
    subWin.setWidget(window)
    subWin.setAttribute(Qt.WA_DeleteOnClose)

    # 把子窗口加入到 MDI 区域
    self.ui.mdiArea.addSubWindow(subWin)
    # 显示子窗口
    subWin.show()
    # 子窗口提到最上层, 并且最大化
    subWin.setWindowState(Qt.WindowActive | Qt.WindowMaximized)

这样实现之后, 运行代码点击对应的侧边按钮就可以显示对应的子窗口:
在这里插入图片描述
但是有一个问题是, 再次点击 btn_client 这些按钮的时候又会打开一个新的子窗口, 这是我们不想要的, 该怎么改动代码呢?

我们可以 在__init__方法中定义对应的实例变量, 然后每次在处理侧边按钮点击事件的时候就去对应的方法中判断是否已经打开了子窗口.

代码如下:

class MainWindow:
	def __init__(self):
		...
		self.subwin_client = None
		self.subwin_loadtest = None

	def load_client_sub_win(self):
		# 已经创建该子窗口, 直接最大化显示
        if self.subwin_client:
            self.subwin_client.setWindowState(Qt.WindowActive | Qt.WindowMaximized)
            return
            
        ...
		
		# 将创建好的子窗口对象赋值给实例对象用于判断
        self.subwin_client = subWin
遇见安然遇见你,不负代码不负卿。
谢谢老铁的时间,咱们下篇再见~