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);
    }
}
View Code

接下来第二点。鼠标点击到widget的其他区域,也就意味着QLineEdit失去了当前的焦点,所以可以重新实现QLineEdit的focuseOutEvent()函数。在该函数中,clearFocus()清除焦点,close()关闭MyEdit(继承自QLineEdit)。代码和效果如下

void MyEdit::focusOutEvent(QFocusEvent *event)
{
    clearFocus();
    close();
    QLineEdit::focusOutEvent(event);
}
View Code

最后实现第三点。方法还是实现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);
}
View Code

在MyButton中,定义一个槽函数来接收MyEdit发送的信号,周期槽函数中直接更改Button的名字即可。因为是样例,所以没有加上判断是否输入为空的情况。代码如下

void MyButton::ReName()
{
    this->setText(edit->Text);
    edit->clear();
}
View Code

全部的工程在这里,留着备用。

关于双击其实还有一种操作,那就是重新实现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);
}
View Code

 

posted on 2015-04-29 23:33  cha1992  阅读(5080)  评论(0编辑  收藏  举报

导航