Menus changed between 4.6 & 4.7?



  • I've just upgraded from 4.6.2 to 4.7 under Mac OS X 10.6.4 to find that the menus in my small app no longer appear. Is this documented in any release notes?

    The problem appears to reside in a library as I haven't rebuilt the app since updating to 4.7

    Anyone any thoughts on this?

    Thanks.



  • ... now here's a curious thing. I've just rebuilt the app from the sources under Mac OS X and Fedora 13 x86_64. Under Mac OS X the menus are still missing but under Linux they appear and the app is useable!

    I build the libraries from the Qt sources under Linux but have to take what I'm given under Mac OS X.

    Very odd.

    Smiffy



  • Hey smiffy, write a minimal example that can to show this odd behavior, so more people can text exactly what you're doing, then check if it's a regression (what would result in a "bugreport":http://bugreports.qt.nokia.com) :-)



  • OK. I've put together a 'minimal' piece of code which displays the same problem.This runs properly under Fedora 13 x86_64 and displays the cut-down menus while under Mac OS X using Xcode (qmake -spec macx-xcode) doesn't display the menus at all. How should I post the code here?

    Smiffy



  • Put your code between a pair of at-Chars (or use the button for code snippets in the toolbar of the textedit here). It then looks like this:

    @
    int main(int argc, int argv **) {
    int x = 42;
    qDebug() << x;
    return 0
    }
    @



  • Hmmm...

    It's not a single file. There's a project file, 2 .cpp, 1 .h & 1 .ui. That is as small as I could make it! I have a .tar.gz of the test.

    Smiffy



  • No way to omit the .ui?



  • I have included the ui_mainwindow.h that is produced instead, though they are roughly the same size.

    OK:

    main.cpp
    @
    // test/main.cpp

    #include <QApplication>
    #include "mainwindow.h"

    int main(int argc, char **argv)
    {
    QApplication a(argc, argv);

    MainWindow mainWindow;
    mainWindow.show();

    return a.exec();
    }
    @

    mainwindow.h
    @
    /*

    • mainwindow.h
    • test

    */

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include "ui_mainwindow.h"

    class MainWindow : public QMainWindow,
    private Ui::MainWindow
    {
    Q_OBJECT
    public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    protected:
    void setupActions();

    protected slots:
    void about();

    };

    #endif // MAINWINDOW_H
    @

    mainwindow.cpp
    @
    /*

    • mainwindow.cpp
    • test

    */

    #include <QtGui>
    #include "mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    {
    setupUi(this);
    setupActions();
    }

    MainWindow::~MainWindow(void)
    {
    }

    void MainWindow::setupActions()
    {
    connect(action_Quit, SIGNAL(triggered(bool)),
    qApp, SLOT(quit()));

    connect(action_About, SIGNAL(triggered(bool)),
    this, SLOT(about()));
    }

    void MainWindow::about()
    {
    QMessageBox::about(this, tr("About test"),
    tr("test Qt V2.1\n"));
    }
    @

    ui_mainwindow.h
    @
    /********************************************************************************
    ** Form generated from reading UI file 'mainwindow.ui'
    **
    ** Created: Mon Nov 1 09:24:34 2010
    ** by: Qt User Interface Compiler version 4.7.0
    **
    ** WARNING! All changes made in this file will be lost when recompiling UI file!
    ********************************************************************************/

    #ifndef UI_MAINWINDOW_H
    #define UI_MAINWINDOW_H

    #include <QtCore/QVariant>
    #include <QtGui/QAction>
    #include <QtGui/QApplication>
    #include <QtGui/QButtonGroup>
    #include <QtGui/QHeaderView>
    #include <QtGui/QMainWindow>
    #include <QtGui/QMenu>
    #include <QtGui/QMenuBar>
    #include <QtGui/QWidget>

    QT_BEGIN_NAMESPACE

    class Ui_MainWindow
    {
    public:
    QWidget *centralwidget;
    QAction *action_Quit;
    QAction *action_About;
    QMenuBar *menubar;
    QMenu *menu_File;
    QMenu *menuHelp;

    void setupUi(QMainWindow *test)
    {
        if (test->objectName().isEmpty())
            test->setObjectName(QString::fromUtf8("test"));
        test->resize(305, 325);
        centralwidget = new QWidget(test);
        centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
        centralwidget->setGeometry(QRect(0, 0, 305, 300));
        action_Quit = new QAction(centralwidget);
        action_Quit->setObjectName(QString::fromUtf8("action_Quit"));
        action_About = new QAction(centralwidget);
        action_About->setObjectName(QString::fromUtf8("action_About"));
        menubar = new QMenuBar(centralwidget);
        menubar->setObjectName(QString::fromUtf8("menubar"));
        menubar->setGeometry(QRect(0, 0, 305, 25));
        menu_File = new QMenu(menubar);
        menu_File->setObjectName(QString::fromUtf8("menu_File"));
        menuHelp = new QMenu(menubar);
        menuHelp->setObjectName(QString::fromUtf8("menuHelp"));
        test->setCentralWidget(centralwidget);
    
        menubar->addAction(menu_File->menuAction());
        menubar->addAction(menuHelp->menuAction());
        menu_File->addAction(action_Quit);
        menuHelp->addAction(action_About);
    
        retranslateUi(test);
    
        QMetaObject::connectSlotsByName(test);
    } // setupUi
    
    void retranslateUi(QMainWindow *test)
    {
        test->setWindowTitle(QApplication::translate("MainWindow", "test", 0, QApplication::UnicodeUTF8));
        action_Quit->setText(QApplication::translate("MainWindow", "&Quit", 0, QApplication::UnicodeUTF8));
        action_About->setText(QApplication::translate("MainWindow", "A&bout", 0, QApplication::UnicodeUTF8));
        menu_File->setTitle(QApplication::translate("MainWindow", "&File", 0, QApplication::UnicodeUTF8));
        menuHelp->setTitle(QApplication::translate("MainWindow", "Help", 0, QApplication::UnicodeUTF8));
    } // retranslateUi
    

    };

    namespace Ui {
    class MainWindow: public Ui_MainWindow {};
    } // namespace Ui

    QT_END_NAMESPACE

    #endif // UI_MAINWINDOW_H
    @

    and, probably totally redundant as I haven't included mainwindow.ui,
    test.pro
    @
    ######################################################################

    Automatically generated by qmake (2.01a) Thu Jul 10 20:10:37 2008

    ######################################################################

    TEMPLATE = app
    TARGET =
    DEPENDPATH += .
    INCLUDEPATH += .

    Input

    HEADERS += mainwindow.h
    FORMS += mainwindow.ui
    SOURCES += main.cpp mainwindow.cpp
    @



  • On Mac OS X, the about and the quit menu items are automatically moved to the application menu item. Your file and help menus are empty and it seem that Qt omits them from the application menu bar then. If you add another action to e.g. the file menu, then the menu is displayed.

    Also, be aware of the pitfalls with OS X menu bars (see "QMenuBar on Mac OS X":http://doc.qt.nokia.com/4.7/qmenubar.html#qmenubar-on-mac-os-x in the API docs). I'd advice against creating these in Qt Designer at all and rather go for manual instantiation in the class constructor.



  • Hi Volker

    The original app had several items in the File menu (plus a Run menu) and they still didn't get displayed. I can't reproduce what you assert. I also wonder why the menus didn't appear on the system-wide menu bar either?

    The manual instantiation is soooooo long-winded that I was trying to avoid that i.e. I am being lazy.

    As I originally posted - this worked fine for all the releases of Qt 4 up to but NOT including 4.7 and it also works as intended under Fedora 13 (x86_64).

    Smiffy



  • Just tested it again.

    Problem is the parent of the QMenuBar (Line 47 in ui_mainwindow.h). If you omit the parent like this:

    @menubar = new QMenuBar();@

    Then it works for me, if you leave the parent, the file menu disappears. That's why I construct the menu bar manually in my apps :-)



  • OK - after editing the ui_mainwindow.h as you suggested I now I get the menus in the system-wide menu bar as I would have expected all along in previous releases of Qt 4. But at least it now works and I can cheat by extracting the menu code and incorporating it into my start-up code :-)

    Many thanks.

    Smiffy



  • Volker,

    What is the difference between the following two code fragments? The first works under Linux & Max OS X, in the second case no menus appear under Linux.

    @
    fileMenu = menuBar()->addMenu(tr("File"));
    @

    @
    menubar = new QMenuBar(0); // or QMenuBar()
    fileMenu = menubar->addMenu(tr("File"));
    @



  • The first one creates a menu bar with your QMainWindow as a parent.

    The menu bar with no parent (second case) should only be used on Mac OS X to provide a shared menu bar for all windows (cf. Section "QMenuBar on Mac OS X":http://doc.qt.nokia.com/4.7/qmenubar.html#qmenubar-on-mac-os-x, esp. the first note, of the "QMenuBar":http://doc.qt.nokia.com/4.7/qmenubar.html API docs).

    That's one of the rare cases where you should use an #ifdef in your code:

    @
    QMenuBar *_menuBar;
    #if defined(Q_WS_MAC)
    _menuBar = new QMenuBar(0);
    #else
    _menuBar = menuBar();
    #endif
    @



  • Wonderful. All is now clear. Many thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.