Qt之控件重命名
现在的软件很多都支持双击重命名的操作,就像在windows下对某个文件夹重命名一样(如下图)
不巧之前也遇到过类似的设计问题,不过是在界面上对某个控件。现在整理一下,控件就用QPushButton来代替。
对一个Button双击重命名,其实总结起来就是一下几点:
1、鼠标双击开始重命名,也就是一个QLineEdit完全覆盖之前的Button
2、鼠标点击其他区域,退出重命名状态,保留之前的名字
3、按下键盘的回车键,完成重命名操作,显示新的名字
下面开始一步一步来。
首先第一点。一个Button能够支持鼠标的双击操作,那肯定是必须重写mouseDoubleClickEvent()这个函数,于是自定义一个子类MyButton,继承自QPushButton,重新实现那个函数。在函数体中,检测是否是鼠标左键按下(因为双击鼠标左键触发重命名),然后显示一个QlineEdit(暂时是它,后面还要改变),同时指定它的父类是MyButton,大小与MyButton一样,就可以完全覆盖之前的Button。QLineEdit中的selectAll()函数可以全选当前内容,当然最后不能忘记调用QPushButton本身的mouseDoubleClickEvent()。代码和实现的效果如下
void MyButton::mouseDoubleClickEvent(QMouseEvent *event) { if(event->button()==Qt::LeftButton) { edit->setParent(this); QString ButtonText = this->text(); edit->setText(ButtonText); edit->resize(this->size()); edit->show(); edit->setFocus(); edit->selectAll(); QPushButton::mouseDoubleClickEvent(event); } }
接下来第二点。鼠标点击到widget的其他区域,也就意味着QLineEdit失去了当前的焦点,所以可以重新实现QLineEdit的focuseOutEvent()函数。在该函数中,clearFocus()清除焦点,close()关闭MyEdit(继承自QLineEdit)。代码和效果如下
void MyEdit::focusOutEvent(QFocusEvent *event) { clearFocus(); close(); QLineEdit::focusOutEvent(event); }
最后实现第三点。方法还是实现QLineEdit中的keyPressEvent()函数。检测按键是否是满足要求的按键,如果是,则保存edit中的内容,并发送信号给MyButon,在MyButton中更改名字。
Qt中的回车键有两个(其实键盘上也是两个),两个标号不一样,这里需要注意。代码如下
void MyEdit::keyPressEvent(QKeyEvent *event) { if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { Text = this->text(); close(); emit renamefinished(); } QLineEdit::keyPressEvent(event); }
在MyButton中,定义一个槽函数来接收MyEdit发送的信号,周期槽函数中直接更改Button的名字即可。因为是样例,所以没有加上判断是否输入为空的情况。代码如下
void MyButton::ReName() { this->setText(edit->Text); edit->clear(); }
全部的工程在这里,留着备用。
关于双击其实还有一种操作,那就是重新实现mousePressEvent()函数,定义一个定时器,同时自定义双击间隔(例如300ms)。当鼠标点击Button时,通过判断定时器是否工作来决定这是第一按下还是第二次按下。如果是双击,即300ms内连续两次按下Button,那么第一次按下时定时器肯定不在工作,此时启动定时器,并设置溢出时间为300ms;第二次按下时,停止定时器,同时标志出双击事件。如果300ms内没有第二次按下Button,定时器溢出,定义相关的槽函数,就可以实现单击事件。这是一种区别单击事件和双击事件的有效方法,尤其在需要同时实现一个控件的双击和单击事件时。相关的代码如下
void MyButton::mousePressEvent(QMouseEvent *event) { if(event->button()==Qt::LeftButton) { if(!timer->isActive()) timer->start(300); //双击最大间隔为300ms else timer->stop(); } QPushButton::mousePressEvent(event); }