如何为QTextEdit的contextMenuEvent通过循环添加正确响应的QAction
问题解决思路
这是典型的闭包延迟绑定问题,和你用不用字典存储action无关——循环里的lambda并没有在创建时捕获当前的i值,而是等到信号触发时才去读取i的当前状态,此时循环已经执行完毕,i固定为最后一次循环的数值(也就是10),所以所有action触发时都会用最后一个建议词。
两种可行的解决方法:
方法1:给lambda添加默认参数,固定当前建议词
利用Python函数默认参数在定义时求值的特性,把当前循环的建议词提前绑定到lambda中:
for i in range(11): # 取前10个建议(索引0-10) action = QAction(suggestions[i].term) # 注意:triggered信号会传递一个checked布尔值,lambda需要接收该参数 action.triggered.connect(lambda checked, term=suggestions[i].term: self.replace_word(cursor, term)) menu.addAction(action)
方法2:使用functools.partial绑定参数
用functools.partial预先把replace_word的参数固定,避免闭包的延迟绑定问题:
from functools import partial for i in range(11): action = QAction(suggestions[i].term) # 预先绑定cursor和当前建议词到replace_word action.triggered.connect(partial(self.replace_word, cursor, suggestions[i].term)) menu.addAction(action)
补充:修正replace_word方法的小问题
你当前的replace_word方法中,self.textCursor()每次调用都会返回新的光标对象,修改它不会直接作用于编辑器的光标,建议直接使用传入的cursor操作:
def replace_word(self, cursor, term): cursor.removeSelectedText() cursor.insertText(term) self.setTextCursor(cursor)
内容的提问来源于stack exchange,提问作者Jeremy Wilson
相关产品推荐
相关产品推荐

