QWidget動態佈局

   QWidget上放置的控件,若是想要保證本身的控件大小不變並能根據窗口的大小動態調整位置,則須要重載QWidget下的resizeEvent(函數原型:voidresizeEvent(QResizeEvent*);)函數,該函數用於從新計算窗口並佈局。html

      使用佈局管理器並不能實現該功能,因爲佈局管理器會根據窗口大小進行相應的放大和縮小,其上面的控件跟着對應變化,因此只能重載該函數來實現窗口的動態佈局。算法


Example:仍以工具箱的實現爲例跟以前的文章: 函數

Qt在停靠窗口上添加控件(實現工具箱功能) 對比


//頭文件內容以下:
工具

#ifndef TOOLKIT_H
#define TOOLKIT_H


#define BUTTONWIDTH 16
#define BUTTONHEIGHT 16
#define WIDTHINTERVAL 21
#define HEIGHTINTERVAL 21
#define LINEWIDTH 30

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QButtonGroup>
#include <QSize>
#include <QVector>

class CToolkit : public QWidget
{
    Q_OBJECT
public:
    explicit CToolkit(QWidget *parent = 0);
    ~CToolkit();
    
signals:
    
public slots:

private:
    void initUI();
    //basic buttons
    QPushButton * basPotBtn;               //draw pointer
    QPushButton * basLineBtn;              //draw line
    QPushButton * basPolygonaLineBtn;      //draw polygon line
    QPushButton * basArcBtn;               //draw arc
    QPushButton * basCurveBtn;             //draw curve
    QPushButton * basBasselCurveBtn;       //draw bassel curve
    QPushButton * basRectangleBtn;         //draw rectangle
    QPushButton * basRoundRectBtn;         //draw round rectangle
    QPushButton * basCircleBtn;            //draw circle
    QPushButton * basSectorBtn;            //draw sector
    QPushButton * basHalfCirBtn;           //draw half circle
    QPushButton * basPolygonBtn;           //draw polygon
    QPushButton * basEnclosedCurBtn;       //draw closed curve
    QPushButton * basEnclosedBasselCurBtn; //draw closed bassel curve
    QPushButton * basTextBtn;              //draw text
    QPushButton * basPumpBtn;              //draw pump

    //extension buttons
    QPushButton *extPotBtn;                 //draw point
    QPushButton *extBtnBtn;                 //draw button
    QPushButton *extPicBtn;                 //draw picture
    QPushButton *extTreLineBtn;             //draw trend line
    QPushButton *extAlaWndBtn;              //draw alarm window
    QPushButton *extXYTreBtn;               //draw XY trend
    QPushButton *extEveWndBtn;              //draw event window
    QPushButton *extVerRuleBtn;             //draw vertical ruler
    QPushButton *extHorRuleBtn;             //draw horizontal ruler
    QPushButton *extBarPicBtn;              //draw bar picture
    QPushButton *extMenuBtn;                //draw menu
    QPushButton *extRepBtn;                 //draw report

    //UI buttons
    QPushButton *UIPotBtn;                 //draw point
    QPushButton *UIBtnBtn;                 //draw button
    QPushButton *UICheBtn;                 //draw checkbox
    QPushButton *UITextBtn;                //draw textedit
    QPushButton *UIComBtn;                 //draw combobox
    QPushButton *UILstBtn;                 //draw listbox
    QPushButton *UISigBtn;                 //draw siglebox
    QPushButton *UITreeBtn;                //draw treeview
    QPushButton *UICalBtn;                 //draw calender
    QPushButton *UIMulTextBtn;             //draw multify textedit
    QPushButton *UIDateBtn;                //draw datetime
    QPushButton *UIRelBtn;                 //draw  relative datetime
    QPushButton *MulTreeBtn;               //draw multify treeview


private:
    //用於在繪製的時候肯定要繪製哪個圖形
    QButtonGroup *m_pBasGropBox;
    QButtonGroup *m_pExtGropBox;
    QButtonGroup *m_pUIGropBox;

    //把已經建立的三組按鈕分別保存用於在從新佈局時使用
    QVector<QPushButton*> mBasBtns;
    QVector<QPushButton*> mExtBtns;
    QVector<QPushButton*> mUIBtns;

    void addBtnsToGroupBox();
    void addBtnsToVector();

public slots:
    void basicGroupBoxClicked(int);
    void extensionGroupBoxClicked(int);
    void UIGroupBoxClicked(int);

public:
    int mDrawType;     //1 indicate basic type, 2 indicate extension type, 3 indicate UI type
    int mDrawIndex;    //mDrawIndex從-1開始遞減

private:

    //初始化基本、擴展和UI按鈕
    void createBasicBtns();
    void createExtensionBtns();
    void createUIBtns();

    int mBasLineHeiLoc;         //基本按鈕上面的線條的相對高度
    int mExtLineHeiLoc;         //擴展按鈕上面的線條的相對高度
    int mUILineHeiLoc;          //UI按鈕上面的線條的相對高度
    int mCurLocWidth;           //當前在窗口中的相對寬度
    int mCurLocHeight;          //當前在窗口中的相對高度
    int mWndWidth;              //當前窗口的寬度

    //保存基本屬性按鈕和擴展按鈕的個數,用於佈局時高度的計算
    int mBasicBtnNums;
    int mExtBtnNums;
    //因爲寫的控制佈局的算法當恰好能整行放完的時候,會致使下一組的按鈕的高度位置多加了一次,因此此處設置此值用來控制高度能正確計算
    int mMode;

    //用於顯示信息的標籤
    QLabel *basicLab;
    QLabel *extLab;
    QLabel *UILab;


    //resize the buttons location
    void resizeEvent(QResizeEvent *);

    void resizeBasicBtns();
    void resizeExtensionBtns();
    void resizeUIBtns();

    //重載此函數用於繪製標籤下的直線
    void paintEvent(QPaintEvent *event);
};

#endif // TOOLKIT_H




//實現文件內容以下:
佈局

#include "toolkit.h"
#include <QLabel>
#include <QPushButton>
#include <QPainter>

CToolkit::CToolkit(QWidget *parent) :
    QWidget(parent)
{
    initUI();
}

CToolkit::~CToolkit()
{
    //basic buttons
    delete  basPotBtn;               //draw pointer
    delete  basLineBtn;              //draw line
    delete  basPolygonaLineBtn;      //draw polygon line
    delete  basArcBtn;               //draw arc
    delete  basCurveBtn;             //draw curve
    delete  basBasselCurveBtn;       //draw bassel curve
    delete  basRectangleBtn;         //draw rectangle
    delete  basRoundRectBtn;         //draw round rectangle
    delete  basCircleBtn;            //draw circle
    delete  basSectorBtn;            //draw sector
    delete  basHalfCirBtn;           //draw half circle
    delete  basPolygonBtn;           //draw polygon
    delete  basEnclosedCurBtn;       //draw closed curve
    delete  basEnclosedBasselCurBtn; //draw closed bassel curve
    delete  basTextBtn;              //draw text
    delete  basPumpBtn;              //draw pump

    //extension buttons
    delete extPotBtn;                 //draw point
    delete extBtnBtn;                 //draw button
    delete extPicBtn;                 //draw picture
    delete extTreLineBtn;             //draw trend line
    delete extAlaWndBtn;              //draw alarm window
    delete extXYTreBtn;               //draw XY trend
    delete extEveWndBtn;              //draw event window
    delete extVerRuleBtn;             //draw vertical ruler
    delete extHorRuleBtn;             //draw horizontal ruler
    delete extBarPicBtn;              //draw bar picture
    delete extMenuBtn;                //draw menu
    delete extRepBtn;                 //draw report

    //UI buttons
    delete UIPotBtn;                 //draw point
    delete UIBtnBtn;                 //draw button
    delete UICheBtn;                 //draw checkbox
    delete UITextBtn;                //draw textedit
    delete UIComBtn;                 //draw combobox
    delete UILstBtn;                 //draw listbox
    delete UISigBtn;                 //draw siglebox
    delete UITreeBtn;                //draw treeview
    delete UICalBtn;                 //draw calender
    delete UIMulTextBtn;             //draw multify textedit
    delete UIDateBtn;                //draw datetime
    delete UIRelBtn;                 //draw  relative datetime
    delete MulTreeBtn;               //draw multify treeview
}

void CToolkit::initUI()
{
    mDrawType = 0;
    mDrawIndex = 0;


    mBasLineHeiLoc = 0;
    mExtLineHeiLoc = 0;
    mUILineHeiLoc = 0;

    mBasicBtnNums = 16;
    mExtBtnNums = 12;

    createBasicBtns();
    createExtensionBtns();
    createUIBtns();

    addBtnsToGroupBox();
    addBtnsToVector();
}


//建立全部的基本按鈕並佈局
void CToolkit::createBasicBtns()
{

    m_pBasGropBox = new QButtonGroup;
    if(NULL == m_pBasGropBox)
    {
        return;
    }
    connect(m_pBasGropBox, SIGNAL(buttonClicked(int)), this, SLOT(basicGroupBoxClicked(int)));


    //draw pointer
    basicLab = new QLabel(tr("基本"), this);
    basicLab->setGeometry(0, 0, 30, 16);

    basPotBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/choice.ico")), tr(""), this);
    basPotBtn->resize(16, 16);
    basPotBtn->setToolTip(tr("指針"));
    basPotBtn->setGeometry(0, 21, 16, 16);
    basPotBtn->setCheckable(true);
    //draw line
    basLineBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/line.ico")), tr(""), this);
    basLineBtn->resize(16, 16);
    basLineBtn->setToolTip(tr("直線"));
    basLineBtn->setGeometry(21, 21, 16, 16);
    basLineBtn->setCheckable(true);
    //draw polygon line
    basPolygonaLineBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/polygonalline.ico")), tr(""), this);
    basPolygonaLineBtn->resize(16, 16);
    basPolygonaLineBtn->setToolTip(tr("折線"));
    basPolygonaLineBtn->setGeometry(42, 21, 16, 16);
    basPolygonaLineBtn->setCheckable(true);
    //draw arc
    basArcBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/arc.ico")), tr(""), this);
    basArcBtn->resize(16, 16);
    basArcBtn->setToolTip(tr("弧線"));
    basArcBtn->setGeometry(63, 21, 16, 16);
    basArcBtn->setCheckable(true);


    //draw curve
    basCurveBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/curve.ico")), tr(""), this);
    basCurveBtn->resize(16, 16);
    basCurveBtn->setToolTip(tr("曲線"));
    basCurveBtn->setGeometry(0, 42, 16, 16);
    basCurveBtn->setCheckable(true);
    //draw bassel curve
    basBasselCurveBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/Besselcurve.ico")), tr(""), this);
    basBasselCurveBtn->resize(16, 16);
    basBasselCurveBtn->setToolTip(tr("貝塞爾曲線"));
    basBasselCurveBtn->setGeometry(21, 42, 16, 16);
    basBasselCurveBtn->setCheckable(true);
    //draw rectangle
    basRectangleBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/rectangle.ico")), tr(""), this);
    basRectangleBtn->resize(16, 16);
    basRectangleBtn->setToolTip(tr("矩形"));
    basRectangleBtn->setGeometry(42, 42, 16, 16);
    basRectangleBtn->setCheckable(true);
    //draw round rectangle
    basRoundRectBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/Roundedrectangle.ico")), tr(""), this);
    basRoundRectBtn->resize(16, 16);
    basRoundRectBtn->setToolTip(tr("圓角矩形"));
    basRoundRectBtn->setGeometry(63, 42, 16, 16);
    basRoundRectBtn->setCheckable(true);


    //draw circle
    basCircleBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/circle.ico")), tr(""), this);
    basCircleBtn->resize(16, 16);
    basCircleBtn->setToolTip(tr("橢圓"));
    basCircleBtn->setGeometry(0, 63, 16, 16);
    basCircleBtn->setCheckable(true);
    //draw sector
    basSectorBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/sector.ico")), tr(""), this);
    basSectorBtn->resize(16, 16);
    basSectorBtn->setToolTip(tr("扇形"));
    basSectorBtn->setGeometry(21, 63, 16, 16);
    basSectorBtn->setCheckable(true);
    //draw half circle
    basHalfCirBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/halfcircle.ico")), tr(""), this);
    basHalfCirBtn->resize(16, 16);
    basHalfCirBtn->setToolTip(tr("弦"));
    basHalfCirBtn->setGeometry(42, 63, 16, 16);
    basHalfCirBtn->setCheckable(true);
    //draw polygon
    basPolygonBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/polygon.ico")), tr(""), this);
    basPolygonBtn->resize(16, 16);
    basPolygonBtn->setToolTip(tr("多邊形"));
    basPolygonBtn->setGeometry(63, 63, 16, 16);
    basPolygonBtn->setCheckable(true);


    //draw closed cur
    basEnclosedCurBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/enclosedcircle.ico")), tr(""), this);
    basEnclosedCurBtn->resize(16, 16);
    basEnclosedCurBtn->setToolTip(tr("封閉曲線"));
    basEnclosedCurBtn->setGeometry(0, 84, 16, 16);
    basEnclosedCurBtn->setCheckable(true);
    //draw close bassel curve
    basEnclosedBasselCurBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/enclosedbasselcurve.ico")), tr(""), this);
    basEnclosedBasselCurBtn->resize(16, 16);
    basEnclosedBasselCurBtn->setToolTip(tr("封閉貝塞爾曲線"));
    basEnclosedBasselCurBtn->setGeometry(21, 84, 16, 16);
    basEnclosedBasselCurBtn->setCheckable(true);
    //draw text
    basTextBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/text.ico")), tr(""), this);
    basTextBtn->resize(16, 16);
    basTextBtn->setToolTip(tr("文本"));
    basTextBtn->setGeometry(42, 84, 16, 16);
    basTextBtn->setCheckable(true);
    //draw pump
    basPumpBtn = new QPushButton(QIcon(tr(":/res/ctrl/BasicCtrl/pump.ico")), tr(""), this);
    basPumpBtn->resize(16, 16);
    basPumpBtn->setToolTip(tr("管道"));
    basPumpBtn->setGeometry(63, 84, 16, 16);
    basPumpBtn->setCheckable(true);  
}


//建立全部的擴展按鈕並佈局
void CToolkit::createExtensionBtns()
{
    m_pExtGropBox = new QButtonGroup;
    if(NULL == m_pExtGropBox)
    {
        return;
    }
    connect(m_pExtGropBox, SIGNAL(buttonClicked(int)), this, SLOT(extensionGroupBoxClicked(int)));


    extLab = new QLabel(tr("擴展"), this);
    extLab->setGeometry(0, 105, 30, 16);

    //draw pointer
    extPotBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/choice.ico")), tr(""), this);
    extPotBtn->resize(16, 16);
    extPotBtn->setToolTip(tr("指針"));
    extPotBtn->setGeometry(0, 126, 16, 16);
    extPotBtn->setCheckable(true);
    //draw button
    extBtnBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/button.ico")), tr(""), this);
    extBtnBtn->resize(16, 16);
    extBtnBtn->setToolTip(tr("按鈕"));
    extBtnBtn->setGeometry(21, 126, 16, 16);
    extBtnBtn->setCheckable(true);
    //draw picture
    extPicBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/picturecontrol.ico")), tr(""), this);
    extPicBtn->resize(16, 16);
    extPicBtn->setToolTip(tr("圖像"));
    extPicBtn->setGeometry(42, 126, 16, 16);
    extPicBtn->setCheckable(true);
    //draw trend line
    extTreLineBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/trendline.ico")), tr(""), this);
    extTreLineBtn->resize(16, 16);
    extTreLineBtn->setToolTip(tr("趨勢曲線"));
    extTreLineBtn->setGeometry(63, 126, 16, 16);
    extTreLineBtn->setCheckable(true);


    //draw alarm window
    extAlaWndBtn = new QPushButton(QIcon(tr(":res/ctrl/ExtCtrl/alarmwindow.ico")), tr(""), this);
    extAlaWndBtn->resize(16, 16);
    extAlaWndBtn->setToolTip(tr("報警窗"));
    extAlaWndBtn->setGeometry(0, 147, 16, 16);
    extAlaWndBtn->setCheckable(true);
    //draw XY trend
    extXYTreBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/XYtrendline.ico")), tr(""), this);
    extXYTreBtn->resize(16, 16);
    extXYTreBtn->setToolTip(tr("XY曲線"));
    extXYTreBtn->setGeometry(21, 147, 16, 16);
    extXYTreBtn->setCheckable(true);
    //draw event window
    extEveWndBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/eventwindow.ico")), tr(""), this);
    extEveWndBtn->resize(16, 16);
    extEveWndBtn->setToolTip(tr("事件窗"));
    extEveWndBtn->setGeometry(42, 147, 16, 16);
    extEveWndBtn->setCheckable(true);
    //draw vertical ruler
    extVerRuleBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/verticaldivilingrule.ico")), tr(""), this);
    extVerRuleBtn->resize(16, 16);
    extVerRuleBtn->setToolTip(tr("垂直標尺"));
    extVerRuleBtn->setGeometry(63, 147, 16, 16);
    extVerRuleBtn->setCheckable(true);


    //draw horizontal ruler
    extHorRuleBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/horizontaldivilingrule.ico")), tr(""), this);
    extHorRuleBtn->resize(16, 16);
    extHorRuleBtn->setToolTip(tr("水平標尺"));
    extHorRuleBtn->setGeometry(0, 168, 16, 16);
    extHorRuleBtn->setCheckable(true);
    //draw bar picture
    extBarPicBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/report.ico")), tr(""), this);
    extBarPicBtn->resize(16, 16);
    extBarPicBtn->setToolTip(tr("棒圖"));
    extBarPicBtn->setGeometry(21, 168, 16, 16);
    extBarPicBtn->setCheckable(true);
    //draw relative datatime
    extRepBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/barpicture.ico")), tr(""), this);
    extRepBtn->resize(16, 16);
    extRepBtn->setToolTip(tr("報表"));
    extRepBtn->setGeometry(42, 168, 16, 16);
    extRepBtn->setCheckable(true);
    //draw menu
    extMenuBtn = new QPushButton(QIcon(tr(":/res/ctrl/ExtCtrl/menu.ico")), tr(""), this);
    extMenuBtn->resize(16, 16);
    extMenuBtn->setToolTip(tr("菜單"));
    extMenuBtn->setGeometry(63, 168, 16, 16);
    extMenuBtn->setCheckable(true);
}


//建立全部的UI按鈕並佈局
void CToolkit::createUIBtns()
{
    m_pUIGropBox = new QButtonGroup;
    if(NULL == m_pUIGropBox)
    {
        return;
    }
    connect(m_pUIGropBox, SIGNAL(buttonClicked(int)), this, SLOT(UIGroupBoxClicked(int)));


    UILab = new QLabel(tr("UI"), this);
    UILab->setGeometry(0, 189, 30, 16);

    //draw pointer
    UIPotBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/choice.ico")), tr(""), this);
    UIPotBtn->resize(16, 16);
    UIPotBtn->setToolTip(tr("指針"));
    UIPotBtn->setGeometry(0, 210, 16, 16);
    UIPotBtn->setCheckable(true);
    //draw button
    UIBtnBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/button.ico")), tr(""), this);
    UIBtnBtn->resize(16, 16);
    UIBtnBtn->setToolTip(tr("按鈕"));
    UIBtnBtn->setGeometry(21, 210, 16, 16);
    UIBtnBtn->setCheckable(true);
    //draw checkbox
    UICheBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/checkbox.ico")), tr(""), this);
    UICheBtn->resize(16, 16);
    UICheBtn->setToolTip(tr("複選框"));
    UICheBtn->setGeometry(42, 210, 16, 16);
    UICheBtn->setCheckable(true);
    //draw textedit
    UITextBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/textedit.ico")), tr(""), this);
    UITextBtn->resize(16, 16);
    UITextBtn->setToolTip(tr("文本框"));
    UITextBtn->setGeometry(63, 210, 16, 16);
    UITextBtn->setCheckable(true);


    //draw combobox
    UIComBtn = new QPushButton(QIcon(tr(":res/ctrl/UICtrl/combobox.ico")), tr(""), this);
    UIComBtn->resize(16, 16);
    UIComBtn->setToolTip(tr("複選框"));
    UIComBtn->setGeometry(0, 231, 16, 16);
    UIComBtn->setCheckable(true);
    //draw listbox
    UILstBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/listbox.ico")), tr(""), this);
    UILstBtn->resize(16, 16);
    UILstBtn->setToolTip(tr("列表框"));
    UILstBtn->setGeometry(21, 231, 16, 16);
    UILstBtn->setCheckable(true);
    //draw singlebox
    UISigBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/singlebox.ico")), tr(""), this);
    UISigBtn->resize(16, 16);
    UISigBtn->setToolTip(tr("單選框"));
    UISigBtn->setGeometry(42, 231, 16, 16);
    UISigBtn->setCheckable(true);
    //draw treeview
    UITreeBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/treeview.ico")), tr(""), this);
    UITreeBtn->resize(16, 16);
    UITreeBtn->setToolTip(tr("樹視圖"));
    UITreeBtn->setGeometry(63, 231, 16, 16);
    UITreeBtn->setCheckable(true);


    //draw calender
    UICalBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/calender.ico")), tr(""), this);
    UICalBtn->resize(16, 16);
    UICalBtn->setToolTip(tr("日曆"));
    UICalBtn->setGeometry(0, 252, 16, 16);
    UICalBtn->setCheckable(true);
    //draw mulify textedit
    UIMulTextBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/mulitfunctionaltextedit.ico")), tr(""), this);
    UIMulTextBtn->resize(16, 16);
    UIMulTextBtn->setToolTip(tr("複雜文本框"));
    UIMulTextBtn->setGeometry(21, 252, 16, 16);
    UIMulTextBtn->setCheckable(true);
    //draw datetime
    UIDateBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/dateandtime.ico")), tr(""), this);
    UIDateBtn->resize(16, 16);
    UIDateBtn->setToolTip(tr("日期時間"));
    UIDateBtn->setGeometry(42, 252, 16, 16);
    UIDateBtn->setCheckable(true);
    //draw relative datatime
    UIRelBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/relativedateandtime.ico")), tr(""), this);
    UIRelBtn->resize(16, 16);
    UIRelBtn->setToolTip(tr("相對時間"));
    UIRelBtn->setGeometry(63, 252, 16, 16);
    UIRelBtn->setCheckable(true);


    //draw mulify treeview
    MulTreeBtn = new QPushButton(QIcon(tr(":/res/ctrl/UICtrl/multifunctionaltreeview.ico")), tr(""), this);
    MulTreeBtn->resize(16, 16);
    MulTreeBtn->setToolTip(tr("多功能樹視圖"));
    MulTreeBtn->setGeometry(0, 273, 16, 16);
    MulTreeBtn->setCheckable(true);
}


//添加全部按鈕到組框中用戶在點擊是獲取點擊的是哪個按鈕,要繪製哪種圖形
void CToolkit::addBtnsToGroupBox()
{
    //add the buttons to m_pBasGropBox
    m_pBasGropBox->addButton(basPotBtn);
    m_pBasGropBox->addButton(basLineBtn);
    m_pBasGropBox->addButton(basPolygonaLineBtn);
    m_pBasGropBox->addButton(basArcBtn);

    m_pBasGropBox->addButton(basCurveBtn);
    m_pBasGropBox->addButton(basBasselCurveBtn);
    m_pBasGropBox->addButton(basRectangleBtn);
    m_pBasGropBox->addButton(basRoundRectBtn);

    m_pBasGropBox->addButton(basCircleBtn);
    m_pBasGropBox->addButton(basSectorBtn);
    m_pBasGropBox->addButton(basHalfCirBtn);
    m_pBasGropBox->addButton(basPolygonBtn);

    m_pBasGropBox->addButton(basEnclosedCurBtn);
    m_pBasGropBox->addButton(basEnclosedBasselCurBtn);
    m_pBasGropBox->addButton(basTextBtn);
    m_pBasGropBox->addButton(basPumpBtn);


    //add the buttons to m_pExtGropBox
    m_pExtGropBox->addButton(extPotBtn);
    m_pExtGropBox->addButton(extBtnBtn);
    m_pExtGropBox->addButton(extPicBtn);
    m_pExtGropBox->addButton(extTreLineBtn);

    m_pExtGropBox->addButton(extAlaWndBtn);
    m_pExtGropBox->addButton(extXYTreBtn);
    m_pExtGropBox->addButton(extEveWndBtn);
    m_pExtGropBox->addButton(extVerRuleBtn);

    m_pExtGropBox->addButton(extHorRuleBtn);
    m_pExtGropBox->addButton(extRepBtn);
    m_pExtGropBox->addButton(extBarPicBtn);
    m_pExtGropBox->addButton(extMenuBtn);


    //add the buttons to m_pUIGroupBox
    m_pUIGropBox->addButton(UIPotBtn);
    m_pUIGropBox->addButton(UIBtnBtn);
    m_pUIGropBox->addButton(UICheBtn);
    m_pUIGropBox->addButton(UITextBtn);

    m_pUIGropBox->addButton(UIComBtn);
    m_pUIGropBox->addButton(UILstBtn);
    m_pUIGropBox->addButton(UISigBtn);
    m_pUIGropBox->addButton(UITreeBtn);

    m_pUIGropBox->addButton(UICalBtn);
    m_pUIGropBox->addButton(UIMulTextBtn);
    m_pUIGropBox->addButton(UIDateBtn);
    m_pUIGropBox->addButton(UIRelBtn);

    m_pUIGropBox->addButton(MulTreeBtn);
}


//保存全部的按鈕信息以在從新計算佈局時使用
void CToolkit::addBtnsToVector()
{
    //add the buttons to the mBasBtns vector
    mBasBtns.push_back(basPotBtn);
    mBasBtns.push_back(basLineBtn);
    mBasBtns.push_back(basPolygonaLineBtn);
    mBasBtns.push_back(basArcBtn);

    mBasBtns.push_back(basCurveBtn);
    mBasBtns.push_back(basBasselCurveBtn);
    mBasBtns.push_back(basRectangleBtn);
    mBasBtns.push_back(basRoundRectBtn);

    mBasBtns.push_back(basCircleBtn);
    mBasBtns.push_back(basSectorBtn);
    mBasBtns.push_back(basHalfCirBtn);
    mBasBtns.push_back(basPolygonBtn);

    mBasBtns.push_back(basEnclosedCurBtn);
    mBasBtns.push_back(basEnclosedBasselCurBtn);
    mBasBtns.push_back(basTextBtn);
    mBasBtns.push_back(basPumpBtn);


    //add the buttons to the mExtBtns vector
    mExtBtns.push_back(extPotBtn);
    mExtBtns.push_back(extBtnBtn);
    mExtBtns.push_back(extPicBtn);
    mExtBtns.push_back(extTreLineBtn);

    mExtBtns.push_back(extAlaWndBtn);
    mExtBtns.push_back(extXYTreBtn);
    mExtBtns.push_back(extEveWndBtn);
    mExtBtns.push_back(extVerRuleBtn);

    mExtBtns.push_back(extHorRuleBtn);
    mExtBtns.push_back(extRepBtn);
    mExtBtns.push_back(extBarPicBtn);
    mExtBtns.push_back(extMenuBtn);


    //add the buttons to the mUIBtns vector
    mUIBtns.push_back(UIPotBtn);
    mUIBtns.push_back(UIBtnBtn);
    mUIBtns.push_back(UICheBtn);
    mUIBtns.push_back(UITextBtn);

    mUIBtns.push_back(UIComBtn);
    mUIBtns.push_back(UILstBtn);
    mUIBtns.push_back(UISigBtn);
    mUIBtns.push_back(UITreeBtn);

    mUIBtns.push_back(UICalBtn);
    mUIBtns.push_back(UIMulTextBtn);
    mUIBtns.push_back(UIDateBtn);
    mUIBtns.push_back(UIRelBtn);

    mUIBtns.push_back(MulTreeBtn);
}


void CToolkit::basicGroupBoxClicked(int id)
{
    mDrawType = 1;

    QList<QAbstractButton *> extButtons = m_pExtGropBox->buttons();
    foreach (QAbstractButton *button, extButtons)
    {
       button->setCheckable(false);
    }

    QList<QAbstractButton *> UIButtons = m_pUIGropBox->buttons();
    foreach (QAbstractButton *button, UIButtons)
    {
       button->setCheckable(false);
    }

    QList<QAbstractButton *> buttons = m_pBasGropBox->buttons();
    foreach (QAbstractButton *button, buttons)
    {
        if (m_pBasGropBox->button(id) != button)
        {
            button->setCheckable(true);
        }
        else
        {
            mDrawIndex = id;
        }
    }
}

void CToolkit::extensionGroupBoxClicked(int id)
{ 
    mDrawType = 2;

    QList<QAbstractButton *> BasButtons = m_pBasGropBox->buttons();
    foreach (QAbstractButton *button, BasButtons)
    {
       button->setCheckable(false);
    }

    QList<QAbstractButton *> UIButtons = m_pUIGropBox->buttons();
    foreach (QAbstractButton *button, UIButtons)
    {
       button->setCheckable(false);
    }

    QList<QAbstractButton *> buttons = m_pExtGropBox->buttons();
    foreach (QAbstractButton *button, buttons)
    {
        if (m_pExtGropBox->button(id) != button)
        {
            button->setCheckable(true);
        }
        else
        {
            mDrawIndex = id;
        }
    }
}

void CToolkit::UIGroupBoxClicked(int id)
{
    mDrawType = 3;

    QList<QAbstractButton *> BasButtons = m_pBasGropBox->buttons();
    foreach (QAbstractButton *button, BasButtons)
    {
       button->setCheckable(false);
    }

    QList<QAbstractButton *> extButtons = m_pExtGropBox->buttons();
    foreach (QAbstractButton *button, extButtons)
    {
       button->setCheckable(false);
    }

    QList<QAbstractButton *> buttons = m_pUIGropBox->buttons();
    foreach (QAbstractButton *button, buttons)
    {
        if (m_pUIGropBox->button(id) != button)
        {
            button->setCheckable(true);
        }
        else
        {
            mDrawIndex = id;
        }
    }
}


//從新佈局窗口
void CToolkit::resizeEvent(QResizeEvent *event)
{
    //獲取當前窗口寬度
    mWndWidth = width();

    mCurLocWidth = 0;
    mCurLocHeight = 0;

    resizeBasicBtns();
    resizeExtensionBtns();
    resizeUIBtns();

    QWidget::resizeEvent(event);
}


//從新計算基本按鈕位置
void CToolkit::resizeBasicBtns()
{
    basicLab->setGeometry(mCurLocWidth, mCurLocHeight, LINEWIDTH, BUTTONHEIGHT);
    mCurLocWidth = 0;
    mCurLocHeight += HEIGHTINTERVAL;
    mBasLineHeiLoc = mCurLocHeight - 2;   //保存基本按鈕上面的要繪製的線的位置

    int tmp = mWndWidth / WIDTHINTERVAL;
    if(tmp * WIDTHINTERVAL + BUTTONWIDTH < mWndWidth)
    {
        tmp++;
    }
    mMode = mBasicBtnNums % tmp;


    //計算全部基本按鈕的位置,當恰好能整行放置全部按鈕的話,在resizeExtensionBtns()中的mCurLocHeight的值多加了一個HEIGHTINTERVAL,
    //因此添加了mMode來控制是否恰好整行放置
    for(QVector<QPushButton*>::iterator it = mBasBtns.begin(); it != mBasBtns.end(); ++it)
    {
        QPushButton *tmpBtn = *it;
        if(mCurLocWidth + BUTTONWIDTH < mWndWidth)
        {
            tmpBtn->setGeometry(mCurLocWidth, mCurLocHeight, BUTTONWIDTH, BUTTONHEIGHT);
            if(mCurLocWidth + WIDTHINTERVAL + BUTTONWIDTH < mWndWidth)
            {
                mCurLocWidth += WIDTHINTERVAL;
            }
            else
            {
                mCurLocWidth = 0;
                mCurLocHeight += HEIGHTINTERVAL;
            }
        }
    }
}



void CToolkit::resizeExtensionBtns()
{
    mCurLocWidth = 0;

    //計算基本按鈕是否恰好整行放置
    if(0 == mMode)
    {
        mCurLocHeight -= HEIGHTINTERVAL;
    }
    {
        mCurLocHeight += HEIGHTINTERVAL;
    }

    int tmp = mWndWidth / WIDTHINTERVAL;
    if(tmp * WIDTHINTERVAL + BUTTONWIDTH < mWndWidth)
    {
        tmp++;
    }
    mMode = mExtBtnNums % tmp;

    extLab->setGeometry(mCurLocWidth, mCurLocHeight, LINEWIDTH, BUTTONHEIGHT);

    mCurLocWidth = 0;
    mCurLocHeight += HEIGHTINTERVAL;
    mExtLineHeiLoc = mCurLocHeight - 2;   //保存擴展按鈕上面的要繪製的線的位置


    //計算全部擴展按鈕的位置,當恰好能整行放置全部按鈕的話,在resizeUIBtns()中的mCurLocHeight的值多加了一個HEIGHTINTERVAL,
    //因此添加了mMode來控制是否恰好整行放置
    for(QVector<QPushButton*>::iterator it = mExtBtns.begin(); it != mExtBtns.end(); ++it)
    {
        QPushButton *tmpBtn = *it;
        if(mCurLocWidth + BUTTONWIDTH < mWndWidth)
        {
            tmpBtn->setGeometry(mCurLocWidth, mCurLocHeight, BUTTONWIDTH, BUTTONHEIGHT);
            if(mCurLocWidth + WIDTHINTERVAL + BUTTONWIDTH < mWndWidth)
            {
                mCurLocWidth += WIDTHINTERVAL;
            }
            else
            {
                mCurLocWidth = 0;
                mCurLocHeight += HEIGHTINTERVAL;
            }
        }
    }
}


void CToolkit::resizeUIBtns()
{
    mCurLocWidth = 0;
    if(0 == mMode)
    {
        mCurLocHeight -= HEIGHTINTERVAL;
    }
    {
        mCurLocHeight += HEIGHTINTERVAL;
    }
    UILab->setGeometry(mCurLocWidth, mCurLocHeight, LINEWIDTH, BUTTONHEIGHT);

    //因爲UI按鈕下面沒有內容,不須要在計算mMode

    mCurLocWidth = 0;
    mCurLocHeight += HEIGHTINTERVAL;
    mUILineHeiLoc = mCurLocHeight - 2;      //保存UI按鈕上面的要繪製的線的位置


    for(QVector<QPushButton*>::iterator it = mUIBtns.begin(); it != mUIBtns.end(); ++it)
    {
        QPushButton *tmpBtn = *it;
        if(mCurLocWidth + BUTTONWIDTH < mWndWidth)
        {
            tmpBtn->setGeometry(mCurLocWidth, mCurLocHeight, BUTTONWIDTH, BUTTONHEIGHT);
            if(mCurLocWidth + WIDTHINTERVAL + BUTTONWIDTH < mWndWidth)
            {
                mCurLocWidth += WIDTHINTERVAL;
            }
            else
            {
                mCurLocWidth = 0;
                mCurLocHeight += HEIGHTINTERVAL;
            }
        }
    }
}


//繪製三條直線
void CToolkit::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);             // 建立QPainter一個對象
    QPen pen;
    painter.setPen(pen);                // 設置畫筆
    painter.drawLine(0, mBasLineHeiLoc, mWndWidth, mBasLineHeiLoc);
    painter.drawLine(0, mExtLineHeiLoc, mWndWidth, mExtLineHeiLoc);
    painter.drawLine(0, mUILineHeiLoc, mWndWidth, mUILineHeiLoc);

    QWidget::paintEvent(event);
}



//main.cpp 代碼以下:this

#include "mainwindow.h"
#include "toolkit.h"
#include <QApplication>
#include <QDockWidget>
#include <QTextEdit>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QMainWindow *mainWnd = new QMainWindow;
    QTextEdit *txtEdit = new QTextEdit;
    mainWnd->setCentralWidget(txtEdit);

    CToolkit *pToolkit = new CToolkit;
    if(NULL == pToolkit)
    {
        return 1;
    }
    QDockWidget *toolkitDock = new QDockWidget();
    if(NULL == toolkitDock)
    {
        return 1;
    }
    toolkitDock->setWindowTitle("工具箱");
    toolkitDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    toolkitDock->setWidget(pToolkit);
    mainWnd->addDockWidget(Qt::LeftDockWidgetArea, toolkitDock);


    mainWnd->show();
    
    return a.exec();
}


源代碼下載:點擊打開連接spa