天天看点

QWidget动态布局

   QWidget上放置的控件,如果想要保证自己的控件大小不变并能根据窗口的大小动态调整位置,则需要重载QWidget下的resizeEvent(函数原型:voidresizeEvent(QResizeEvent*);)函数,该函数用于重新计算窗口并布局。

      使用布局管理器并不能实现该功能,由于布局管理器会根据窗口大小进行相应的放大和缩小,其上面的控件跟着对应变化,所以只能重载该函数来实现窗口的动态布局。

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 代码如下:

#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();
}
           

源代码下载:点击打开链接