前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PySide6 GUI 编程(31):多个 QWidget 窗口展示

PySide6 GUI 编程(31):多个 QWidget 窗口展示

原创
作者头像
bowenerchen
发布2024-08-21 23:44:15
230
发布2024-08-21 23:44:15
举报
文章被收录于专栏:编码视界

QWidget对象作为临时变量进行展示

示例代码

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

import sys
from datetime import datetime

from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget


def get_time_str() -> str:
    return datetime.now().isoformat()


def init_new_window() -> QMainWindow:
    new_window = QMainWindow()
    label = QLabel("这是新窗口,编号:{}".format(get_time_str()), new_window)
    v_layout = QVBoxLayout()
    v_layout.addWidget(label)
    container = QWidget()
    container.setLayout(v_layout)
    new_window.setCentralWidget(container)
    print("new_window 窗口初始化完成")
    return new_window


def button_clicked():
    print("按钮被点击了,开始初始化 new_window 窗口")
    tmp_window = init_new_window()
    # tmp_window是临时变量, .show()不会阻塞,因此在.show()之后,tmp_window 变量可以被回收
    # 因此看不到 tmp_window 窗口被显示出来
    tmp_window.show()
    print('new_window.show()执行完成')


class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        button = QPushButton("显示第二个 QWidget 窗口", self)
        button.clicked.connect(button_clicked)
        label = QLabel("这是主窗口,编号: {}".format(get_time_str()), parent = self)
        v_layout = QVBoxLayout()
        v_layout.addWidget(button)
        v_layout.addWidget(label)
        container = QWidget()
        container.setLayout(v_layout)
        self.setCentralWidget(container)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 验证下 init_new_window 函数返回的窗口可以正常运行
    # 但是值得注意的是
    # 使用 init_new_window().show() 时,
    # 窗口可能会在 .show() 方法返回后被立即销毁,
    # 因为没有变量引用它,Python 的垃圾回收器可能会在稍后的某个时间点回收这个对象
    # 这样会导致窗口无法正常显示
    # 将 init_new_window() 的返回值分配给一个变量(如 ret)时,
    # 将确保该窗口对象在应用程序的生命周期内处于活跃状态,
    # 因此窗口将继续显示,直到应用程序退出或变量超出作用域,
    ret = init_new_window()
    ret.show()
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec())

这段代码在处理临时 QWidget 对象时,考虑了两种场景:

  • 函数中作为临时变量
    函数中的临时变量
    函数中的临时变量
  • 无变量引用的场景
    无变量引用的场景
    无变量引用的场景

运行效果

实时展示临时的 QWidget 对象
实时展示临时的 QWidget 对象

进程在刚启动时会初始化出两个窗口,这可以证明 init_new_window() 返回的对象是可以正常展示的

进程启动时初始化出两个窗口
进程启动时初始化出两个窗口

在点击按钮显示第二个 QWidget 窗口后,并没有第三个窗口展示出来,Console 也只打印了:

只打印日志但是没有窗口展示出来
只打印日志但是没有窗口展示出来
点击按钮时触发临时对象的初始化
点击按钮时触发临时对象的初始化

让QWidget对象的生命周期延长

示例代码

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

import sys
from datetime import datetime

from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget


def get_time_str() -> str:
    return datetime.now().isoformat()


def init_new_window() -> QMainWindow:
    new_window = QMainWindow()
    label = QLabel("这是新窗口,编号:{}".format(get_time_str()), new_window)
    v_layout = QVBoxLayout()
    v_layout.addWidget(label)
    container = QWidget()
    container.setLayout(v_layout)
    new_window.setCentralWidget(container)
    print("new_window 窗口初始化完成")
    return new_window


class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.tmp_window = QMainWindow()  # 初始化一个窗口
        button = QPushButton("显示第二个 QWidget 窗口", self)
        button.clicked.connect(self.button_clicked)
        label = QLabel("这是主窗口,编号: {}".format(get_time_str()), parent = self)
        v_layout = QVBoxLayout()
        v_layout.addWidget(button)
        v_layout.addWidget(label)
        container = QWidget()
        container.setLayout(v_layout)
        self.setCentralWidget(container)

    def button_clicked(self):
        print("按钮被点击了,开始初始化 new_window 窗口")
        # 重新初始化一个窗口
        # 此时 self.tmp_window 将跟随 MyMainWindow 对象的生命周期生存
        # 同时,每次点击按钮时,都会刷新 self.tmp_window 窗口
        # 因此每次都会新生成一个窗口对象覆盖 self.tmp_window
        self.tmp_window = init_new_window()
        self.tmp_window.show()
        print('new_window.show()执行完成')

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec())
生命周期与主界面对象的生命周期一致
生命周期与主界面对象的生命周期一致

运行效果

每次生成新的窗口
每次生成新的窗口

可以看到每次点击按钮时,都会生成新的窗口:

覆盖变量的逻辑
覆盖变量的逻辑

控制另一个窗口的展示或隐藏

示例代码

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

import sys
from datetime import datetime

from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget


def get_time_str() -> str:
    return datetime.now().isoformat()


def init_new_window() -> QMainWindow:
    new_window = QMainWindow()
    label = QLabel("这是新窗口,编号:{}".format(get_time_str()), new_window)
    v_layout = QVBoxLayout()
    v_layout.addWidget(label)
    container = QWidget()
    container.setLayout(v_layout)
    new_window.setCentralWidget(container)
    print("new_window 窗口初始化完成")
    return new_window


class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.tmp_window = None
        button = QPushButton("显示第二个 QWidget 窗口", self)
        button.clicked.connect(self.button_clicked)
        label = QLabel("这是主窗口,编号: {}".format(get_time_str()), parent = self)
        v_layout = QVBoxLayout()
        v_layout.addWidget(button)
        v_layout.addWidget(label)
        container = QWidget()
        container.setLayout(v_layout)
        self.setCentralWidget(container)

    def button_clicked(self):
        if self.tmp_window is not None:
            print('窗口已经完成初始化了')
            if self.tmp_window.isVisible():
                self.tmp_window.hide()
            else:
                self.tmp_window.show()
            return
        print("按钮被点击了,开始初始化 new_window 窗口")
        # 重新初始化一个窗口
        # 此时 self.tmp_window 将跟随 MyMainWindow 对象的生命周期生存
        # 同时,每次点击按钮时,都会刷新 self.tmp_window 窗口
        # 因此每次都会新生成一个窗口对象覆盖 self.tmp_window
        self.tmp_window = init_new_window()
        self.tmp_window.show()
        print('new_window.show()执行完成')


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec())

运行效果

通过按钮控制窗口的展示与隐藏
通过按钮控制窗口的展示与隐藏

通过判断对象状态实现对窗口行为的控制:

核心逻辑
核心逻辑

通过信号与槽实现两个窗口展示的联动

示例代码

代码语言:python
代码运行次数:0
复制
from __future__ import annotations

import hashlib
import sys
from datetime import datetime

from PySide6.QtWidgets import QApplication, QLabel, QLineEdit, QMainWindow, QVBoxLayout, QWidget


def get_time_str() -> str:
    return datetime.now().isoformat()


def init_new_window(label_object: QLabel) -> QMainWindow:
    new_window = QMainWindow()
    v_layout = QVBoxLayout()
    v_layout.addWidget(label_object)
    container = QWidget()
    container.setLayout(v_layout)
    new_window.setCentralWidget(container)
    print("new_window 窗口初始化完成")
    return new_window


class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.tmp_window = None
        self.setWindowTitle("使用信号连接两个窗口")
        label = QLabel("这是主窗口,编号: {}".format(get_time_str()), parent = self)
        self.another_window_label = QLabel('这是展示在第二个窗口上的 Label')
        self.line_edit = QLineEdit('请输入数据', self)
        self.line_edit.setMaxLength(128)
        self.line_edit.returnPressed.connect(self.line_edit_return_pressed)
        v_layout = QVBoxLayout()
        v_layout.addWidget(label)
        container = QWidget()
        container.setLayout(v_layout)
        self.setCentralWidget(container)

    def line_edit_return_pressed(self):
        text = self.line_edit.text()
        hash_obj = hashlib.sha3_256()
        hash_obj.update(text.encode('utf-8'))
        hash_value = hash_obj.hexdigest()
        self.another_window_label.setText('输入的数据是:{}\n哈希算法是:{}\n哈希值是:{}'.format(
            text, hash_obj.name, hash_value))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    another_window = init_new_window(window.another_window_label)
    another_window.show()
    sys.exit(app.exec())

运行效果

窗口联动
窗口联动

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • QWidget对象作为临时变量进行展示
    • 示例代码
      • 运行效果
      • 让QWidget对象的生命周期延长
        • 示例代码
          • 运行效果
          • 控制另一个窗口的展示或隐藏
            • 示例代码
              • 运行效果
              • 通过信号与槽实现两个窗口展示的联动
                • 示例代码
                  • 运行效果
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档