如何使用 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 输出窗口。
【问题讨论】:
您将textEdit
和quitButton
添加到layout
,并将布局设置为小部件QtNodepad
。但是你没有在任何地方添加你的menuBar
,也没有给它一个父母。因此,它不会变得可见。 (如果您调用menuBar->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 中添加菜单栏和按钮?的主要内容,如果未能解决你的问题,请参考以下文章