很多时候我们会发现输入的一长串内容不得不全部删除重新输入,这时比起一直按着退格键不放一个清除内容按钮更受欢迎。
今天我将介绍三种为QLineEdit添加清除内容按钮的方法,其中两种方法有较强的功能针对性,另一种方法则是通用的,不仅可以用来实现清除输入内容,还可以扩展出其他功能。
本文索引 方法1:setClearButtonEnabled显示清除按钮这是Qt5.2之后提供的方法,当使用了setClearButtonEnabled(true);之后会在 QLineEdit的右侧显示一个图标为QStyle::SP_DialogResetButto的QAction,点击后会清除输入内容:
// 方案1 auto edit1 = new QLineEdit; edit1->setClearButtonEnabled(true);效果:
看到右边那个图标,如果是Qt自带的话会是一个类似扫把的图形,如果使用了系统主题那么会有些许差异,点击它,输入内容就会全部清除。
方法2:使用QAction实现清除按钮如前所述,setClearButtonEnabled其实只是让实现存在的QAction显示出来而已,所以我们也可以自己实现这一过程。
要实现这一功能,需要Qt5.2之后提供的addAction方法。它负责把一个QAction添加到edit的指定位置。
不过要注意的是,这个QAction只能显示出图标,文字内容的显示不出的。
// 方案2 auto clearAction = new QAction; clearAction->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogResetButton)); auto edit2 = new QLineEdit; // QLineEdit::TrailingPosition表示将action放置在右边 edit2->addAction(clearAction, QLineEdit::TrailingPosition); QObject::connect(clearAction, &QAction::triggered, edit2, [edit2]{ edit2->setText(""); });因为我们知道lineedit默认使用的清除按钮的图标,也知道如何清除输入,所以可以自己实现这一过程。
这是效果,与方法1时几乎没什么区别:
不过方法二的威力不止于此,基于我们可以使用自己的QAction,那么就可以定制一些操作,比如使用我们自己的图标:
clearAction->setIcon(QIcon(":/clear.png"));这种方法相比前一种略显复杂,然而却提供了更好的扩展性。
接下来要介绍的最后一种方法更加的灵活,你不仅可以显示自定义图标,还可以显示自定义文字,当然作为代价它比第二种方法要复杂不少。
方法3:自定义QLineEdit为其添加按钮这种方法对Qt的版本没有什么要求,所以它也足够通用。
想要在QLineEdit上添加一个widget一点也不复杂,首先我们要弄清以下几个原理:
qt的widget和layout是可以堆叠的,之前在实现半透明遮罩中有提过
你可以为QLineEdit设置layout,如你所料layout会堆叠在edit的输入框上
edit的layout会只使用控件的最小尺寸,这样不会导致将整个输入框遮盖掉
edit的可输入区域是可以设置的,你可以合理的设置输入区的大小避免文字进入layout之下被遮盖
所以如果我们想为QLineEdit或是其派生类添加一个widget比如QPushButton,那么需要如下几部:
创建你需要的widget以及一个布局管理器
添加拉伸因子和widget至布局管理器,拉伸因子可以不添加,只要设置好布局管理器的排列方向即可
设置布局管理器里组件的排列方向并把布局管理器添加到QLineEdit
获取你添加的widget的宽度,然后在加上合适的边框距离,将QLineEdit的输入区域限制在合理的大小
说起来简单做起来难,我们边看代码边讲解。
我们先看类的定义,ButtonEdit是一个带有按钮的QLineEdit:
#include <QWidget> #include <QLineEdit> #include <QPushButton> #include <QString> #include <QIcon> class ButtonEdit: public QLineEdit { Q_OBJECT public: explicit ButtonEdit(const QString &btnText, QWidget *parent = nullptr); explicit ButtonEdit(const QIcon &icon, QWidget *parent = nullptr); ~ButtonEdit() override = default; private: // 设置文本按钮或图标按钮的大小和外观 void setTextButton(); void setIconButton(); // 将按钮添加到edit void addButton(); QPushButton *button; Q_SIGNALS: void buttonClicked(bool); }; // 按钮和输入内容的边距 constexpr int buttonMargin = 3;我们的类可以从一个string或者icon构建,当edit的按钮被点击那么我们就发出buttonClicked信号。