即时文本搜索 / 新信号发出时中断

0 投票
1 回答
534 浏览
提问于 2025-04-18 03:29

我在用PyQt4做一个即时搜索功能,利用的是QLineEdit里的textChanged信号。

搜索的速度还不错,但更新QTextEdit显示结果的时候有点慢(或者说我写的那个生成输出字符串的函数比较慢)。有没有办法让搜索稍微延迟一下,或者在一定时间内如果又发出了新的textChanged信号就中断之前的搜索呢?这样可以避免在搜索框里输入时,输入变得卡顿。

或者有没有其他的建议来解决这个问题?也许不需要用到线程……

基本上代码看起来是这样的:

class MyApp(..):

    def __init__(self):
        ....

        self.central.editSearch.textChanged.connect(self.search_instant)

    def search_instant(self, query):
        # skip strings with less than 3 chars
        if len(query) < 3:
            return
        self.search()

    def search(self)
        ... search in lots of strings ...
        self.central.myTextEdit.setText(result)
        # reimplemented function building the output

好的,这里是我根据谷歌示例做的,peakxu建议的:

class MyApp(..):

    def __init__(self):
        ....

        self.central.editSearch.textChanged.connect(self.search_instant)

        # Timer for instant search
        # Signal is emitted 500 ms after timer was started
        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.timer.setInterval(500)
        self.timer.timeout.connect(self.search)


    def search_instant(self, query):
        # Stop timer (if its running)
        self.timer.stop()

        # skip strings with less than 3 chars
        if len(query) < 3:
            return

        # Start the timer
        self.timer.start()    

    def search(self)
        # The search will only performed if typing paused for at least 500 ms
        # i. e. no `textChanged` signal was emitted for 500 ms
        ... search in lots of strings ...
        self.central.myTextEdit.setText(result)
        # reimplemented function building the output

1 个回答

2

你可以考虑几个替代方案。

  1. 让搜索在一个独立的线程中运行,如果需要的话可以中断它。可以参考这个链接:https://qt-project.org/forums/viewthread/16109
  2. 在之前的搜索完成之前,先阻止信号的发送。详细信息可以查看这个链接:http://qt-project.org/doc/qt-4.8/qobject.html#blockSignals
  3. 自己写一个防抖动的包装函数来处理搜索功能。

目前来看,第一个选项听起来是最好的。

更新: 这个 Qt Google Suggest 示例 可能会对你有帮助。他们使用了一个 QTimer 来跟踪用户输入之间的时间。

撰写回答