現在的軟件很多都支持雙擊重命名的操作,就像在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); }