日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Helper辅助类设计技巧

發布時間:2023/12/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Helper辅助类设计技巧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Helper輔助類設計技巧

  • Helper輔助類設計技巧
    • 需求
    • 基礎版
    • 進階版
    • Helper版
    • 優化改進

需求

當點擊一個按鈕后,執行功能代碼。按鈕文字為“執行”,代碼執行成功后按鈕閃爍顯示“成功”,失敗閃爍顯示“失敗”。閃爍完成后還原顯示“執行”。

注:平臺為Qt。

基礎版

按照常規思路,點擊按鈕后,設置按鈕文字,啟動一個定時器。在定時器中刷新按鈕字體顏色,記錄定時器執行次數,完成后還原按鈕文字。廢話少說,上代碼:

class MainWindow : public QMainWindow {Q_OBJECT public:MainWindow(QWidget *parent = 0):QMainWindow(parent){ui.setupUi(this);}~MainWindow(){}private slots:void on_pushButton_clicked(){bool success = true;ui.pushButton->setText(success ? "成功" : "失敗");m_times = 10;flash();}void flash(){static bool b = true;b = !b;m_times--;if (m_times > 0){ui.pushButton->setStyleSheet(b ? "color:red;" : "color:blue;");QTimer::singleShot(100, this, SLOT(flash()));}else{ui.pushButton->setText("執行");ui.pushButton->setStyleSheet( "");}}private:Ui::MainWindowClass ui;int m_times; };

進階版

上面的代碼能夠很好地工作,但是卻存在幾個問題:

  • 如果另外一個按鈕也需要同樣的功能,我們必須再次寫同樣的代碼,代碼量線性增加。
  • 如果這些代碼有bug,修復bug的代碼是成線性關系的。

針對這個問題,我們第一直覺當然是實現一個可以有閃爍功能的按鈕類:

class FlashButton :public QPushButton {Q_OBJECT public:FlashButton(QWidget* parent = nullptr):QPushButton(parent){}public slots:void flash(const QString& text){m_times = 10;m_srcText = this->text();flash();}private slots:void flash(){static bool b = true;b = !b;m_times--;if (m_times > 0){this->setStyleSheet(b ? "color:red;" : "color:blue;");QTimer::singleShot(100, this, SLOT(flash()));}else{this->setStyleSheet("");setText(m_srcText);}}private:int m_times;QString m_srcText; };

然后之前的代碼就像這樣:

class MainWindow : public QMainWindow {Q_OBJECT public:MainWindow(QWidget *parent = 0):QMainWindow(parent){ui.setupUi(this);m_button = new FlashButton(this);m_button->setText("執行");ui.verticalLayout->addWidget(m_button);}~MainWindow(){}private slots:void on_pushButton_clicked(){bool success = true;m_button->flash(success ? "成功" : "失敗");}private:Ui::MainWindowClass ui;FlashButton* m_button; };

相比基礎版,主程序的代碼少了許多,并且邏輯也更清晰。最重要的是解決了基礎版存在的問題。

Helper版

但是,進階版的代碼同樣存在一些問題:

  • 我們只能在代碼中創建我們的按鈕,沒法在Qt Designer中進行布局,這是一件很不爽的事情。
  • 對于現有的代碼,我們想增加此功能的代碼也很大,尤其是需要修改的按鈕如果也是一個QPushButton的子類的時候。

那如果很好地解決這些問題呢?叮咚,Helper版閃亮登場!

class FlashButtonHelper : public QObject {Q_OBJECT public:FlashButtonHelper(QPushButton* button):QObject(button), m_button(button){}public slots :void flash(const QString& text){m_times = 10;m_srcText = m_button->text();flash();}private slots:void flash(){static bool b = true;b = !b;m_times--;if (m_times > 0){m_button->setStyleSheet(b ? "color:red;" : "color:blue;");QTimer::singleShot(100, this, SLOT(flash()));}else{m_button->setStyleSheet("");m_button->setText(m_srcText);}}private:QPushButton* m_button;int m_times;QString m_srcText; }; class MainWindow : public QMainWindow {Q_OBJECT public:MainWindow(QWidget *parent = 0):QMainWindow(parent){ui.setupUi(this);}~MainWindow(){}private slots:void on_pushButton_clicked(){bool success = true;FlashButtonHelper* flasher = new FlashButtonHelper(ui.pushButton);flasher->flash(success ? "成功" : "失敗");}private:Ui::MainWindowClass ui; };

這樣我們又可以在Qt Designer中愉快地進行界面布局了,并且如果需要對現有代碼增加功能,我們需要做的工作是否簡單,在需要的地方添加如下代碼即可:

FlashButtonHelper* flasher = new FlashButtonHelper(button); flasher->flash("成功");

優化改進

對于大項目,很多時候需要對代碼精雕細琢。在上面的代碼中,如果我們點擊按鈕100次,那么就會有100個Helper類創建,這并不是我們想要的。因為其實只需要一個Helper即可(當然可以在適當的時候銷毀,但是我們并不想在主程序中增加代碼)。單例類為我們提供了解決思路,創建是首先判斷對象是否存在,存在則返回存在的的對象即可:

class FlashButtonHelper : public QObject{Q_OBJECT public:~FlashButtonHelper(){ instances()->remove(m_button); }static FlashButtonHelper* getInstance(QPushButton* obj){if (!instances()->contains(obj)){(*instances())[obj] = new FlashButtonHelper(obj);}return (*instances())[obj];}public slots :void flash(const QString& text){m_times = 10;m_srcText = m_button->text();flash();}private slots:void flash(){static bool b = true;b = !b;m_times--;if (m_times > 0){m_button->setStyleSheet(b ? "color:red;" : "color:blue;");QTimer::singleShot(100, this, SLOT(flash()));}else{m_button->setStyleSheet("");m_button->setText(m_srcText);}}private:FlashButtonHelper(QPushButton* button): QObject(button), m_button(button){}static QHash<QPushButton*, FlashButtonHelper*>* instances(){static QHash<QPushButton*, FlashButtonHelper*> s_instances;return &s_instances;} private:QPushButton* m_button;int m_times;QString m_srcText; };#define FLASH_HELPER(btn) FlashButtonHelper::getInstance(btn) class MainWindow : public QMainWindow {Q_OBJECT public:MainWindow(QWidget *parent = 0):QMainWindow(parent){ui.setupUi(this);}~MainWindow(){}private slots:void on_pushButton_clicked(){bool success = true;FLASH_HELPER(ui.pushButton)->flash(success ? "成功" : "失敗");}private:Ui::MainWindowClass ui; };

關鍵點:

  • 采用靜態hash表保存所有的Helper對象。
  • Helper構造函數將自己加入hash表,析構時從hash表中移除。
  • Helper構造函數私有化,由getInstance執行是否創建Helper對象。
  • Helper采用Qt的QObject進行內存管理。在目標對象銷毀時自動銷毀自己。
  • 定義了FLASH_HELPER讓代碼更易讀。

結語:上面的FlashHelper基本上就是一個Helper類的標準模板。俺就是拋磚一下,相信大家可以舉一反三,設計更多的屬于自己的優雅的Helper了。

總結

以上是生活随笔為你收集整理的Helper辅助类设计技巧的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。