Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Indirect QMainWindow subclasses and .ui files
Forum Updated to NodeBB v4.3 + New Features

Indirect QMainWindow subclasses and .ui files

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 2.2k Views 1 Watching
  • 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 Offline
    M Offline
    MarcF
    wrote on last edited by MarcF
    #1

    I am using Qt Creator 5.4. I am creating an application which uses several different QMainWindow subclasses. Because the subclasses share some core functionality, I would like to derive from QMainWindow, put the core functionality in that subclass, and then derive the various actual main windows from that subclass. So, for the sake of illustration, let's say:

    class BaseWindow : public QMainWindow;
    class MainWindow : public BaseWindow // 1st sub-subclass
    class AltWindow : public BaseWindow // 2nd sub-subclass

    Additionally, because there is substantial similarity between the MainWindow and AltWindow UIs, I would like to be able to copy, say, the MainWindow .ui file and import it into AltWindow, and then make some changes to the latter via Qt Designer.

    The solution I have tried results in a proper display of widgets in MainWindow and AltWindow classes, but the signals/slots are not working. Here is what I tried.

    The initial problem is that Add new... | Qt | Qt Designer Form | Choose a form template will only let me choose a template based on QMainWindow, rather than my BaseWindow class above. So, to get around this, I created BaseWindow using the Designer Form Class template. Then, I went into the project file directory, copied BaseWindow.ui and renamed the copy "MainWindow.ui". I added that file to the project using "Add Existing Files..." I added a button widget to the .ui file using the Qt Designer. In Designer, I connected the PushButton::clicked() signal to a corresponding slot in MainWindow.\

    I also figured it was necessary to open the MainWindow.ui file using the plain text editor, to change "BaseWindow" to "MainWindow" in the following xml snippet:

    <class>MainWindow</class>
     <widget class="MainWindow" name="MainWindow">
    

    I then created a MainWindow class, derived from BaseWindow, as a c++ class rather than a Qt Designer Form template. I manually added the code necessary to create the UI object (I am using the "single inheritance" approach described in the Qt documentation), called ui->setup(this), etc. The relevant code:

    #include "MainWindow.h"
    #include "ui_MainWindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        BaseWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    // Etc.
    

    I also added the necessary code to mainWindow.h:

    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public BaseWindow
    {
    . . .
    
    private slots:
        void on_mainBtn_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    

    As I noted,MainWindow displays properly, but the QPushButton::clicked() signal does not work. Notably, the "connections" tag in MainWindow.ui is empty (I assume that's where they go when sig/slots are created through Qt Designer?) I also tried manually adding a sig/slot connection in the MainWindow constructor:

    QObject::connect( ui->mainBtn, SIGNAL(clicked()), this, SLOT(on_mainBtn_clicked() ) );
    

    but Qt Creator application output pane gives the following error message:

    Debugging starts
    QObject::connect: No such slot BaseWindow::on_mainBtn_clicked() in ..\UiFiletest2\MainWindow.cpp:9
    QObject::connect:  (sender name:   'mainBtn')
    QObject::connect:  (receiver name: 'MainWindow')
    Debugging has finished
    

    Note the reference to BaseWindow rather than MainWindow, even though both the connection code and the slot code are definitely in MainWindow.

    Where am I going wrong? Is there a better way to create QMainWindow sub-subclasses that derive from a child of QMainWindow? Any suggestions would be much appreciated.

    1 Reply Last reply
    0
    • kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      Hello,
      It's pretty unusual to have multiple main windows, but should be possible in principle. Do you have the Q_OBJECT macro in all of your derived classes?

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      1
      • M Offline
        M Offline
        MarcF
        wrote on last edited by MarcF
        #3

        Aha! Yes, that worked. I am an idiot. Thank you!

        As to your other observation, I am creating, in effect, a real-time strategy game. The opening window is a plain widget containing a QStackedLayout. The top widget in the stack is a selection page, with several buttons that allow the user to go to the map editor, scenario editor, single player game, network game, etc. Each of these sub pages is its own MainWindow subclass.

        I had been meaning to ask whether there is a better way to accomplish this common game architecture. Can you suggest anything? My initial thought was to simply have a single MainWindow object that dynamically reconfigures its UI depending on the specific "page" (e.g., map editor, single-player game, etc.) specified by the user. But that seemed like a very complicated way to do things.

        kshegunovK 1 Reply Last reply
        0
        • M MarcF

          Aha! Yes, that worked. I am an idiot. Thank you!

          As to your other observation, I am creating, in effect, a real-time strategy game. The opening window is a plain widget containing a QStackedLayout. The top widget in the stack is a selection page, with several buttons that allow the user to go to the map editor, scenario editor, single player game, network game, etc. Each of these sub pages is its own MainWindow subclass.

          I had been meaning to ask whether there is a better way to accomplish this common game architecture. Can you suggest anything? My initial thought was to simply have a single MainWindow object that dynamically reconfigures its UI depending on the specific "page" (e.g., map editor, single-player game, etc.) specified by the user. But that seemed like a very complicated way to do things.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @MarcF

          As to your other observation, I am creating, in effect, a real-time strategy game.

          Curiously enough I'm doing the same, although I have decided to give Qt3D a try for that purpose.

          The opening window is a plain widget containing a QStackedLayout. The top widget in the stack is a selection page, with several buttons that allow the user to go to the map editor, scenario editor, single player game, network game, etc. Each of these sub pages is its own MainWindow subclass.

          I'd suggest doing that the other way around. Firstly your tools (scenario/map editor) I'd put in their separate application, not in the main one. This is usually the case for most games, as they are not essential to play the game. This has the side effect that you don't create/manage widgets for things you won't be needing, thus reducing memory and CPU requirements. Secondly, you'd make a generic widget, having the ability to add some "toolbox" widgets, as the central/main widget of your main window. I don't know whether it's a good idea to stack main windows, you might be in for some trouble with that. If you still want the stack widget, you can use it as a central widget and add your QWidget (derived) pages to it. The menu actions and the like can be connected to the appropriate slots at runtime, so I don't see much point of stacking QMainWindows.

          I hope that helps.

          Kind regards.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved