Search code examples
c++qtuser-interfaceqt5qt-designer

How to use an object not declared in the UI file as signal receiver with QUiLoader?


I want to use multiple UI files for different components of my main window as well as the main window itself (because I for example want an extra UI file for the menubar and the toolbar, because both might get quite big), but make <connections> between signals of the widgets in the UI files and slots of the mainwindow. I have right now:

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
    <class>mainwindow</class>
    <widget class="FGaugeMainWindow" name="MainWindow">
        <property name="title">
            <string>FGauge</string>
        </property>
        <widget class="QWidget" name="MainWidget">
        </widget>
        <widget class="QStatusBar" name="StatusBar">
        </widget>
    </widget>
</ui>

menubar.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
    <class>menubar</class>
    <widget class="FGaugeMenuBar" name="MenuBar">
        <widget class="QMenu" name="MenuFile">
            <property name="title">
                <string>File</string>
            </property>
            <addaction name="ActionFileOpen"/>
        </widget>
        <action name="ActionFileOpen">
            <property name="text">
                <string>Open …</string>
            </property>
        </action>
        <addaction name="MenuFile"/>
    </widget>
    <connections>
        <connection>
            <sender>ActionFileOpen</sender>
            <signal>triggered()</signal>
            <receiver>MainWindow</receiver>
            <slot>loadProject()</slot>
        </connection>
    </connections>
</ui>

The menubar.ui is loaded by a custom subclass of QUiLoader (for the custom FGaugeMainWindow and FGaugeMenuBar subclasses) then set as menubar for the main window with setMenuBar(). But the connections of course don't work since when QUiLoader loads menubar.ui containing the connections, it doesn't know anything about the main window defined in mainwindow.ui and its slots.

How can this be done, if at all ? Of course I could just move the menu bar UI into the mainwindow UI file, but as I add more menus and menu items and widgets, the file would get quite big ... which I would want to avoid if somehow possible.

I'm using Qt 5.15.3 with C++.


Solution

  • Since it is not possible (I deduce that from looking at the source code) to reference a signal of a widget not defined in the UI file the connection is defined in (without ducplicating QUiLoader in its entirety), I decided to use a custom format for the menubar - will be less verbose anyways.