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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++链式继承

發布時間:2023/11/27 生活经验 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++链式继承 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??????? 繼承,對于學習C++的每一個人來說,都不會陌生。在Qt的開發中,如果你需要對一個無邊框的界面支持move操作,那么你就得通過繼承重寫虛函數來實現,這并不難,但如果我還需要對一個按鈕支持移動,一般情況,當然是Crtl + c 、Crtl + v搞定,但我們不難發現,對于move這個操作來說,其實代碼完全一模一樣,那么有沒有什么辦法可以簡化,可以一勞永逸呢?

??????? 答案是肯定的,這里我們就需要用到C++的模板來實現了,即本文要介紹的鏈式繼承。

??????? 前面有實現過move操作,這里將它抽取出來,代碼如下:

  1: #include <QWidget>
  2: #include <QMouseEvent>
  3: #include <QPoint>
  4: 
  5: //T 為基類,繼續擁有一個QWidget *parent參數的構造函數
  6: template <typename T>
  7: class WidgetMove : public T
  8: {
  9: public:
 10:     WidgetMove(QWidget *parent = 0):T(parent)
 11:     {
 12:     }
 13: protected:
 14:     void mousePressEvent(QMouseEvent *event)
 15:     {
 16:         //當鼠標左鍵按下時,記錄當前位置
 17:         if(event->button() == Qt::LeftButton)
 18:         {
 19:             m_CurrentPos = event->globalPos() - T::frameGeometry().topLeft();
 20:             event->accept();
 21:         }
 22:         T::mousePressEvent(event);
 23:     }
 24: 
 25:     void mouseMoveEvent(QMouseEvent *event)
 26:     {
 27:         //支持窗體移動
 28:         if (event->buttons() & Qt::LeftButton)
 29:         {
 30:             T::move(event->globalPos() - m_CurrentPos);
 31:             event->accept();
 32:         }
 33:         T::mouseMoveEvent(event);
 34:     }
 35: private:
 36:     QPoint m_CurrentPos;
 37: };

?

接下來我們實現一個圖片按鈕:

  1: #include <QPushButton>
  2: #include "widgetmove.h"
  3: 
  4: //間接繼承QPushButton,讓按鈕支持移動
  5: class ImgButton : public QPushButton
  6: {
  7:     Q_OBJECT
  8: public:
  9:     explicit ImgButton(QWidget *parent = 0);
 10:     void paintEvent(QPaintEvent *event);
 11:     QPixmap m_Pixmap;
 12: };
 13: 
 14: 
 15: #include "imgbutton.h"
 16: #include <QIcon>
 17: #include <QBitmap>
 18: 
 19: ImgButton::ImgButton(QWidget *parent) :
 20:    QPushButton(parent)
 21: {
 22:     //必須設置為無邊框,否則可見區域和圖片繪制區域將出現不重疊
 23:     setWindowFlags( Qt::FramelessWindowHint );
 24:     m_Pixmap.load("close.png");
 25:     resize(100,100);
 26:     m_Pixmap = m_Pixmap.scaled(this->size(),Qt::IgnoreAspectRatio);
 27: }
 28: 
 29: void ImgButton::paintEvent(QPaintEvent *event)
 30: {
 31:     //繪制背景圖片
 32:     QIcon icon(m_Pixmap);
 33:     this->setIcon(icon);
 34:     this->setIconSize(size());
 35:     //將png圖片透明部分設置為穿透
 36:     this->setMask(m_Pixmap.mask());
 37:     //繪制
 38:     QPushButton::paintEvent(event);
 39: }

然后我們把異形窗體重新實現了:

  1: #include <QString>
  2: #include <QBitmap>
  3: #include <QPaintEvent>
  4: #include <QPalette>
  5: //異形窗體實現
  6: 
  7: //T 為基類,繼續擁有一個QWidget *parent參數的構造函數
  8: template <typename T>
  9: class WidgetRuleless : public T
 10: {
 11: public:
 12:     WidgetRuleless(QWidget *parent = 0):T(parent)
 13:     {
 14:         //設置為無邊框
 15:         T::setWindowFlags( Qt::FramelessWindowHint );
 16:     }
 17:     void SetBackgroundImg(const QString &imgFile)
 18:     {
 19:         m_Pixmap.load(imgFile);
 20: 
 21:         //保持圖片跟界面一樣大小
 22:         m_Pixmap = m_Pixmap.scaled(T::size());
 23: 
 24:         T::setAutoFillBackground(true);
 25: 
 26:         //不規則窗口的關鍵,將圖片透明的地方設為穿透
 27:         T::setMask( m_Pixmap.mask() );
 28:     }
 29: protected:
 30:     void paintEvent(QPaintEvent *event)
 31:     {
 32:         if(!m_Pixmap.isNull())
 33:         {
 34:             //繪制背景圖片
 35:             QPalette bgPalette = this->palette();
 36:             bgPalette.setBrush(QPalette::Background,m_Pixmap);
 37:             T::setPalette(bgPalette);
 38:         }
 39:     }
 40: 
 41: private:
 42:     QPixmap m_Pixmap;
 43: };

?

組件準備好后,我們就可以輕松的使用了

  1:    //創建一個異形窗體,支持move操作,基類為QWidget
  2:     WidgetRuleless< WidgetMove<QWidget> > wid;
  3:     wid.SetBackgroundImg("hudie.png");
  4:     wid.resize(640, 480);
  5:    //創建一個Button類,并且支持move操作
  6:     WidgetMove<ImgButton> btn(&wid);
  7:     btn.move(300,300);
  8:     wid.show();

?

簡單幾行代碼,我們就可以得到以下效果:

效果圖: 蝴蝶為異形窗體,小樹為異形按鈕,并且都支持move動作。

?

這里我們將經常用的小功能(主要是需要通過繼承實現的),分解成若干小零件,在日常項目開發中,我們只需要進行簡單的組合,就可以得到一個功能強大的控件。

后記:C++是一門異常強大的語言,模板的注入更為C++添加了無窮的潛力,十余年來,他的潛力不斷被挖掘出來,但依舊有存在巨大的潛力等待我們去探索,去發現。

?

注:模板類中不支持Qt信號和槽的機制。

轉載于:https://www.cnblogs.com/lingluotianya/p/4430190.html

總結

以上是生活随笔為你收集整理的C++链式继承的全部內容,希望文章能夠幫你解決所遇到的問題。

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