PyQt5 QMdiArea多子窗口批量选中与指针获取技术问询
实现QMdiArea多子窗口Ctrl选中功能
嘿,要实现按住Ctrl键选中多个子窗口的需求,我们可以通过给QMdiArea添加事件过滤来跟踪鼠标点击事件,结合Ctrl键的状态维护一个选中窗口列表。下面是修改后的完整代码,关键部分我都加了注释:
from PyQt5.QtWidgets import QApplication, QMainWindow, QMdiArea, QAction, QMdiSubWindow, QTextEdit from PyQt5.QtCore import Qt, QEvent import sys class MDIWindow(QMainWindow): count = 0 def __init__(self): super().__init__() self.mdi = QMdiArea() self.setCentralWidget(self.mdi) # 维护选中的子窗口列表 self.selected_windows = [] # 给QMdiArea安装事件过滤器,用来捕捉点击事件 self.mdi.installEventFilter(self) bar = self.menuBar() file = bar.addMenu("File") file.addAction("New") file.addAction("cascade") file.addAction("Tiled") file.addAction("selected_subwindows") file.triggered[QAction].connect(self.WindowTrig) self.setWindowTitle("MDI Application") def eventFilter(self, obj, event): # 只处理QMdiArea的鼠标左键点击事件 if obj == self.mdi and event.type() == QEvent.MouseButtonPress and event.button() == Qt.LeftButton: # 获取点击位置对应的子窗口 clicked_window = self.mdi.subWindowAt(event.pos()) if not clicked_window: return super().eventFilter(obj, event) # 检查是否按住了Ctrl键 ctrl_pressed = QApplication.keyboardModifiers() & Qt.ControlModifier if ctrl_pressed: # 如果按住Ctrl,切换该窗口的选中状态 if clicked_window in self.selected_windows: self.selected_windows.remove(clicked_window) # 取消选中的视觉反馈:恢复默认样式 clicked_window.setStyleSheet("") else: self.selected_windows.append(clicked_window) # 选中的视觉反馈:添加蓝色边框 clicked_window.setStyleSheet("QMdiSubWindow { border: 2px solid blue; }") else: # 没有按住Ctrl,清空之前的选中,只保留当前窗口 for win in self.selected_windows: win.setStyleSheet("") self.selected_windows = [clicked_window] clicked_window.setStyleSheet("QMdiSubWindow { border: 2px solid blue; }") # 将点击的窗口设为活跃窗口(可选,根据你的需求调整) self.mdi.setActiveSubWindow(clicked_window) return super().eventFilter(obj, event) def WindowTrig(self, p): if p.text() == "New": MDIWindow.count = MDIWindow.count + 1 sub = QMdiSubWindow() sub.setWidget(QTextEdit()) sub.setWindowTitle("Sub Window" + str(MDIWindow.count)) self.mdi.addSubWindow(sub) sub.show() if p.text() == "cascade": self.mdi.cascadeSubWindows() if p.text() == "Tiled": self.mdi.tileSubWindows() if p.text()=="selected_subwindows": # 打印选中窗口的指针 print("选中的窗口指针列表:") for idx, win in enumerate(self.selected_windows): print(f"窗口 {idx+1}: {win}") # 获取窗口内的QTextEdit部件 text_edit = win.widget() if isinstance(text_edit, QTextEdit): print(f" 窗口内文本内容预览: {text_edit.toPlainText()[:50]}...") # 只显示前50个字符 app = QApplication(sys.argv) mdi =MDIWindow() mdi.show() app.exec_()
关键功能说明:
- 选中状态管理:用
self.selected_windows列表保存所有选中的子窗口,按住Ctrl点击时切换窗口的选中状态,不按Ctrl时自动清空之前的选中记录,只保留当前点击的窗口。 - 视觉反馈:给选中的窗口添加蓝色边框,取消选中时恢复默认样式,让用户能直观看到哪些窗口处于选中状态。
- 子窗口部件访问:通过
win.widget()可以直接获取子窗口内的QTextEdit组件,后续你可以用它来做文本对比、内容同步等操作。 - 事件过滤机制:给
QMdiArea安装事件过滤器后,我们能精准捕捉到区域内的鼠标点击事件,从而判断用户点击的目标窗口,以及是否按住了Ctrl键。
这样修改后,你就可以按住Ctrl键点击多个子窗口,然后通过selected_subwindows菜单选项查看选中的窗口指针和对应的文本内容啦。
内容的提问来源于stack exchange,提问作者zezo
相关产品推荐
相关产品推荐

