工具栏按钮下拉菜单

时间:2023-01-20 08:57:17

     这里要实现的是这样一种界面效果,点击工具栏上的一个按钮,在这个按钮的下面弹出一个下拉菜单,这给分组式工具条设计带来不少便利。

                                 工具栏按钮下拉菜单

  这种样式在execl中非常常见。


实现的核心思想是:创建一个弹出式菜单,将其弹出的位置设置在按钮的下面。当然,可以从按钮对象派生一个对象实现这个功能。这里使用的从一个窗体对象派生,在其内部聚合了一个按钮和菜单对象。

struct GZLTMenuData
{
    int pos;
    int para;

    GZLTMenuData(){}
    GZLTMenuData(int p,int a):pos(p),para(a){}
};
Q_DECLARE_METATYPE(GZLTMenuData)

class GZLTBorderWidget : public QWidget
{
    Q_OBJECT
public:
    GZLTBorderWidget(QWidget * parent = NULL);

signals:
    void signalBorderSetting(int pos,int para);

public slots:
    void onClick();
    void onTriggered(QAction * action);

protected:
    void addMenuSeparator();
    void addMenuItem(const QIcon & icon,const QString & text,const GZLTMenuData & data);

protected:
    QLabel * m_icon;
    QPushButton * m_button;
    QHBoxLayout * m_layout;
    QMenu * m_menu;
};



GZLTBorderWidget::GZLTBorderWidget(QWidget * parent)
    :QWidget(parent)
{
    //ppp = parent;

    m_icon = new QLabel;
    m_button = new QPushButton(this);
    m_layout = new QHBoxLayout;
    m_menu = new QMenu(this);

    m_layout->addWidget(m_icon);
    m_layout->addWidget(m_button);

    this->setLayout(m_layout);
    m_icon->setFixedSize(20,20);
    m_button->setFixedSize(20,20);

    QIcon defaultIcon(":/res/icon/border01.png");
    m_icon->setPixmap(defaultIcon.pixmap(20));
    m_button->setIcon(QIcon(":/res/icon/selButton.png"));

    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("左框线"),
                GZLTMenuData(BORDER_POS_LEFT,BORDER_PARA_SMALLLINE));
    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("右框线"),
                GZLTMenuData(BORDER_POS_RIGHT,BORDER_PARA_SMALLLINE));
    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("上框线"),
                GZLTMenuData(BORDER_POS_TOP,BORDER_PARA_SMALLLINE));
    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("下框线"),
                GZLTMenuData(BORDER_POS_BUTTOM,BORDER_PARA_SMALLLINE));

    addMenuSeparator();
    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("去除左框线"),
                GZLTMenuData(BORDER_POS_LEFT,BORDER_PARA_NOLINE));
    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("去除右框线"),
                GZLTMenuData(BORDER_POS_RIGHT,BORDER_PARA_NOLINE));
    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("去除上框线"),
                GZLTMenuData(BORDER_POS_TOP,BORDER_PARA_NOLINE));
    addMenuItem(QIcon(":/res/icon/border01.png"),QStringLiteral("去除下框线"),
                GZLTMenuData(BORDER_POS_BUTTOM,BORDER_PARA_NOLINE));

    connect(m_button,SIGNAL(clicked()),SLOT(onClick()));
    connect(m_menu,SIGNAL(triggered(QAction*)),SLOT(onTriggered(QAction*)));
}

void GZLTBorderWidget::addMenuItem(const QIcon & icon,const QString & text,const GZLTMenuData & data)
{
     QAction * action  = m_menu->addAction(icon,text);
     action->setData(QVariant::fromValue(data));
}
void GZLTBorderWidget::addMenuSeparator()
{
    m_menu->addSeparator();
}

void GZLTBorderWidget::onClick()
{
    QWidget * parent = this->parentWidget();
    QPoint pt = this->pos();
    QPoint st = parent->mapToGlobal(pt);
    st.setY(st.y()+this->height());
    m_menu->popup(st);
}

void GZLTBorderWidget::onTriggered(QAction * action)
{
    if(action)
    {
        QIcon icon = action->icon();
        m_icon->setPixmap(icon.pixmap(20));

        GZLTMenuData data = action->data().value<GZLTMenuData>();

        emit signalBorderSetting(data.pos,data.para);
    }
}