How to use Qt classes defined accross multiple files?
-
I'm trying to create my first Qt desktop application. I have managed to create a
QMainWindow
widget and I am trying to add a menu bar to it. I was able to create a MainWindow with a menu bar that has one menu option. I was able to do this when all my code was in one file, and I was using theMainWindow
constructor to set up the whole GUI.I now would like to separate my GUI/widgets into separate files for maintainability.
Here are my current files:
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "filesystem.h" #include "./menu/filemenu.h" class QString; class FileMenu; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; QString main_title = ""; int width; int height; FileMenu *filemenu; void setName() { this->setWindowTitle(MainWindow::main_title); }; void resizeMainWindow(); void setUp(); // void createMenuBar(); }; #endif
mainwindow.cpp
#include <stdlib.h> #include <QtWidgets> #include "mainwindow.h" #include "ui_mainwindow.h" #include <QDesktopWidget> #include <QRect> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->setUp(); filemenu = new FileMenu(this); filemenu->createMenuBar(); } MainWindow::~MainWindow(){ delete ui; } void MainWindow::resizeMainWindow() { QRect main_screen = QDesktopWidget().availableGeometry(QDesktopWidget().primaryScreen()); MainWindow::height = main_screen.height(); MainWindow::width = main_screen.width(); this->resize(MainWindow::width, MainWindow::height); } void MainWindow::setUp() { this->setName(); this->resizeMainWindow(); }
./menu/filemenu.h
#ifndef FILEMENU_H #define FILEMENU_H #include <QMenu> #include <QAction> #include <QMenuBar> #include "../mainwindow.h" class MainWindow; class QMenu; class QMenuBar; class FileMenu: public QMainWindow { Q_OBJECT public: FileMenu(MainWindow *p); ~FileMenu(); void createMenuBar(); private: MainWindow *parent; QMenu *fileOption; QAction *newFolder; QAction *newFile; QAction *newWindow; QAction *exitWindow; void createFileActions(); private slots: void openNewFolder(); void openNewWindow(); void openNewFile(); void exitWindow(); }; #endif
./menu/filemenu.cpp
#include "filemenu.h" #include <QMainWindow> FileMenu::FileMenu(MainWindow *p): parent(p) { //this->createMenuBar(); this->createFileActions(); } void FileMenu::createMenuBar() { fileOption = menuBar()->addMenu(tr("&File")); fileOption->addAction(newWindow); fileOption->addAction(newFolder); fileOption->addAction(newFile); } void FileMenu::createFileActions() { newFolder = new QAction(tr("&New Folder"), this); newFolder->setShortcut(tr("Ctrl+Shift+N")); newFolder->setStatusTip(tr("Create a new folder")); connect(newFolder, &QAction::triggered, this, &FileMenu::openNewFolder); newWindow = new QAction(tr("&New Window"), this); newWindow->setShortcut(tr("Ctrl+N")); newWindow->setStatusTip("Open a new MTX window"); connect(newWindow,&QAction::triggered, this, &FileMenu::openNewWindow); newFile = new QAction(tr("&New File"), this); newFile->setShortcut(tr("Shift+N")); newFile->setStatusTip("Create a new file"); connect(newFile, &QAction::triggered, this, &FileMenu::openNewFile); exitWindow = new QAction(tr("&Exit"), this); exitWindow->setShortcut(tr("Shift+C")); exitWindow->setStatusTip("Exit MTX"); connect(exitWindow, &QAction::triggered, this, &FileMenu::openNewFile); } void FileMenu::exitWindow() { exit(EXIT_SUCCESS); } FileMenu::~FileMenu() { delete newFolder; delete newFile; delete newWindow; delete exitWindow; }
However, when I make and run the project when it's structured as above, the main window loads with no menu. What am I doing wrong?
Thanks for the help.
-
Hi and welcome to devnet,
Because you're not looking at the main window you expect. You did not really separate things here actually, you created a separate QMainWindow based class that you put in the main QMainWindow based class but you don't show it.
-
@SGaist Can you expound on this statement? I'm not sure I understand it exactly as you've phrased it.
You did not really separate things here actually, you created a separate QMainWindow based class that you put in the main QMainWindow based class but you don't show it.
Thanks.
-
@MakingTheEight
Hi
In the old Mainwindow, you doMainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
this->setUp();
filemenu = new FileMenu(this); // new main window
filemenu->createMenuBar();
}But you do not see FileMenu, but the MainWindow ( i assume). Please try filemenu = new FileMenu(); // new main window dont give parent filemenu->createMenuBar(); filemenu->show();
You should see you actually have 2 MainWindows :)
I assume you want to use FileMenu as the new MainWindow ?
int main(int argc, char *argv[]) { QApplication a(argc, argv); a.setStyleSheet( yourstylesheet ); MainWindow w; // use FileMenu here instead w.show(); return a.exec(); }
-
class MainWindow : public QMainWindow { ... class FileMenu: public QMainWindow {
Do you realise that you create TWO QMainWindows?
Why is FileMenu derived from QMainWindow? -
@jsulm I have tried to have
FileMenu
inherit fromQMenu
but I get the following error.
error: ‘menuBar’ was not declared in this scope
.My idea was to have
FileMenu
inheritQMenu
fromQMainWindow
. How would you suggest I solve my problem.Thanks for the hel
-
Remove the use of
menuBar
from it and pass theFileMenu
instance to yourMainWindow
status bar.