Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    Solved How to use Qt classes defined accross multiple files?

    General and Desktop
    gui developer desktop qmenu qmainwindow
    4
    8
    1119
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      MakingTheEight last edited by

      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 the MainWindow 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.

      jsulm 1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        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.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        M 1 Reply Last reply Reply Quote 2
        • M
          MakingTheEight @SGaist last edited by

          @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.

          mrjj 1 Reply Last reply Reply Quote 0
          • mrjj
            mrjj Lifetime Qt Champion @MakingTheEight last edited by mrjj

            @MakingTheEight
            Hi
            In the old Mainwindow, you do

            MainWindow::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();
            }
            
            
            1 Reply Last reply Reply Quote 2
            • jsulm
              jsulm Lifetime Qt Champion @MakingTheEight last edited by

              @MakingTheEight

              class MainWindow : public QMainWindow {
              ...
              class FileMenu: public QMainWindow {
              

              Do you realise that you create TWO QMainWindows?
              Why is FileMenu derived from QMainWindow?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              M 1 Reply Last reply Reply Quote 1
              • M
                MakingTheEight @jsulm last edited by

                @jsulm I have tried to have FileMenu inherit from QMenu but I get the following error.
                error: ‘menuBar’ was not declared in this scope.

                My idea was to have FileMenu inherit QMenu from QMainWindow. How would you suggest I solve my problem.

                Thanks for the hel

                1 Reply Last reply Reply Quote 0
                • SGaist
                  SGaist Lifetime Qt Champion last edited by

                  Remove the use of menuBar from it and pass the FileMenu instance to your MainWindow status bar.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply Reply Quote 2
                  • M
                    MakingTheEight last edited by

                    @jsulm @mrjj @ig Thanks for all the help.
                    I was able to fix the inheritance issue by creating a new FileMenu instance in the main window.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post