自适应效果:
缩小时:
拉伸时:
#include "VMSHeaderFrm.h"
#include "MTButton.h"
#include "Utils.h"
#include "VMSPluginManager.h"
#include <QHBoxLayout>
#include <QButtonGroup>
#include <QMenuBar>
#include <QAction>
VMSHeaderFrm::VMSHeaderFrm(QWidget *parent)
: QFrame(parent),
m_pGroupBtn(new QButtonGroup(this))
{
ui.setupUi(this);
m_pBtnLayout = new QHBoxLayout(ui.pluginFrm);
m_pBtnLayout->setSpacing(0);
m_pBtnLayout->addStretch();
HorizontalList.clear();
MeunList.clear();
//创建下拉菜单
menuSelection = new QMenu(this);
//工具栏的下拉式菜单按钮,QToolButton::InstantPopup
pDropBtn = new QToolButton(this);
pDropBtn->setPopupMode(QToolButton::InstantPopup);
pDropBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
pDropBtn->setFixedSize(50,34);
pDropBtn->setMenu(menuSelection);
pDropBtn->hide();
Utils::setProperty(ui.qss_normal_btn, "state", (int)WINDOWN_STATE::W_S_FULL_SCREEN);
initConnect();
}
VMSHeaderFrm::~VMSHeaderFrm()
{
}
void VMSHeaderFrm::addModel(int model)//点击单个添加时(添加到首页按钮之后)
{
QPushButton* pBtn = nullptr;
if (model != 0)//已创建首页按钮
{
int wid = GetCurrentMeunWid() - 70 - ButtonWidth() * GroupButtonSize();//剩余长度
if (wid < ButtonWidth())//剩余长度 > 控件长度
{
m_pBtnLayout->insertWidget(HorizontalList.size() + 1, pDropBtn);//下拉按钮在组内按钮尾部之后展示
//把尾部最后一项添加到下拉菜单里
if (StringToMoudel(HorizontalList.last()) != -1)//将最后一项转为model值
{
MeunList.prepend(HorizontalList.last());//下拉菜单列表首部增加一项
removeModel(StringToMoudel(HorizontalList.last()), model);//移除水平最后一项
RefreshMeun(MeunList);
if (MeunList.size() > 0)
{
pDropBtn->show();
}
else
pDropBtn->hide();
}
}
}
//添加标题栏目按钮组
int index = 0;
if (model == 0) //首页
{
pBtn = new QPushButton(tr("frishPage"));
pBtn->setObjectName("qss_first_page_btn");
}
else
{
VMSPlugin* p = IPlugins->plugin(model);
if (p == nullptr)
return;
PluginTitleBtn* pBtn2 = new PluginTitleBtn(p->modelName(), this);
connect(pBtn2, &PluginTitleBtn::sgnClose, this, [this, model] {solts_closeBtn(model); });
index = 1;
pBtn = pBtn2;
HorizontalList.prepend(p->modelName());//该项添加到首部
}
//点击项添加到frishPage按钮之后,并选中该项
pBtn->setCheckable(true);
m_pGroupBtn->addButton(pBtn, model);
m_pBtnLayout->insertWidget(index, pBtn);
m_model.insert(model);
m_Recordmodel.insert(model);
}
void VMSHeaderFrm::removeModel(int model,int select)//添加时移除尾部按钮项
{
if (model == 0)//首页按钮不可以移除
return;
QAbstractButton* p = m_pGroupBtn->button(model);//找到该model对应的按钮
if (p)
{
m_pBtnLayout->removeWidget(p);//布局中移除按钮
m_pGroupBtn->removeButton(p);//按钮组里移除按钮
m_model.remove(model);//移除该model值
VMSPlugin* p2 = IPlugins->plugin(model);
HorizontalList.removeOne(p2->modelName());
delete p;
emit sgnRemoveModel(model, select);//发信号移除对应页面
}
}
void VMSHeaderFrm::checkedModel(int id)
{
if (isExistModel(id))
{
m_pGroupBtn->button(id)->setChecked(true);
}
}
bool VMSHeaderFrm::isExistModel(int id)
{
return m_model.contains(id);
}
void VMSHeaderFrm::clear()
{
QAbstractButton* pBtn = nullptr;
for (auto i : m_model)
{
pBtn = m_pGroupBtn->button(i);
m_pBtnLayout->removeWidget(pBtn);
m_pGroupBtn->removeButton(pBtn);
}
m_model.clear();
}
int VMSHeaderFrm::GetCurrentMeunWid()
{
return m_CurrentMenuWidth;
}
int VMSHeaderFrm::GroupButtonSize()
{
return m_pGroupBtn->buttons().size();
}
int VMSHeaderFrm::ButtonWidth()
{
QPushButton* button = this->findChild<QPushButton*>("qss_first_page_btn");
if (button) {
int SigWidth = button->width();//按钮长度
return SigWidth;
}
return 0;
}
void VMSHeaderFrm::initConnect()
{
connect(ui.qss_close_btn, &QPushButton::clicked, this, [this] { emit sgnState(WINDOWN_STATE::W_S_HIDE); });
connect(ui.qss_normal_btn, &QPushButton::clicked, this, [this] {
WINDOWN_STATE state = (WINDOWN_STATE)ui.qss_normal_btn->property("state").toInt();
state = (state == WINDOWN_STATE::W_S_NORMAL ? WINDOWN_STATE::W_S_FULL_SCREEN : WINDOWN_STATE::W_S_NORMAL);
emit sgnState(state);
Utils::setProperty(ui.qss_normal_btn, "state", (int)state);
});
connect(ui.qss_min_btn, &QPushButton::clicked, this, [this] { emit sgnState(WINDOWN_STATE::W_S_MIN); });
connect(m_pGroupBtn, &QButtonGroup::idToggled, this, &VMSHeaderFrm::onButtonToggled);
connect(menuSelection,&QMenu::triggered,this, &VMSHeaderFrm::solts_Selectmenu);
}
void VMSHeaderFrm::resizeEvent(QResizeEvent* event)
{
QSize newSize = event->size();//整个标题窗口的动态长度
int AllWidth = newSize.width();
int OtherWidth = ui.functionRegionFrm->width() + ui.logFrm->width();//其余控件的总长度
m_CurrentMenuWidth = AllWidth - OtherWidth;
QPushButton* button = this->findChild<QPushButton*>("qss_first_page_btn");
int SigWidth = button->width();//按钮长度
int Num = (m_CurrentMenuWidth - 90) / SigWidth;//能装下Num个按钮
RefreshTitle(Num-1);
QWidget::resizeEvent(event); // 调用基类的处理
}
void VMSHeaderFrm::RefreshTitle(int Num)
{
if (Num > HorizontalList.size())//拉长可装下更多水平按钮
{
int seleid = m_pGroupBtn->checkedId();//当前页面展示的id值
int addNum = Num - HorizontalList.size();//添加的个数
QList<QString> TempMeunList = MeunList;
if (addNum < TempMeunList.size())
{
//尾部添加项
for (int i = 0; i < addNum; i++)
{
if (StringToMoudel(TempMeunList.at(i)) != -1)//取下拉菜单项内容,检查其对应model值
{
AddModelToTail(StringToMoudel(TempMeunList.at(i)), seleid);//尾部添加项
m_pBtnLayout->insertWidget(HorizontalList.size() + 1, pDropBtn);
}
}
}
else
{
for (int i = 0; i < TempMeunList.size(); i++)
{
if (StringToMoudel(TempMeunList.at(i)) != -1)
{
AddModelToTail(StringToMoudel(TempMeunList.at(i)), seleid);
}
}
}
}
else if (Num < HorizontalList.size())
{
int seleid = m_pGroupBtn->checkedId();//当前页面展示的id值
int reduceNum = HorizontalList.size() - Num;//需要缩进去的个数
QList<QString> tempList = HorizontalList;
std::reverse(tempList.begin(), tempList.end());//倒置水平列表
if (tempList.size() > reduceNum)
{
for (int i = 0; i < reduceNum; i++)
{
//移除尾部信息
QString strName = tempList.at(i);//读取尾部按钮信息
int model = StringToMoudel(strName);//查询移除项model值
if (seleid == model)
{
reduceNum++;
continue;//跳过选中项
}
if(model != -1)
removeModel(model, seleid);//若存在则移除该项+
//添加下拉菜单信息
MeunList.prepend(strName);//列表菜单头部添加移除项信息
}
}
m_pBtnLayout->insertWidget(HorizontalList.size() + 1, pDropBtn);
}
RefreshMeun(MeunList);
if (MeunList.size() > 0)
{
pDropBtn->show();
}
else
pDropBtn->hide();
}
void VMSHeaderFrm::RefreshMeun(QList<QString> MeunList)
{
menuSelection->clear();
foreach (QString strItem, MeunList)
{
menuSelection->addAction(strItem);//添加下拉菜单项
}
}
void VMSHeaderFrm::AddModelToTail(int value,int select)//添加到水平按钮组尾部
{
VMSPlugin* p = IPlugins->plugin(value);
if (p == nullptr)
return;
MeunList.removeOne(p->modelName());//下拉菜单列表移除项
//添加水平按钮到尾部
PluginTitleBtn* pBtn2 = new PluginTitleBtn(p->modelName(), this);
connect(pBtn2, &PluginTitleBtn::sgnClose, this, [this, value] {solts_closeBtn(value); });
m_pGroupBtn->addButton(pBtn2, value);
m_pBtnLayout->insertWidget(HorizontalList.size() + 1, pBtn2);
m_model.insert(value);
m_Recordmodel.insert(value);
HorizontalList.append(p->modelName());//水平列表尾部添加一项
emit sgnaddVmsPage(value, select);//发信号添加一项对应的新页面
}
void VMSHeaderFrm::ReduceModel(int value)
{
}
void VMSHeaderFrm::solts_Selectmenu(QAction* action)//下拉菜单点击
{
if (action)
{
QString selectStr = action->text();
MeunList.removeOne(selectStr);//下拉菜单中移除点击项
//添加一项新的按钮
if (StringToMoudel(selectStr) != -1)
{
addModel(StringToMoudel(selectStr));//添加水平按钮
checkedModel(StringToMoudel(selectStr));//选中该项
emit sgnaddVmsPage(StringToMoudel(selectStr), StringToMoudel(selectStr));//添加对应页面
}
}
}
void VMSHeaderFrm::solts_closeBtn(int model)
{
if (MeunList.size() == 0)
{
removeModel(model,0);//只进行按钮移除
}
else
{
removeModel(model,0);//移除按钮
//水平菜单尾部添加下拉菜单的内容
int model = StringToMoudel(MeunList.at(0));
AddModelToTail(model,0);
RefreshMeun(MeunList);
if (MeunList.size() > 0)
{
pDropBtn->show();
}
else
pDropBtn->hide();
}
}
int VMSHeaderFrm::StringToMoudel(QString str)
{
foreach(const int& value, m_Recordmodel)
{
if (IPlugins->pluginName(value) == str)
{
return value;
}
}
return -1;
}
void VMSHeaderFrm::onButtonToggled(int id, bool checked)
{
if (checked)
{
emit sgnChangedModel(id);
}
}
#pragma once
#include <QtWidgets/QWidget>
#include "ui_SmartVMS.h"
QT_BEGIN_NAMESPACE
namespace Ui { class SmartVMSClass; };
QT_END_NAMESPACE
class SmartVMS : public QWidget
{
Q_OBJECT
public:
SmartVMS(QWidget *parent = nullptr);
~SmartVMS();
private:
void initUI();
void onStateChanged(int state);
void onAddPage(int model);
void onRemovePage(int model, int selectmodel);
void onChangePage(int model);
void initConnect();
private:
Ui::SmartVMSClass* ui;
class QStackedWidget* m_pStackWdt = nullptr;
class VMSHeaderFrm* m_pHeadFrm = nullptr;
class VMSFirstPageFrm* m_pFirstPageFrm = nullptr;
QMap<int, class FrameBase*> m_mapFrm;
private slots:
void addVmsPage(int model, int selectmodel);
};
用法:
m_pHeadFrm = new VMSHeaderFrm(this);
pLay->addWidget(m_pHeadFrm);
m_pHeadFrm->addModel(model); //添加对应按钮