How to add a menu bar and a push button in the same UI using Qt?

695 Views Asked by At

I am trying to program a interface that has a push button and a menu bar using Qt 5.15.

Problem: The main issue is even though a menu bar (menuBar) is instantiated it is not visible in the .ui output window. Also, a push button (quitButton) is instantiated it is visible in the .ui output window. I might be missing something. I am getting a feeling that in Qt either you get a menu bar or a push button widgets but not both. Is it right? Moreover, how can I get both the menu bar and push button in the same .ui window?

This is my QtNotepad.cpp code

#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();
}

This is my QtNotepad.h code

#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;
    
};

This is my main function code.

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QtNotepad  window;
    window.show();
    return a.exec();
}

This is my .ui output window.

enter image description here

1

There are 1 best solutions below

0
Arnav Deo On
QMenuBar* menuBar = new QMenuBar(nullptr);

This line may be the problem. There is one way to approach this -

  1. Add a QMenuBar menuBar as a member of the class QtNotepad
  2. Initialise the menu bar in constructor with parent as this, not nullptr

Since the menuBar is initialised with a nullptr parent, The Window will not take ownership of the menuBar.