QT 自动伸缩的工具栏和自定义配置的工具栏 QToolBar更多按钮的样式设置

1.实现目标

如下图所示,播放窗口的工具栏,有很多按钮,当窗口的宽度不够时,能够自动生成更多按钮,点击更过按钮就会出现多余按钮的menu菜单;

2。实现方法

一开始我还想着加个按钮控件,在播放窗口resize函数中判断工具栏的宽度能容纳几个按钮,判断宽度是否够,如果不够的话,则要显示更多按钮,点击更多按钮,在弹出个QMenu菜单,显示更多的工具按钮;后来发现是我想复杂了,其实QToolBar已经支持了这个自动缩放自动跳整的功能;只要全部加到QToolBar中,它会自己根据宽度来判断显示几个,是否要显示更多按钮,点击按钮自动弹出Qmenu菜单;而且还可以是QToolBar中只有图标,更多菜单是图标加汉字说明;

2.1点击更多按钮后默认图标会很小,通过下面定义,可以改变图标大小;

 

#pragma once
#include <QProxyStyle>
class CustomStyle : public QProxyStyle
{
    Q_OBJECT

public:
    virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
    {
        if (metric == QStyle::PM_SmallIconSize|| metric==QStyle::PM_ButtonIconSize) {
            return 24;
        }
        return QProxyStyle::pixelMetric(metric, option, widget);
    }
};

2.2工具栏按钮头文件

#ifndef PLAYWNDTOOLBAR_H
#define PLAYWNDTOOLBAR_H

#include <QWidget>
#include "ui_PlayWndToolBar.h"
#include <QToolBar>
#include "MenuBar/Menu.h"
class PlayWndToolBar : public QWidget
{
    Q_OBJECT

public:
    PlayWndToolBar(QWidget *parent = 0);
    ~PlayWndToolBar();
    int UpdateToolBar(QList<int> tools);
    int setToolVisiable(int id, bool visible);
    bool GetToolCheckState(int id);
    void SetToolCheckState(int id, bool checked=false);
    int ClickTool(int id);
signals:
    void SignalToolBtnClicked(int id, bool checked);
private:
    Ui::PlayWndToolBar ui;
    QToolBar* ptr_toolbar_{ nullptr };
    QAction* CreateActionById(int id);
    void InitToolBarExtendedMenu(QToolBar* ptr_toolbar);
    QMap<int, QAction*> m_mapAction;
};

#endif // PLAYWNDTOOLBAR_H

 

2.3工具栏按钮cpp文件

#include "PlayWndToolBar.h"
#include <QMenu>
#include "VideoConfig/ToolActionBaseDef.h"
#include "VideoConfig/Controller/LocalSystemConfigManager.h"
#pragma execution_character_set("utf-8")
#include"CustomStyle.h"
#include <QToolButton>
PlayWndToolBar::PlayWndToolBar(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    //设置为无边框,自定义关闭,放大,缩小按钮
    this->setWindowFlags(Qt::FramelessWindowHint);
    ptr_toolbar_ = new QToolBar(ui.widgetToolBar);
    ptr_toolbar_->setObjectName("ptr_playwnd_toolbar_");
    ptr_toolbar_->setFixedHeight(32);
    ptr_toolbar_->setIconSize(QSize(32, 32));
    ptr_toolbar_->setToolButtonStyle(Qt::ToolButtonIconOnly);//设置只有图标
    ptr_toolbar_->setContextMenuPolicy(Qt::PreventContextMenu);
    ptr_toolbar_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);//横向设置为preferred,会自动根据长度调整,否则不会
    CustomStyle* pCustomStytle = new CustomStyle();//更多菜单菜单按钮的图标默认会很小,这个作用是让菜单图标变大
    ptr_toolbar_->setStyle(pCustomStytle);
    ui.horizontalLayToolbar->addWidget(ptr_toolbar_);
    /*QAction* paction = new QAction();
    QIcon favorite_icon_image;
    favorite_icon_image.addPixmap(QPixmap(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_record_nor.svg"), QIcon::Normal);
    favorite_icon_image.addPixmap(QPixmap(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_record_sel.svg"), QIcon::Active);
    paction->setIcon(favorite_icon_image);
    paction->setIconText("录像");*/
    //ptr_toolbar_->addAction(paction);
    
//设置样式:弹出菜单,文字距离图标30
    ptr_toolbar_->setStyleSheet("QToolBar{background:#3D3D3D;} QMenu::item{ height:34px;width:120px; padding-left:30px;} QMenu::item:pressed { background-color: rgb(32,128,247);color:#FFFFFF }");
    InitToolBarExtendedMenu(ptr_toolbar_);
    //connect(ui.pBMore, &QPushButton::clicked, this, [=]() { 
    //    /*ptr_toolbar_->removeAction(paction);
    //    ptr_extral_menu->addAction(paction);*/
    //    ptr_extral_menu->exec(QCursor::pos());
    //});
    //ui.pBMore->hide();
}

PlayWndToolBar::~PlayWndToolBar()
{

}

int PlayWndToolBar::UpdateToolBar(QList<int> tools)
{
    QList<QAction*> listaction=ptr_toolbar_->actions();
    for (int i = 0; i < listaction.size(); i++)
    {
        ptr_toolbar_->removeAction(listaction.at(i));
    }
    for (int i=0;i<tools.size();i++)
    {
        if (m_mapAction.find(tools.at(i))!=m_mapAction.end())//已有
        {
            ptr_toolbar_->addAction(m_mapAction[tools.at(i)]);
        }
        else
        {
            QAction* pAction = CreateActionById(tools.at(i));
            if (pAction!=NULL)
            {
                ptr_toolbar_->addAction(pAction);
                m_mapAction.insert(tools.at(i), pAction);
            }
            
        }
    }
    //listaction = ptr_extral_menu->actions();
    //ptr_toolbar_->setMaximumWidth(width);
    //ptr_toolbar_->resize(width, 32);
    //for (int i = 0; i < listaction.size(); i++)
    //{
    //    ptr_extral_menu->removeAction(listaction.at(i));
    //}
    //for (int i=shownum;i<tools.size();i++)
    //{
    //    if (m_mapAction.find(tools.at(i)) != m_mapAction.end())//已有
    //    {
    //        ptr_extral_menu->addAction(m_mapAction[tools.at(i)]);
    //    }
    //    else
    //    {
    //        QAction* pAction = CreateActionById(tools.at(i));
    //        if (pAction != NULL)
    //        {
    //            ptr_extral_menu->addAction(pAction);
    //        }
    //    }
    //}
    /*if (shownum<tools.size())
    {
        ui.pBMore->show();
    }
    else
    {
        ui.pBMore->hide();
    }*/
    return 0;
}

int PlayWndToolBar::setToolVisiable(int id, bool visible)
{
    int ret = -1;
    if (m_mapAction.find(id)!=m_mapAction.end())
    {
        m_mapAction[id]->setVisible(visible);
        ret = 0;
    }
    return ret;
}

bool PlayWndToolBar::GetToolCheckState(int id)
{
    bool ret = false;
    if (m_mapAction.find(id) != m_mapAction.end())
    {
        ret=m_mapAction[id]->isChecked();
    }
    return ret;
}

void PlayWndToolBar::SetToolCheckState(int id,bool checked)
{
    if (m_mapAction.find(id) != m_mapAction.end())
    {
        m_mapAction[id]->setChecked(checked);
    }
}

int PlayWndToolBar::ClickTool(int id)
{
    int ret = -1;
    if (m_mapAction.find(id) != m_mapAction.end())
    {
        m_mapAction[id]->trigger();
        ret = 0;
    }
    return ret;
}

QAction* PlayWndToolBar::CreateActionById(int id)
{
    QString strType = "";
    QAction* pAction=NULL;
    pAction = new QAction();
    ToolActionBaseDef::ToolActionId toolid = (ToolActionBaseDef::ToolActionId)id;
    switch (toolid)
    {
    case ToolActionBaseDef::ActSnapShot://抓图
        strType=("snapshot");
        pAction->setText("抓图");
        break;
    case ToolActionBaseDef::ActRecord://录像
        strType=("record");
        pAction->setCheckable(true);
        pAction->setText("开始录像");
        pAction->setToolTip("开始录像");
        connect(pAction, &QAction::triggered, [=](bool checked) {
            if (checked)
            {
                pAction->setText("停止录像");
                pAction->setToolTip("停止录像");
            }
            else
            {
                pAction->setText("开始录像");
                pAction->setToolTip("开始录像");
            }
        });
        break;
    case ToolActionBaseDef::ActClip:
        strType=("clip");  // 剪裁
        pAction->setCheckable(true);
        pAction->setText("开始剪辑");
        pAction->setToolTip("开始剪辑");
        connect(pAction, &QAction::triggered, [=](bool checked) {
            if (checked)
            {
                pAction->setText("停止录像");
                pAction->setToolTip("停止录像");
            }
            else
            {
                pAction->setText("开始剪辑");
                pAction->setToolTip("开始剪辑");
            }
        });
        break;
    case ToolActionBaseDef::ActVoice:
        strType=("voice");
        pAction->setCheckable(true);
        pAction->setText("打开声音");
        pAction->setToolTip("打开声音");
        connect(pAction, &QAction::triggered, [=](bool checked) {
            if (checked)
            {
                pAction->setText("关闭声音");
                pAction->setToolTip("关闭声音");
            }
            else
            {
                pAction->setText("打开声音");
                pAction->setToolTip("打开声音");
            }
        });
        break;
    /*case ToolActionBaseDef::ActDigitZoom:
            strType=("DigitalZoom");
            break;
    case ToolActionBaseDef::ActStreamInfo:
        strType=("CodeFlowInformation");
        break;
    case ToolActionBaseDef::ActVideoEnhance:
        strType=("VideoEnhancementKxymFxkcRb");
        break;
    case ToolActionBaseDef::ActSwitchStream:
        strType=("SwitchStreamTypeMEByrOKBEBPh");
        break;
    case ToolActionBaseDef::ActFisheyeExpand:
        strType=("FisheyeExpansion");
        break;
    case ToolActionBaseDef::ActProjectOnWall:
        strType=("OnTheWallYMQjuSKWuxlcYt");
        break;
    case ToolActionBaseDef::ActCreateDigitZoomRect:
        strType=("LzinJeCFDfFNWAdAyv");
        break;
    case ToolActionBaseDef::ActCreateFisheyeExpandRect:
        strType=("SYsBmbMVVddcQbHIps");
        break;*/
    case ToolActionBaseDef::ActWndPTZ:
        strType=("ptz");
        pAction->setCheckable(true);
        pAction->setText("打开云台");
        pAction->setToolTip("打开云台");
        connect(pAction, &QAction::triggered, [=](bool checked) {
            if (checked)
            {
                pAction->setText("关闭云台");
                pAction->setToolTip("关闭云台");
            }
            else
            {
                pAction->setText("打开云台");
                pAction->setToolTip("打开云台");
            }
        });
        break;
    /*case ToolActionBaseDef::ActInstantPlayback:
        strType=("InstantReplayHHnDasyk");
        break;
    case ToolActionBaseDef::ActJumpPlayBack:
        strType=("playback");
        break;
    case ToolActionBaseDef::ActPictureView:
        strType=("ImagePreview");
        break;
    case ToolActionBaseDef::ActIoControl:
        strType=("AlarmOutput");
        break;*/
    case ToolActionBaseDef::ActVoiceTalk:
        strType=("talk");
        pAction->setCheckable(true);
        pAction->setText("开始对讲");
        pAction->setToolTip("开始对讲");
        connect(pAction, &QAction::triggered, [=](bool checked) {
            if (checked)
            {
                pAction->setText("停止对讲");
                pAction->setToolTip("停止对讲");
            }
            else
            {
                pAction->setText("开始对讲");
                pAction->setToolTip("开始对讲");
            }
        });
        break;
    /*case ToolActionBaseDef::ActGunBallLinkage:
        strType=("ManualLinkageXKcVVbWi");
        break;
    case ToolActionBaseDef::ActCrowdSituation:
        strType=("PersonnelSituationMoHMjjCdPl");
        break;*/
    case ToolActionBaseDef::ActDownload:
        strType=("download");
        pAction->setText("下载");
        pAction->setToolTip("下载");
        break;
    //case ToolActionBaseDef::ActTag:
    //    strType=("AddTagsJEJawyEj");
    //    break;
    //case ToolActionBaseDef::ActLock:
    //    strType=("LockTheVideowbhEyJZAZRxYMHzd");
    //    break;
    //case ToolActionBaseDef::ActDrawFrame:
    //    strType=("SmokeFramePlaybackQEdJCzZWG");
    //    break;
    //case ToolActionBaseDef::ActAdvanceSeconds:
    //    strType=("ForwardForSecondscqlcqpzgfN");
    //    break;
    //case ToolActionBaseDef::ActSegmentPlayback:
    //    strType=("SegmentedPlaybackMlCaRlzC");
    //    break;
    //case ToolActionBaseDef::ActSynPlayback:
    //    strType=("SynPlayback");
    //    break;
    case ToolActionBaseDef::ActInstantReplay://快速回放
        strType=("instantreplay");
        pAction->setCheckable(true);
        pAction->setText("快速回放");
        pAction->setToolTip("快速回放");
        connect(pAction, &QAction::triggered, [=](bool checked) {
            if (checked)
            {
                pAction->setText("返回");
                pAction->setToolTip("返回");
            }
            else
            {
                pAction->setText("快速回放");
                pAction->setToolTip("快速回放");
            }
        });
        break;
    //case ToolActionBaseDef::ActDisplayRotate://画面旋转
    //    strType=("HCP-ControlClient.01bbc3a41711441caa2b154043b153a7.button");
    //    break;
    //case ToolActionBaseDef::ActOneTouchPark://云台守望
    //    strType=("YuntaiWatchman");
    //    break;
    //case 302:  // 抓图打印
    //    strType=("Print");
    //case 303:  // 可视追踪
    //    strType=("VisualTrackingksjvBhjq");
    //    break;
    //case 304:  // ActSearchByImage
    //    strType=("SearchByPicture");
    //    break;
    //case ToolActionBaseDef::ActHealthStatus:  // 监控点状态
    //    strType=("CameraStatus");
    //    break;
    //case 306:  // 布撤防
    //    strType=("ClothRemovalIhetFufd");
    //case 307:  // ActGoToVCA
    //    strType=("VCARetrievalbyXHuolipNGDNDcV");
    //    break;
    //    //case 308:  // 枪球联动
    //    //    strType=("ManualLinkageXKcVVbWi");
    //case 309:  // 广播
    //    strType=("Broadcast");
    //    break;
    //case 310:  // 目标属性叠加
    //    strType=("HCP-ControlClient.ef621b1899474895b0378a2c891fab1a.name");
    //    break;
    //case ToolActionBaseDef::ActCloseSingle:
    //    strType=("Close");
    //    break;
    //case ToolActionBaseDef::ActCloseAllWindows:
    //    strType=("CloseAll");
    //    break;
    //case ToolActionBaseDef::ActLocateToTree:
    //    strType=("LocateToTree");
    //    break;
    //case ToolActionBaseDef::ActReturn:
    //    strType=("Return");
    //    break;
    //case ToolActionBaseDef::ActProblemCreate:
    //    strType=("ProblemCreate");
    //    break;
    //case ToolActionBaseDef::ActAddFavorite:
    //    strType=("AddFavorite");
    //    break;
    //case ToolActionBaseDef::ActFullScreen:
    //    strType=("SwitchFullScreen");
    //    break;
    default:
        break;
    }
    if (strType!="")
    {
        QIcon button_icon;
        button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_nor.svg").arg(strType)), QIcon::Normal);
        button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_dis.svg").arg(strType)), QIcon::Disabled);
        button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_hover.svg").arg(strType)), QIcon::Active);
        button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_nor.svg").arg(strType)), QIcon::Selected);
        if (pAction->isCheckable())
        {
            button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_sel.svg").arg(strType)), QIcon::Normal, QIcon::On);
            button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_dis.svg").arg(strType)), QIcon::Disabled, QIcon::On);
            button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_sel.svg").arg(strType)), QIcon::Active, QIcon::On);
            button_icon.addPixmap(QPixmap(QString(":/preview/Resources/pic/Preview/ToolIcon/icon_tool_%1_sel.svg").arg(strType)), QIcon::Selected, QIcon::On);
        }
        pAction->setIcon(button_icon);
        pAction->setData(toolid);    
        connect(pAction, &QAction::triggered, [=](bool checked) {
            emit SignalToolBtnClicked(toolid, checked);
        });
    }
    else
    {
        if (pAction != NULL)
        {
            delete pAction;
            pAction = NULL;
        }
    }
    
    return pAction;
}
void PlayWndToolBar::InitToolBarExtendedMenu(QToolBar* ptr_toolbar)
{
    // QToolBar更多按钮样式图标设置
    auto* ptr_ext_btn = ptr_toolbar->findChild<QToolButton*>("qt_toolbar_ext_button");
    ptr_ext_btn->setToolTip(QObject::tr("更多")); // tip:更多

                                                  // 更多按钮显示样式, 自测过程发现写在qss中不生效,使用QIcon代替
    QIcon extbutton_icon;
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_nor.svg"), QIcon::Normal);
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_horver.svg"), QIcon::Active);
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_horver.svg"), QIcon::Selected);
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_disr.svg"), QIcon::Disabled);
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_nor.svg"), QIcon::Normal, QIcon::On);
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_horver.svg"), QIcon::Active, QIcon::On);
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_horver.svg"), QIcon::Selected, QIcon::On);
    extbutton_icon.addPixmap(QPixmap(":/playback/Resources/pic/Playback/ToolIcon/icon_tool_more_dis.svg"), QIcon::Disabled, QIcon::On);
    ptr_ext_btn->setIcon(extbutton_icon);

    //// 取出先前的扩展菜单,并创建新的菜单,准备替换
    //auto* old_ext_menu = ptr_ext_btn->menu();
    //HUIControl::CMenu* ptr_new_menu = new HUIControl::CMenu(ptr_ext_btn);
    ////ptr_new_menu->setStyle(old_ext_menu->style());
    //ptr_new_menu->setWindowFlag(Qt::NoDropShadowWindowHint);
    ////ptr_new_menu->setObjectName(menu_obj_name);
    //// 并设置新的菜单
    //ptr_ext_btn->setMenu(ptr_new_menu);

    //// 针对从右向左布局的语种通过右侧留间隙的方式,保证右侧图标可见
    ////             if(QGuiApplication::layoutDirection() == Qt::RightToLeft)
    ////                 ptr_new_menu->setStyleSheet("QMenu::item{ padding-right: 42; }");

    //if (init_width)
    //    ptr_new_menu->setMinimumWidth(213);

    //// 断开QToolButton内部的信号槽关联,接管弹出菜单处理,避免因如下槽函数执行偏晚,
    //// action未填入,菜单宽度为0,导致阿语(从右向左布局)出现弹出菜单的方向不对问题
    //ptr_ext_btn->disconnect(ptr_ext_btn);
    //QObject::connect(ptr_ext_btn, &QToolButton::pressed, ptr_toolbar, [old_ext_menu, ptr_new_menu, ptr_ext_btn]()
    //{
    //    ptr_new_menu->clear();
    //    ptr_new_menu->addActions(old_ext_menu->actions());
    //    //ptr_new_menu->setStyle(new CPlayIconStyle);
    //    ptr_ext_btn->showMenu();
    //});
}

 

posted @ 2024-12-16 19:33  一字千金  阅读(45)  评论(0编辑  收藏  举报