【问题标题】:add the same menu to multiple windows with Qt使用 Qt 将相同的菜单添加到多个窗口
【发布时间】:2017-01-22 12:42:19
【问题描述】:

我正在用 Qt 编写一个程序。 我有一个 QMainWindow 和一个名为 createMenus() 的函数,它返回一个 QMenuBar*。

在 MainWindow 类中:QMainWindow,我调用:this->setMenuBar(createMenus());

所以我有一个漂亮的 MainWindow,顶部有一个菜单。

现在,在“文件”中,我想放置一个按钮来创建一个新窗口(大概是一个 QWidget?)。 我想在新窗口的顶部显示相同的 MenuBar。

void MainWindow::createWindow()
{
    QWidget* window = new QWidget;

    QVBoxLayout* center_box = new QVBoxLayout;
    center_box->setContentsMargins(0, 0, 0, 0);
    center_box->setSpacing(0);

#ifndef Q_OS_MAC
    QMenuBar* newMenu = createMenus();
    center_box->setMenuBar(newMenu);
#endif

    window->setLayout(center_box);
}

这有效(在 Linux 中),因为 QMenuBar 显示在新窗口中。 后果就是MainWindow中的QMenuBar消失了。

有人可以指导我使用相同的 QMenuBar 创建多个窗口的最佳实现吗?

【问题讨论】:

  • 您必须使用new 创建新菜单,否则其他窗口将获得所有权
  • 嗨@deW1,我该怎么办?现在,在 createMenus() 中,我有函数“bar = new QMenuBar()”和“return bar;”。因此,从技术上讲,*newMenu 始终是一个新菜单。结果,上面的代码在新窗口中没有显示任何菜单。
  • 向我们展示更多代码,例如通过创建Minimal, Complete, and Verifiable example。至少我们需要看到你的createMenus() 的代码,否则我们只能猜测。
  • 我所做的是创建一个创建新 QMenuBar 并填充它的方法,然后从每个窗口的构造函数中调用该方法一次。这样每个窗口都有自己的 QMenuBar,但它们都是相同的,没有代码重复。

标签: c++ qt


【解决方案1】:

我查看了您的问题并注意到了相同的行为,但是您不能简单地复制现有的 QMenuBar QMainWindow

但是,您可以像以前一样使用工厂方法,但您必须确保不会返回 QMenuBar,否则菜单不会显示。

可能的实现:

QMenuBar* MainWindow::createMenu()
{
    QMenuBar *menu = new QMenuBar();


    menu->addMenu("Test0");
    menu->addMenu("Test1");
    menu->addMenu("Test2");
    menu->addMenu("Test3");

    return menu;
}

然后在你的方法中你可以这样做:

void MainWindow::createWindow()
{
    QWidget* window = new QWidget;

    QVBoxLayout* center_box = new QVBoxLayout;

#ifndef Q_OS_MAC
    center_box->setMenuBar(createMenu());
#endif

    window->setLayout(center_box);
    window->show();
}

另一种方法是将QMenuBar 子类化,但如果您想创建特定类型的实现或添加到现有类的功能,这更合适。

custommenubar.h

#ifndef CUSTOMMENUBAR_H
#define CUSTOMMENUBAR_H

#include <QObject>
#include <QMenuBar>

class CustomMenuBar : public QMenuBar
{
    Q_OBJECT

    public:
        explicit CustomMenuBar();
};

#endif // CUSTOMMENUBAR_H

custommenubar.cpp

#include "custommenubar.h"

CustomMenuBar::CustomMenuBar()
{
    addMenu("Test");
    addMenu("1");
    addMenu("2");
    addMenu("3");
}

然后在你的方法中:

void MainWindow::createWindow()
{
    QWidget* window = new QWidget;

    QVBoxLayout* center_box = new QVBoxLayout;

#ifndef Q_OS_MAC
    QMenuBar* newMenu = new CustomMenuBar();
    center_box->setMenuBar(newMenu);
#endif

    window->setLayout(center_box);
    window->show();
}

确保你把所有东西都清理干净:)

【讨论】:

  • 我做到了。答案仍然强烈宣传子类化以填充菜单栏。当然这是有效,但与使用工厂函数相比,它在几个层面上都不好:1. 它会产生很多不必要的代码噪音,2. 它添加了另一个 moc 和编译器调用,添加到 compile和链接时间,3。它添加了六个符号(类、构造函数、元对象+函数)而不是 1 仅用于一个函数,增加了二进制大小和加载时间,4。它使代码共享更加困难(想想创建 MyMenuBar1 和MyMenuBar2 部分共享项目)
  • @E4z9 我可以稍后交换它并包含工厂方法。
猜你喜欢
  • 1970-01-01
  • 2022-08-20
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多