鱼C论坛

 找回密码
 立即注册
查看: 325|回复: 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()
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

可以将子窗口设置为 Qt.Tool 窗口类型。这样子窗口不会抢占主窗口的焦点,同时满足其他要求。您可以尝试以下修改:

  1. from PySide6.QtWidgets import QApplication, QMainWindow, QMdiArea, QToolWindow, QWidget, QVBoxLayout, QLabel


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


  10. class MainWindowA(QMainWindow):
  11.     def __init__(self, parent=None):
  12.         super().__init__(parent)
  13.         self.mdi_area = QMdiArea(self)
  14.         self.setCentralWidget(self.mdi_area)
  15.         self.init_ui()

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

  22.         self.createAnnouncementWindow()

  23.     def resizeEvent(self, event):
  24.         super().resizeEvent(event)
  25.         new_size = event.size()
  26.         self.width = new_size.width()
  27.         self.height = new_size.height()

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

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

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

  42.     def subWindowDestroyed(self):
  43.         self.subWindow = None

  44.     def toggleSubWindow(self):
  45.         if self.subWindow is None:
  46.             self.createAnnouncementWindow()
  47.             self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
  48.             self.subWindow.move(0, int(self.height * 0.8))
  49.         elif self.subWindow.isVisible():
  50.             self.subWindow.hide()
  51.         else:
  52.             self.subWindow.show()
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

我试了,当只有一个子窗口createAnnouncementWindow时,没有问题,但是有多个子窗口时,我与其他子窗口互动时,createAnnouncementWindow会被隐藏
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

可以按照以下方式进行设置:

  1. from PySide6.QtWidgets import QMainWindow, QMdiArea, QWidget, QVBoxLayout, QLabel, QApplication
  2. from PySide6.QtCore import Qt

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

  11. class MainWindowA(QMainWindow):
  12.     def __init__(self, parent=None):
  13.         super().__init__(parent)
  14.         self.mdi_area = QMdiArea(self)
  15.         self.setCentralWidget(self.mdi_area)
  16.         self.init_ui()

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

  23.         self.createAnnouncementWindow()

  24.     def resizeEvent(self, event):
  25.         super().resizeEvent(event)
  26.         new_size = event.size()
  27.         self.width = new_size.width()
  28.         self.height = new_size.height()

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

  34.     def createAnnouncementWindow(self):
  35.         self.announcementWindow = AnnouncementWindow(self)
  36.         self.subWindow = self.mdi_area.addSubWindow(self.announcementWindow)
  37.         self.subWindow.setWindowFlags(Qt.Tool | Qt.WindowStaysOnTopHint)
  38.         self.subWindow.show()
  39.         self.subWindow.destroyed.connect(self.subWindowDestroyed)

  40.     def subWindowDestroyed(self):
  41.         self.subWindow = None

  42.     def toggleSubWindow(self):
  43.         if self.subWindow is None:
  44.             self.createAnnouncementWindow()
  45.             self.subWindow.resize(int(self.width * 0.75), int(self.height * 0.169))
  46.             self.subWindow.move(0, int(self.height * 0.8))
  47.         elif self.subWindow.isVisible():
  48.             self.subWindow.hide()
  49.         else:
  50.             self.subWindow.show()

  51. if __name__ == '__main__':
  52.     app = QApplication([])
  53.     window = MainWindowA()
  54.     window.show()
  55.     app.exec()
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://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类中在设置一次,这样有什么好处吗?
小甲鱼最新课程 -> https://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 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

明白了,多谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-6 07:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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