You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:QDialog执行一次查找后关闭,如何保持打开并持续搜索QPlainTextEdit

解决QDialog查找后关闭的问题,实现类似记事本的持久查找窗口

问题核心是你用了exec()模态对话框,调用accept()会直接关闭窗口。要实现记事本那样保持查找窗口打开、多次执行查找的效果,需要改用非模态对话框+信号传递的方式,让对话框通知主窗口执行查找操作,而不是关闭对话框。

修改后的代码

MainWindow部分

from PyQt5.QtWidgets import QMainWindow, QClipboard
from PyQt5.QtCore import Qt

class MainWindow(QMainWindow, Ui_Widget):
    def __init__(self, app):  # 修正原代码笔误:类构造函数必须是__init__
        super().__init__()
        self.app = app
        self.setupUi(self)
        self.setWindowTitle("Untitled - Notepad")
        self.actionFind.triggered.connect(self.open_find_dialog)
        self.find_dialog = None  # 保存对话框实例,避免被垃圾回收

    def open_find_dialog(self):
        # 获取选中文本或剪贴板文本作为初始搜索内容
        cursor = self.plainTextEdit.textCursor()
        selected_text = cursor.selectedText()
        init_text = selected_text if selected_text else QClipboard().text(QClipboard.Clipboard)

        # 复用已打开的对话框,避免重复创建
        if not self.find_dialog or not self.find_dialog.isVisible():
            self.find_dialog = FindDialog(init_text)
            self.find_dialog.find_next_requested.connect(self.perform_find)
            self.find_dialog.show()
        else:
            self.find_dialog.activateWindow()

    def perform_find(self, search_text):
        # 执行查找,开启循环匹配
        self.plainTextEdit.find(search_text, Qt.MatchWrap)

FindDialog部分

from PyQt5.QtWidgets import QDialog
from PyQt5.QtCore import pyqtSignal

class FindDialog(QDialog, Ui_FindDialog):
    # 定义信号,用于向主窗口传递搜索文本
    find_next_requested = pyqtSignal(str)

    def __init__(self, text):  # 修正原代码笔误:类构造函数必须是__init__
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle("Find")
        self.search_text = text

        # 按钮信号连接
        self.f_find_next_pushButton.clicked.connect(self.emit_find_signal)
        self.f_cancel_find_pushButton.clicked.connect(self.close)

        self.f_search_lineEdit.setText(self.search_text)

    def emit_find_signal(self):
        # 获取输入框文本并发射信号,不关闭对话框
        current_text = self.f_search_lineEdit.text().strip()
        if current_text:
            self.search_text = current_text
            self.find_next_requested.emit(self.search_text)

关键修改点说明

  • 修正构造函数:原代码中的init是语法错误,Python类构造函数必须写为__init__才能正确初始化。
  • 非模态对话框:用show()替代exec(),对话框不会阻塞主窗口,且保持打开状态。
  • 信号传递机制:在FindDialog中定义find_next_requested信号,点击“查找下一个”时发射信号,主窗口接收后执行查找,避免关闭对话框。
  • 对话框复用:主窗口中保存对话框实例,再次点击“查找”时直接激活已有窗口,避免重复创建。

内容的提问来源于stack exchange,提问作者Sayan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 11:38:18