c – 如何在qt中的状态栏中创建菜单,如PC开始菜单

在我的qt应用程序中,我设计了几个图标的状态栏.在状态栏的左侧,我添加了菜单图标(QPixmap),当我点击该图标时,我需要显示类似于PC开始菜单的菜单.我搜索了很多,但我没有找到Qwidget.

这是我的qt应用程序窗口

根据我最近的评论,我在下面添加了我编辑的代码,因为我无法在评论部分添加代码,plz建议一个解决方案

//Menu Button
    menuBtn->setIcon(QPixmap(":/new/prefix1/ic_menu_black.png"));
    statusBar()->addWidget(menuBtn);
    connect(menuBtn,SIGNAL(clicked(bool)),this,SLOT(showPopupMenu()));

void MainWindow::showPopupMenu(){


    QMenu qMenuStart;

    QAction qCmdStart1(QString::fromUtf8("Product Details"), &qMenuStart);
    qMenuStart.addAction(&qCmdStart1);

    QAction qCmdStart2(QString::fromUtf8("Memory Status"), &qMenuStart);
    qMenuStart.addAction(&qCmdStart2);

    QObject::connect(&qCmdStart1, &QAction::triggered,[](bool){
        qDebug() << "Product Details triggered"; }
    );
    QObject::connect(&qCmdStart2, &QAction::triggered,[](bool){
        qDebug() << "Memory Status triggered"; }
    );

    qMenuStart.exec();

    menuBtn->setMenu(&qMenuStart);

    qMenuStart.show();
    qMenuStart.popup(mapToGlobal(pos() - QPoint(0, qMenuStart.height())));

    qDebug()<<"Menu Clicked!";

}

点击菜单按钮弹出菜单

解决方法:

我拿了你的示例代码并对其进行了更改,以说明我在最新评论中所描述的内容:

将成员变量添加到MainWindow声明:

QMenu *menuStart;

更改的示例代码:

// configure start menu:
menuStart = new QMenu(menuBtn);
menuStart->addAction(QString::fromUtf8("Product Details"),
  [](bool){
    qDebug() << "Product Details triggered"; }
  );
menuStart->addAction(QString::fromUtf8("Memory Status"),
  [](bool){
    qDebug() << "Memory Status triggered"; }
  );
//Menu Button
menuBtn->setIcon(QPixmap(":/new/prefix1/ic_menu_black.png"));
menuBtn->setMenu(menuStart);
statusBar()->addWidget(menuBtn);
connect(menuBtn,SIGNAL(clicked(bool)),this,SLOT(showPopupMenu()));

注意:

我将menuBtn设置为menuStart的父级.因此,menuBtn应该在它自身被销毁时管理menuStart的销毁.

信号处理程序分别变短:

void MainWindow::showPopupMenu()
{
  menuStart->show(); // <-- trick to force layout of the menu before height() is called
  // position menu relative to menuBtn at popup
  menuStart->popup(
    mapToGlobal(menuBtn->pos() - QPoint(0, menuStart->height())));

  qDebug()<<"Menu Clicked!";
}

我仔细地做了,但无法测试它(因为它不是MCVE).所以,请带上一粒“盐”.

注意:

我刚刚意识到你使用“pre-Qt5”风格的连接信号处理程序. Qt5引入了一个很好的extension to its signals支持函数指针以及方法指针.因此,我能够将信号处理程序简单地称为lambdas.(lambdas就是这些[](bool){/*…*/}我连接到动作槽.我总是怀疑这些新的lambdas直到我意识到它们是为信号处理程序编写非常简单的适配器以及制作非常紧凑的示例代码的绝佳工具.)

有关Lambdas的更新:

方括号[]可用于将变量添加到lambda的环境(或上下文).如果它是空的(因为我使用它),只能使用全局变量和函数.使用[this]表示当前将此指针添加到环境中.因此,lambda可以访问当前类实例的成员变量.

当我第一次认识到lambdas时,我经常看到[=]意味着lambda获取调用函数的当前上下文(例如每个本地函数变量的副本).我个人认为这很危险,特别是对于信号处理程序.我将详细阐述一下:

lambda的环境允许访问lambda体中的“外部变量”.可以通过值或通过引用添加变量.如果变量是通过引用提供的,则可以在lambda体中访问它,但它不会授予“外部”变量的生命周期足够长. (如果不是它会产生一个“悬空引用”,具有相同的未定义行为,如悬挂指针.)它是否有助于防止引用?不.对于原始类型(例如int或float)来说这很好,但对于对象来说可能效率低(甚至语义错误).使用指向对象的指针与使用引用一样危险.因此,应谨慎使用lambda的环境.

根据经验,我个人使用以下方法来实现lambda:我总是从一个空的环境([])开始.如果我在lambda中识别出我需要的变量,我将它添加到环境中,我认为它足够的寿命(或寻找替代).

更新:

由于我是SVG的私人粉​​丝,我准备了一个(类似的)菜单图标作为SVG文件:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="32" height="32">
  <title>Start Menu</title>
  <desc>Start Menu</desc>
  <rect id="line"
    x="4" y="6" width="24" height="4"
    style="stroke:none;fill:#444"/>
  <use xlink:href="#line" transform="translate(0,8)"/>
  <use xlink:href="#line" transform="translate(0,16)"/>
 </svg>

您可以将其保存在文本文件ic_menu_black.svg中,并尝试将其加载到您的应用程序中.

遗憾的是,Qt的进口商仅对SVG提供了有限的支持.因此,并非SVG中可能的每个技巧都能在Qt中正常工作.因此,我从我们的Qt应用程序中修改了一个图标的副本,以确保它能够正常工作.

上一篇:android-如何在我的应用程序中将状态栏设置为白色背景和黑色文本(黑色图标)


下一篇:android – 状态栏遮盖了Overlay Action Bar