鱼C论坛

 找回密码
 立即注册
查看: 98|回复: 7

通过调用实例方法的子窗口如何保持可见性

[复制链接]
发表于 2025-1-17 09:51:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
from PySide6.QtWidgets import *

通过调用self.createAnnouncementWindow()函数的方式创建的子窗口,要如何才能保持:在与其他窗口交互时,
createAnnouncementWindow()窗口依旧保持可见性,在保持可见性的同时,下面的123功能不能收到影响

1. 弹出窗口可以跟随主窗口移动,2.在主窗口关闭时也随之关闭,3.不影响与其他窗口的交互
class MainWindowA(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle("主窗口 B")
        screen = QApplication.primaryScreen().geometry()
        self.screenWidth = screen.width()
        self.screenHeight = screen.height()
        self.setGeometry(0, 0, self.screenWidth, self.screenHeight)

        self.createAnnouncementWindow()    # 创建公告子窗口

    def resizeEvent(self, event):
        super().resizeEvent(event)
        new_size = event.size()
        self.width = new_size.width()
        self.height = new_size.height()

        self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))  # 公告窗口
        self.subWindow.move(0, int(self.height * 0.8))
        if self.subWindow and self.subWindow.isVisible():
            self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))  # 公告窗口
            self.subWindow.move(0, int(self.height * 0.8))

    def main_width_height(self):
        if self.width:
            return self.width, self.height

    def createAnnouncementWindow(self):    # 创建公告窗口
        self.announcementWindow = AnnouncementWindow(self.mdi_area)
        self.subWindow = self.mdi_area.addSubWindow(self.announcementWindow)
        self.subWindow.show()
        self.subWindow.destroyed.connect(self.subWindowDestroyed)  # 监听子
    def subWindowDestroyed(self):
        # 子窗口被销毁时,将 self.subWindow 设置为 None
        self.subWindow = None
    def toggleSubWindow(self):
        if self.subWindow is None:
            # 如果子窗口已经被关闭,重新创建它
            self.createAnnouncementWindow()
            self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))  # 调整子窗口大小
            self.subWindow.move(0, int(self.height * 0.8))
        elif self.subWindow.isVisible():
            self.subWindow.hide()
        else:
            self.subWindow.show()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2025-1-17 09:51:18 | 显示全部楼层
要实现公告窗口在与其他窗口交互时保持可见性,同时满足以下要求:

1. 弹出窗口可以跟随主窗口移动。
2. 在主窗口关闭时也随之关闭。
3. 不影响与其他窗口的交互。

可以将子窗口设置为 Qt.Tool 窗口类型。这样子窗口不会抢占主窗口的焦点,同时满足其他要求。您可以尝试以下修改:
from PySide6.QtWidgets import QApplication, QMainWindow, QMdiArea, QToolWindow, QWidget, QVBoxLayout, QLabel


class AnnouncementWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowFlags(self.windowFlags() | Qt.Tool)  # 设置为Tool窗口
        self.setWindowTitle("公告窗口")
        layout = QVBoxLayout()
        layout.addWidget(QLabel("公告内容"))
        self.setLayout(layout)


class MainWindowA(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.mdi_area = QMdiArea(self)
        self.setCentralWidget(self.mdi_area)
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("主窗口 B")
        screen = QApplication.primaryScreen().geometry()
        self.screenWidth = screen.width()
        self.screenHeight = screen.height()
        self.setGeometry(0, 0, self.screenWidth, self.screenHeight)

        self.createAnnouncementWindow()

    def resizeEvent(self, event):
        super().resizeEvent(event)
        new_size = event.size()
        self.width = new_size.width()
        self.height = new_size.height()

        self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
        self.subWindow.move(0, int(self.height * 0.8))
        if self.subWindow and self.subWindow.isVisible():
            self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
            self.subWindow.move(0, int(self.height * 0.8))

    def main_width_height(self):
        if self.width:
            return self.width, self.height

    def createAnnouncementWindow(self):
        self.announcementWindow = AnnouncementWindow(self)
        self.subWindow = self.mdi_area.addSubWindow(self.announcementWindow)
        self.subWindow.setWindowFlags(Qt.Tool)  # 与主窗口一起移动、关闭
        self.subWindow.show()
        self.subWindow.destroyed.connect(self.subWindowDestroyed)

    def subWindowDestroyed(self):
        self.subWindow = None

    def toggleSubWindow(self):
        if self.subWindow is None:
            self.createAnnouncementWindow()
            self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
            self.subWindow.move(0, int(self.height * 0.8))
        elif self.subWindow.isVisible():
            self.subWindow.hide()
        else:
            self.subWindow.show()

把公告窗口设置为 Qt.Tool 类型可以保证它不会成为主窗口焦点的一部分,这样即使用户切换到其他应用程序后再返回,公告窗口也能保持在前台。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-17 10:42:09 | 显示全部楼层
FishC 发表于 2025-1-17 09:51
要实现公告窗口在与其他窗口交互时保持可见性,同时满足以下要求:

1. 弹出窗口可以跟随主窗口移动。

我试了,当只有一个子窗口createAnnouncementWindow时,没有问题,但是有多个子窗口时,我与其他子窗口互动时,createAnnouncementWindow会被隐藏
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-1-17 10:42:40 | 显示全部楼层
rxts 发表于 2025-01-17 10:42
FishC 发表于 2025-1-17 09:51
要实现公告窗口在与其 ...


如果希望在有多个子窗口的情况下,`createAnnouncementWindow` 依然保持可见,你可以考虑使用 `Qt.WindowStaysOnTopHint` 使其始终位于其他子窗口之上。这将确保公告窗口始终可见,而不会干扰其他窗口的交互。

可以按照以下方式进行设置:
from PySide6.QtWidgets import QMainWindow, QMdiArea, QWidget, QVBoxLayout, QLabel, QApplication
from PySide6.QtCore import Qt

class AnnouncementWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowFlags(Qt.Tool | Qt.WindowStaysOnTopHint)  # 保持在前
        self.setWindowTitle("公告窗口")
        layout = QVBoxLayout()
        layout.addWidget(QLabel("公告内容"))
        self.setLayout(layout)

class MainWindowA(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.mdi_area = QMdiArea(self)
        self.setCentralWidget(self.mdi_area)
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("主窗口 B")
        screen = QApplication.primaryScreen().geometry()
        self.screenWidth = screen.width()
        self.screenHeight = screen.height()
        self.setGeometry(0, 0, self.screenWidth, self.screenHeight)

        self.createAnnouncementWindow()

    def resizeEvent(self, event):
        super().resizeEvent(event)
        new_size = event.size()
        self.width = new_size.width()
        self.height = new_size.height()

        self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
        self.subWindow.move(0, int(self.height * 0.8))
        if self.subWindow and self.subWindow.isVisible():
            self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
            self.subWindow.move(0, int(self.height * 0.8))

    def createAnnouncementWindow(self):
        self.announcementWindow = AnnouncementWindow(self)
        self.subWindow = self.mdi_area.addSubWindow(self.announcementWindow)
        self.subWindow.setWindowFlags(Qt.Tool | Qt.WindowStaysOnTopHint)
        self.subWindow.show()
        self.subWindow.destroyed.connect(self.subWindowDestroyed)

    def subWindowDestroyed(self):
        self.subWindow = None

    def toggleSubWindow(self):
        if self.subWindow is None:
            self.createAnnouncementWindow()
            self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
            self.subWindow.move(0, int(self.height * 0.8))
        elif self.subWindow.isVisible():
            self.subWindow.hide()
        else:
            self.subWindow.show()

if __name__ == '__main__':
    app = QApplication([])
    window = MainWindowA()
    window.show()
    app.exec()

这个代码使用了 `
...
` 标签来包裹代码段,在 Discuz! 论坛上可以清晰地展现代码块。通过加上 `Qt.WindowStaysOnTopHint`,公告窗口可以始终保持在其他子窗口的前面。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-17 11:07:53 | 显示全部楼层
FishC 发表于 2025-1-17 10:42
如果希望在有多个子窗口的情况下,`createAnnouncementWindow` 依然保持可见,你可以考虑使用 `Qt.Wind ...

'
    def createAnnouncementWindow(self):    # 创建公告窗口
        self.announcementWindow = AnnouncementWindow(self.mdi_area)
        self.subWindow = self.mdi_area.addSubWindow(self.announcementWindow)
        self.subWindow.setWindowFlags(Qt.Tool | Qt.WindowStaysOnTopHint)
        self.subWindow.show()
        self.subWindow.destroyed.connect(self.subWindowDestroyed)  # 监听子
'
可以了,但是我有一点不明白,在createAnnouncementWindow函数中设置一次self.subWindow.setWindowFlags(Qt.Tool | Qt.WindowStaysOnTopHint)就有效果,为什么要在AnnouncementWindow类中在设置一次,这样有什么好处吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-1-17 11:08:22 | 显示全部楼层
rxts 发表于 2025-01-17 11:07
FishC 发表于 2025-1-17 10:42
如果希望在有多个子窗 ...


在 `createAnnouncementWindow` 函数中,您已经通过 `self.subWindow.setWindowFlags(Qt.Tool | Qt.WindowStaysOnTopHint)` 设置了子窗口的窗口标志,这是为了确保子窗口在创建时具有指定的属性。

在 `AnnouncementWindow` 类中再次设置窗口标志通常是为了在特殊情况下应用此类标志。例如,假设 `AnnouncementWindow` 类可能在其他上下文中使用,并且在某些情况下需要保持在顶部,那么直接在类中设置 `Qt.Tool | Qt.WindowStaysOnTopHint` 就很方便。

但是,如果 `AnnouncementWindow` 仅在当前场景中使用,并且其行为完全由 `createAnnouncementWindow` 函数控制,您可以只在 `createAnnouncementWindow` 中设置标志。在此情况下,直接在 `AnnouncementWindow` 类中设置标志并无特别必要。这只是一种冗余的保险。

总结来说:

  • 在 `createAnnouncementWindow` 中设置一次通常已经足够。
  • 在 `AnnouncementWindow` 中设置用于多次复用该类且需要相同窗口标志的场景。


以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-17 11:44:56 | 显示全部楼层
FishC 发表于 2025-1-17 11:08
在 `createAnnouncementWindow` 函数中,您已经通过 `self.subWindow.setWindowFlags(Qt.Tool | Qt.Win ...

明白了,多谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-1-17 11:45:15 | 显示全部楼层
rxts 发表于 2025-01-17 11:44
FishC 发表于 2025-1-17 11:08
在 `createAnnounceme ...


不客气!如果您还有其他问题或需要进一步的帮助,请随时提问。随时乐意为您提供支持!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-2-5 14:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表