Qt實現的多菜單選擇界面

1.效果展示

樣式效果
這種菜單樣式比較常用,實現的方法也有很多種,比如可以直接使用QTableWidget,也可以用QStackedWidget實現。這裏我是用QToolButton和QWidget+QScrollArea實現的。這個可以在實例化時指定菜單按鍵數。

2.實現代碼

2.1 菜單實現代碼

2.1.1 頭文件

#ifndef CBASECONFIG_H
#define CBASECONFIG_H

/************************************************************************
 * 名稱:上導航菜單欄界面
 * 上邊是導航按鍵,下面是對應的界面
 * 作者:fens
*************************************************************************/

#include <QWidget>
#include <QToolButton>
#include <QMap>

namespace Ui {
class CBaseConfig;
}

class CBaseConfig : public QWidget
{
    Q_OBJECT

public:
    explicit CBaseConfig(QWidget *parent = nullptr);
    ~CBaseConfig();
    //設置菜單按鍵的最小寬度
    void setMenuMiniWidth(int minw);
    //設置菜單按鍵的最小高度
    void setMenuMiniHeight(int minh);
    //設置菜單按鍵的最大寬度
    void setMenuMaxWidth(int maxw);
	//設置菜單按鍵的最大高度
    void setMenuMaxHeight(int maxh);

    //用於設置按鍵屬性,固定大小/縮放
    void setMenuBtnSizePolicy(QSizePolicy val);
    //初始化生成菜單按鍵和對應界面
    void initMenu(QVector<QPair<QString, QWidget*> >& listItem);

signals:
    void clicked(int , bool ); //按鍵序號,從0開始, 狀態-true選中;false-未選中

private slots:
    void onToolButtonClicked();

private:
    Ui::CBaseConfig *ui;

    QString m_bakebtnName; //備份當前顯示的界面按鍵
    QVector<QToolButton*>m_btnMap;       //用於保存菜單按鍵
    QMap<QString, QWidget*>m_widgetsMap; //用於保存菜單對應的界面
    QSizePolicy m_btnQSizePolicy;		 
};

#endif // CBASECONFIG_H

2.1.2 源文件

#include "cbaseconfig.h"
#include "ui_cbaseconfig.h"
#include <QDebug>

CBaseConfig::CBaseConfig(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CBaseConfig)
{
    ui->setupUi(this);
    this->setProperty("form", true);

    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);

//    m_btnQSizePolicy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    m_btnQSizePolicy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

CBaseConfig::~CBaseConfig()
{
    delete ui;
}

void CBaseConfig::setMenuMiniHeight(int minh)
{
    ui->widgetSetMenu->setMinimumWidth(minh);
}

void CBaseConfig::setMenuMiniWidth(int minw)
{
    ui->widgetSetMenu->setMinimumWidth(minw);
}

void CBaseConfig::setMenuMaxHeight(int maxh)
{
    ui->widgetSetMenu->setMaximumHeight(maxh);
}

void CBaseConfig::setMenuMaxWidth(int maxw)
{
    ui->widgetSetMenu->setMaximumWidth(maxw);
}

void CBaseConfig::setMenuBtnSizePolicy(QSizePolicy val)
{
    m_btnQSizePolicy = val;
}

//根據傳入的菜單名稱和QWidget界面來生成菜單界面
void CBaseConfig::initMenu(QVector<QPair<QString, QWidget*> >& listItem)
{
    m_btnMap.clear();
    m_widgetsMap.clear();

    QToolButton *ptbn = NULL;

    for (int i = 0; i < listItem.count(); i++)
    {
        ptbn = new QToolButton;
        ptbn->setObjectName(QString("tbSetMenu%1").arg(i));
        ptbn->setText(listItem.at(i).first);
        ptbn->setSizePolicy(m_btnQSizePolicy);
        ptbn->setCheckable(true);
        connect(ptbn, &QToolButton::clicked, this, &CBaseConfig::onToolButtonClicked);

        ui->horizontalLayout->addWidget(ptbn);
        ui->mainLayout->addWidget(listItem.at(i).second);
        listItem.at(i).second->hide();
        m_btnMap.push_back(ptbn);
        m_widgetsMap[listItem.at(i).first] = listItem.at(i).second;
    }

    m_btnMap.at(0)->setChecked(true);
    m_bakebtnName = listItem.at(0).first;
    listItem.at(0).second->show();
}

void CBaseConfig::onToolButtonClicked()
{
    QToolButton *b = (QToolButton *)sender();
    QString name = b->text();

    for ( int i = 0; i < m_btnMap.size(); i++ )
    {
        if (m_btnMap.at(i) == b)
        {
            m_btnMap.at(i)->setChecked(true);
            emit clicked(i, true);
        }
        else
        {
            if( m_btnMap.at(i)->isChecked() )
                emit clicked(i, false);
            m_btnMap.at(i)->setChecked(false);
        }
    }

//     qDebug()<<"in CBaseConfig::onToolButtonClicked, button "<<name<<", checked!"<<"last: "<<m_bakebtnName;

    m_widgetsMap[m_bakebtnName]->hide();
    m_widgetsMap[name]->show();
    m_bakebtnName = name;

}

2.2 應用代碼

使用代碼源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "cbaseconfig.h"
#include <QLabel>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    init();

    //設置菜單鍵樣式,實際應用時,建議寫在單獨的qss文件中
    QStringList qss;
    qss.append("QToolButton{color:rgb(250, 250,250);font:14px;min-width:72px;min-height:37px;background-color: qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #0931B4,stop:1 #050A51);border:1px;border-right-color: rgb(20, 20, 20);border-left-color: rgb(20, 20, 20);/*border-radius控制圓角大小*/	}");
    qss.append("QToolButton:pressed{background-color: qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #0931B4,stop:1 #050A51);}");
    qss.append("QToolButton:checked{background-color: qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #420064,stop:1 #0D22DE);}");

    this->setStyleSheet(qss.join(""));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    int heigth = 76;
    CBaseConfig *baseConfig = new CBaseConfig;
    baseConfig->setMenuMiniHeight(heigth);
    baseConfig->setMenuMaxHeight(heigth);


    QVector<QPair<QString, QWidget*> > listItem;
    //基本設置
    listItem.clear();

    QWidget *pWidget;
    QGridLayout *playout ;
    QLabel *lab;
	
	//循環添加7個菜單按鍵
    for (int i = 1; i <= 7; i++)
    {
        pWidget = new QWidget;
        playout = new QGridLayout;
        lab = new QLabel;
        lab->setText(QString("菜單%1").arg(i));
        lab->setAlignment(Qt::AlignCenter);
        lab->setStyleSheet("font: 48px");

        playout->addWidget(lab);
        pWidget->setLayout(playout);

        listItem.push_back(qMakePair(QString("菜單%1").arg(i),pWidget));
    }

    connect(baseConfig, &CBaseConfig::clicked, this, [this](int no, bool flag){
        if (flag )
            qDebug()<<"no: "<<no<<" enter screen.";
        else
            qDebug()<<"no: "<<no<<" leave screen.";
    });

    baseConfig->initMenu(listItem);
	
	//這裏爲什麼要使用QScrollArea,這樣菜單界面內容超出一頁內容時,可以像網頁一頁向下滾動。
    ui->scrollArea->setWidget(baseConfig);
}

這裏每個頁面也可以再嵌入菜單;這個只是實現了一個簡單的菜單框架,這個菜單可以再改進添加上菜單鍵的翻頁,菜單鍵太多,就兩邊加上箭頭,用於把隱藏的按鍵顯示出來;還可以把按鍵改爲豎着排放的。

示例代碼下載:
碼雲:https://gitee.com/fenstec/demo_code.git

微信訂閱號:
在這裏插入圖片描述

發佈了42 篇原創文章 · 獲贊 41 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章