如何使用 Qt 在同一个 UI 中添加菜单栏和按钮?

Posted

技术标签:

【中文标题】如何使用 Qt 在同一个 UI 中添加菜单栏和按钮?【英文标题】:How to add a menu bar and a push button in the same UI using Qt? 【发布时间】:2021-08-27 10:43:51 【问题描述】:

我正在尝试使用 Qt 5.15 编写具有按钮和菜单栏的界面。

问题:主要问题是即使实例化了菜单栏 (menuBar),它在 .ui 输出窗口中可见 .此外,一个按钮 (quitButton) 被实例化,它在 .ui 输出窗口中可见。我可能会遗漏一些东西。我有一种感觉,在 Qt 中,您要么获得菜单栏,要么获得按钮小部件,但不能同时获得两者。这样对吗?此外,如何在同一个 .ui 窗口中同时获取菜单栏和按钮?

这是我的 QtNotepad.cpp 代码

#include "qtnotepad.h"

QtNotepad::QtNotepad(QWidget *parent)
    : QWidget(parent)

    openAction = new QAction(tr("&Open"), this);
    saveAction = new QAction(tr("&Save"), this);
    exitAction = new QAction(tr("&Exit"), this);

    connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
    connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
    connect(exitAction, SIGNAL(triggered()), this, SLOT(quit()));

    QMenuBar* menuBar = new QMenuBar(nullptr);

    fileMenu = menuBar->addMenu(tr("&File"));

    fileMenu->addAction(openAction);
    fileMenu->addAction(saveAction);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAction);

    textEdit = new QTextEdit;
    quitButton = new QPushButton(tr("Quit"));

    connect(quitButton, SIGNAL(clicked()), this, SLOT(quit()));

    QHBoxLayout* layout = new QHBoxLayout;
    layout->addWidget(textEdit);
    layout->addWidget(quitButton);

    setLayout(layout);

    setWindowTitle(tr("Notepad"));



void QtNotepad::open()

    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("Text Files (*.txt);; C++ Files(*.cpp *.h);;.dat Files(*.dat)"));

    if (fileName != "")
    
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly))
        
            QMessageBox::critical(this, tr("Error"), tr("Could not open file"));
            return;
        
        QTextStream in(&file);
        textEdit->setText(in.readAll());
        file.close();
    


void QtNotepad::save()

    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), ""), tr("Text Files (*.txt);;C++ Files (*.cpp *.h)");

    if (fileName != "")
    
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly))
        
            //error message
        
        else
        
            QTextStream stream(&file);
            stream << textEdit->toPlainText();
            stream.flush();
            file.close();
        
    


void QtNotepad::quit()

    QMessageBox messageBox;
    messageBox.setWindowTitle(tr("Notepad"));
    messageBox.setText(tr("Do you really want to quit?"));
    messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    messageBox.setDefaultButton(QMessageBox::No);
    if (messageBox.exec() == QMessageBox::Yes)
        qApp->quit();

这是我的 QtNotepad.h 代码

#include <QtWidgets/QMainWindow>
#include "ui_qtnotepad.h"
#include<qtextedit.h>
#include<qpushbutton.h>
#include<qlayout.h>
#include<qobject.h>
#include<qmessagebox.h>
#include<qwidget.h>
#include<qdialog.h>
#include<qfiledialog.h>
#include<qtextstream.h>
#include<qmenubar.h>

class QtNotepad : public QWidget

    Q_OBJECT

public:
    QtNotepad(QWidget *parent = Q_NULLPTR);

private slots:
    void quit();
    void open();
    void save();
    

private:
    Ui::QtNotepadClass ui;
    QTextEdit* textEdit;
    QPushButton* quitButton;
    QAction* openAction;
    QAction* saveAction;
    QAction* exitAction;

    QMenu* fileMenu;
    
;

这是我的主要功能代码。

#include "qtnotepad.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    QtNotepad  window;
    window.show();
    return a.exec();

这是我的 .ui 输出窗口。

【问题讨论】:

您将textEditquitButton 添加到layout,并将布局设置为小部件QtNodepad。但是你没有在任何地方添加你的menuBar,也没有给它一个父母。因此,它不会变得可见。 (如果您调用menuBar-&gt;show(),它将成为一个单独的窗口。) 我没有得到Ui::QtNotepadClass ui; 的角色。您似乎创建了硬编码的所有内容(即在 C++ 中)。那么,UI 是干什么用的? 顺便说一句。对于带有菜单栏的窗口,您可以考虑从QMainWindow 派生您的类QtNotepad。它有一个单独的函数setMenuBar()。 @Scheff'sCat 感谢您的快速回复。我使用了 layout->addWidget(menuBar)。现在菜单栏显示为小部件并垂直布局。 Ui::QtNotepadclass ui;是一个错误;我不用这个。我会删除它。您能否通过从 QMainWindow 派生类 QtNotepad 来澄清您的意思?我应该创建一个从 QMainWindow 派生的新类说“qtmenu”,它会生成“qtmenu.h”和“qtmenu.cpp”文件吗? 【参考方案1】:
QMenuBar* menuBar = new QMenuBar(nullptr);

这条线可能是问题所在。有一种方法可以解决这个问题 -

    添加 QMenuBar menuBar 作为 QtNotepad 类的成员 用parent 将构造函数中的菜单栏初始化为this,而不是nullptr

由于menuBar 是用nullptr 父级初始化的,因此窗口不会获得菜单栏的所有权。

【讨论】:

以上是关于如何使用 Qt 在同一个 UI 中添加菜单栏和按钮?的主要内容,如果未能解决你的问题,请参考以下文章

如何用Qt的designer添加菜单栏

qt3.3.8的designer里如何添加静态函数

双击ui文件之后,qt creator的菜单栏和鼠标右键选项就看不到了?

如何使 Qt 图标(在菜单栏和工具栏中)更大?

pyqt 按钮怎么添加右键菜单

Qt菜单栏和标题栏怎么合一?