司开星的博客

QLineEdit实现点击全选文本

最近收到一个需求:希望实现点击一个QLineEdit全文其中的文本。QLineEdit没有点击信号,要实现这个功能需要自己写方法。

需求

最近写的软件包含一个简单的网页浏览器的部分,其中地址栏用的标准QLineEdit。另外界面文件是用Qt Designer画的,代码中直接引用UI文件。这样修改界面比较直观。

现在有个需求,希望点击地址栏的QLineEdit时直接全选地址,效果类似chrome浏览器地址栏的点击效果。

解决办法

翻了一下QLineEdit的自带信号,并没有单击的信号。

网上搜索了一下,基本上都是说要重写QLineEdit的方法。但是由于我的界面.ui文件,要重写方法只能先把.ui转换成.py。

转换方法:

pyuic4 -i 0 MyWindow.ui -o MyWindow.py

在安装pyqt4之后命令行中就能使用pyuic4命令。具体参数的含义这里暂时不深究。

转换之后需要在源码中引用新生成的py文件。将之前的引用ui文件的代码:

1
2
3
4
5
from PyQt4.uic import loadUiType 

qtCreatorFile = "MyWindow.ui"

Ui_MainWindow, QtBaseClass = loadUiType(qtCreatorFile)

修改为:

1
from MyWindow import Ui_MainWindow

之后就是重写QLineEdit类了。这里有个问题:QLineEdit有两个相关的方法可以被重写:mousePressEvent()focusInEvent() 。一开始笔者重写了focusInEvent ():

1
2
3
def focusInEvent(self, event):
self.setText("www")
self.selectAll()

但测试时发现setText()有效果,但selectAll()没有效果。搜索之后发现如下回答:

With focusInEvent, when you click the widget, it gets executed, but since you click, it removes the selected text.

也就是focusInEvent() 会自动移除选中效果。换成重写 mousePressEvent()后即可正常实现。

更好的办法

在之前的问题回答下不仅回答了重写mousePressEvent() ,还提供了另一个更方便的解决方式:

1
2
txt_demo = QtGui.QLineEdit()
txt_demo.mousePressEvent = lambda _ : txt_demo.selectAll()

即使用匿名函数重写实例的方法,这样不需要修改类。

后来搜索了一下,这种写法算给实例动态添加方法。

参考资料:

  1. 使用Designer编写PyQt程序的简单流程
  2. Pyside - Select all text when QLineEdit gets focus