加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Qt實(shí)現(xiàn)的多菜單選擇界面

02/27 15:54
4682
閱讀需 21 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

這種菜單樣式比較常用,實(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

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
HCNW3120#300 1 Avago Technologies 1 CHANNEL LOGIC OUTPUT OPTOCOUPLER, 0.300 INCH, SURFACE MOUNT, DIP-8
$4.78 查看
FTLX8571D3BCL 1 Finisar Corporation Transceiver, 840nm Min, 860nm Max, 10000Mbps(Tx), 10000Mbps(Rx), LC Connector, Board/panel Mount, ROHS COMPLIANT PACKAGE-20
$77.85 查看
ECS-250-20-33-DU-TR 1 ECS International Inc Parallel - Fundamental Quartz Crystal, 25MHz Nom, SMD, 4 PIN
$0.86 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜