QT QLineEdit 獲取焦點/獲取焦點后全選字符


為了實現  QLineEdit 獲取焦點/獲取焦點后全選字符的功能,在網上先查了 QLineEdit 獲取焦點的方法,有兩種:
1 此方法只有在窗體從失去焦點到獲取焦點時有作用:即窗體失去焦點后再次獲取焦點時,將焦點置於某個 QLineEdit 中。
 此功能明顯不是偶想要的!!! 但由於網上現有的文章都是一樣的,說的不是很清楚,所以只有試了才知道。
有三段代碼:
1) 在窗體初始化時增加如下代碼:

1     // QLineEdit 獲取焦點 1 - 此方法錯誤: 只有在窗體從失去焦點到獲取焦點時有作用
2     ui->ledSendStr->installEventFilter(this);
3     ui->ledSendFile->installEventFilter(this);
4     ui->ledSendPreTime->installEventFilter(this);

2) 在窗體的 .h 文件中聲明 SLOT,如下:

1 public slots:
2     bool eventFilter(QObject *,QEvent *);       // QLineEdit 獲取焦點 2

3) 實現的代碼

 1 // QLineEdit 獲取焦點 3
 2 bool MainWindow::eventFilter(QObject *watched, QEvent *event)
 3 {
 4     if(watched == ledSendStr)
 5     {
 6         if(QEvent::FocusIn == event->type())
 7         {
 8             qDebug() << "focus in";
 9             ledSendStr->selectAll();        // 不起使用,只有在窗體獲取到焦點時才有功能
10             ledSendStr->setFocus(Qt::OtherFocusReason);
11         }
12         else if(QEvent::FocusOut == event->type())
13         {
14             qDebug() << "focus out";
15         }
16     }
17     else if(watched == ledSendFile)
18     {
19     }
20     else if(watched == ledSendPreTime)
21     {
22     }
23     return QWidget::eventFilter(watched,event);     // 最后將事件交給上層對話框
24 }

 

2 繼承 QLineEdit, 再實現如下兩個 SIGNAL:
  virtual void focusInEvent(QFocusEvent *e);
  virtual void focusOutEvent(QFocusEvent *e);

1) 繼承類的聲明:

 1 #ifndef MYLINEEDIT_H
 2 #define MYLINEEDIT_H
 3 
 4 #include <QLineEdit>
 5 #include <QDebug>
 6 
 7 class MyLineEdit: public QLineEdit
 8 {
 9     Q_OBJECT
10 
11  public:
12     MyLineEdit(QWidget *parent=0);
13     ~MyLineEdit();
14 
15  protected:
16     virtual void focusInEvent(QFocusEvent *e);
17     virtual void focusOutEvent(QFocusEvent *e);
18 };
19 
20 #endif // MYLINEEDIT_H

2) 繼承類的實現:

 1 #include "myLineEdit.h"
 2 
 3 MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent)
 4 {
 5 }
 6 
 7 MyLineEdit::~MyLineEdit()
 8 {
 9 }
10 
11 void MyLineEdit::focusInEvent(QFocusEvent *e)
12 {
13     // qDebug() << "*MyLineEdit::focusInEvent" << this->objectName();
14 
15     QPalette pGreen = QPalette();
16     pGreen.setColor(QPalette::Base,Qt::gray);    //QPalette::Base 對可編輯輸入框有效,還有其他類型,具體的查看文檔
17     setPalette(pGreen);
18     
19     ledSendStr->selectAll();        // 不起使用,只有在窗體獲取到焦點時才有功能
20     ledSendStr->setFocus(Qt::OtherFocusReason);
21 }
22 
23 void MyLineEdit::focusOutEvent(QFocusEvent *e)
24 {
25     // qDebug() << "*MyLineEdit::focusOutEvent" << this->objectName();
26 
27     QPalette pWhite = QPalette();
28     pWhite.setColor(QPalette::Base,Qt::white);
29     setPalette(pWhite);
30 }

3) 使用 MyLineEdit 類定義控件,並完成布局。
測試運行發現,3) 中定義的控件隨着焦點的獲取/失去顏色會發生變化,但全選字符串的功能卻無效!
但如果在如下代碼:

1 ledSendStr->selectAll();
2 ledSendStr->setFocus(Qt::OtherFocusReason);

放在一個按鍵的 Clicked 槽中就可以實現全選字符串的功能。 為什么無效呢???原因不知道,想到的區別就是同樣的代碼,一個是在 MainWindow 中、而另一個是在 myLineEdit 中。

試着將 Focus Get/Lost 動作放到 MainWindow 中響應:通過 SIGNAL/SLOT 來實現。 1) 在繼承類的聲明中增加如下代碼:

1 signals:
2     void selectAllWhenFocus(QString strCtrlName);

2) 在繼承類實現的 void MyLineEdit::focusInEvent(QFocusEvent *e) 函數中增加如下代碼:

1 emit selectAllWhenFocus(this->objectName());

3) 在 MainWindow 的 .h 文件中增加如下代碼:

1 public slots:
2     void selectAllWhenFocusSlot(QString strCtrlName);

4) 在 MainWindow 的源代碼中增加如下代碼:

1 void MainWindow::selectAllWhenFocusSlot(QString strCtrlName)
2 {
3     // qDebug() << "Main Windows: " << strCtrlName;
4 
5     ledSendStr->selectAll();
6     ledSendStr->setFocus(Qt::OtherFocusReason);
7 }

但發現一樣無法實現全選控件中字符串的功能。 無語......

最后無奈下想到延時一下,再做全選的動作。修改上述第四步的代碼如下:

 1 void MainWindow::selectAllWhenFocusSlot(QString strCtrlName)
 2 {
 3     // qDebug() << "Main Windows: " << strCtrlName;
 4 
 5     m_strCtrlName = strCtrlName;
 6     if(NULL != m_timerDelaySelect)
 7     {
 8         if(m_timerDelaySelect->isActive())
 9         {
10             m_timerDelaySelect->stop();
11         }
12         delete m_timerDelaySelect;
13         m_timerDelaySelect = NULL;
14     }
15     m_timerDelaySelect = new QTimer(this);
16     //新建定時器
17     connect(m_timerDelaySelect,SIGNAL(timeout()),this,SLOT(timerUpDateSeleceAll()));
18     m_timerDelaySelect->start(200);
19 }

和延時超時的處理函數:

 1 void MainWindow::timerUpDateSeleceAll()
 2 {
 3     if(m_strCtrlName == "ledSendPreTime")
 4     {
 5         ledSendPreTime->selectAll();
 6         ledSendPreTime->setFocus(Qt::OtherFocusReason);
 7     }
 8     else if(m_strCtrlName == "ledSendStr")
 9     {
10         ledSendStr->selectAll();
11         ledSendStr->setFocus(Qt::OtherFocusReason);
12     }
13     else if(m_strCtrlName == "ledSendFile")
14     {
15         ledSendFile->selectAll();
16         ledSendFile->setFocus(Qt::OtherFocusReason);
17     }
18 
19     if(NULL != m_timerDelaySelect)
20     {
21         if(m_timerDelaySelect->isActive())
22         {
23             m_timerDelaySelect->stop();
24         }
25         delete m_timerDelaySelect;
26         m_timerDelaySelect = NULL;
27     }
28 }

發現這樣全選控件中文符串的功能竟然實現了!!!

在實現上述功能時,遇到的第一個問題其實不是代碼,而不是 Layout 的問題: 之前所有控件是“拖”出來的,然后進行了 Layout 處理。忽然發現按上述修改,使用 MyLineEdit 類定義的第個控件是在代碼中定義的,無法像之前一樣“拖”到窗體中、並完成 Layout! 還好 QT 的代碼  Layout 功能比較強大。最后兩者結合才完成了想要的窗體 Layout。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM