這種菜單樣式比較常用,實(shí)現(xiàn)的方法也有很多種,比如可以直接使用QTableWidget,也可以用QStackedWidget實(shí)現(xiàn)。這里我是用QToolButton和QWidget+QScrollArea實(shí)現(xiàn)的。這個(gè)可以在實(shí)例化時(shí)指定菜單按鍵數(shù)。
效果展示
實(shí)現(xiàn)代碼
菜單實(shí)現(xiàn)代碼
頭文件
#ifndef?CBASECONFIG_H
#define?CBASECONFIG_H
/************************************************************************
?*?名稱:上導(dǎo)航菜單欄界面
?*?上邊是導(dǎo)航按鍵,下面是對(duì)應(yīng)的界面
?*?作者:fens
*************************************************************************/
#include?<QWidget>
#include?<QToolButton>
#include?<QMap>
namespace?Ui?{
class?CBaseConfig;
}
class?CBaseConfig?:?public?QWidget
{
????Q_OBJECT
public:
????explicit?CBaseConfig(QWidget?*parent?=?nullptr);
????~CBaseConfig();
????//設(shè)置菜單按鍵的最小寬度
????void?setMenuMiniWidth(int?minw);
????//設(shè)置菜單按鍵的最小高度
????void?setMenuMiniHeight(int?minh);
????//設(shè)置菜單按鍵的最大寬度
????void?setMenuMaxWidth(int?maxw);
??//設(shè)置菜單按鍵的最大高度
????void?setMenuMaxHeight(int?maxh);
????//用于設(shè)置按鍵屬性,固定大小/縮放
????void?setMenuBtnSizePolicy(QSizePolicy?val);
????//初始化生成菜單按鍵和對(duì)應(yīng)界面
????void?initMenu(QVector<QPair<QString,?QWidget*>?>&?listItem);
signals:
????void?clicked(int?,?bool?);?//按鍵序號(hào),從0開始,?狀態(tài)-true選中;false-未選中
private?slots:
????void?onToolButtonClicked();
private:
????Ui::CBaseConfig?*ui;
????QString?m_bakebtnName;?//備份當(dāng)前顯示的界面按鍵
????QVector<QToolButton*>m_btnMap;???????//用于保存菜單按鍵
????QMap<QString,?QWidget*>m_widgetsMap;?//用于保存菜單對(duì)應(yīng)的界面
????QSizePolicy?m_btnQSizePolicy;?????
};
#endif?//?CBASECONFIG_H
源文件
#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;
}
//根據(jù)傳入的菜單名稱和QWidget界面來(lái)生成菜單界面
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;
}
應(yīng)用代碼
使用代碼源文件
#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();
????//設(shè)置菜單鍵樣式,實(shí)際應(yīng)用時(shí),建議寫在單獨(dú)的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;
????//基本設(shè)置
????listItem.clear();
????QWidget?*pWidget;
????QGridLayout?*playout?;
????QLabel?*lab;
??
??//循環(huán)添加7個(gè)菜單按鍵
????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,這樣菜單界面內(nèi)容超出一頁(yè)內(nèi)容時(shí),可以像網(wǎng)頁(yè)一頁(yè)向下滾動(dòng)。
????ui->scrollArea->setWidget(baseConfig);
}
這里每個(gè)頁(yè)面也可以再嵌入菜單;這個(gè)只是實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的菜單框架,這個(gè)菜單可以再改進(jìn)添加上菜單鍵的翻頁(yè),菜單鍵太多,就兩邊加上箭頭,用于把隱藏的按鍵顯示出來(lái);還可以把按鍵改為豎著排放的。
示例代碼下載: 碼云:https://gitee.com/fenstec/demo_code.git