PDA

View Full Version : Window menu problem, C# & Qt



linuxoid
14th February 2010, 06:49
I've wasted 2 days trying to figure out why one class (UI designed in Qt Creator and then converted to C#) shows the menu and the other (written by hand, mostly copy&paste from the Qt-converted one) doesn't show the menu. Maybe a pair of fresh eyes can see what's wrong? It drives me nuts. Here are the codes:

Made in Qt Creator:


public class MainWindow : QMainWindow{

public QAction actionNew;
public QAction actionOpen;
public QAction actionSave;
public QAction actionSaveAs;
public QAction actionQuit;
public QAction actionConfigGiraffe;
public QAction actionConvert;
public QAction actionRestart;
public QAction actionAbout;

public QWidget mainWidget;
public QWidget menuWidget;
public QWidget toolWidget;
public QWidget statusWidget;
public QStackedWidget stackWidget;
public QWidget startPage;
public QWidget basicVideoPage;
public QWidget basicAudioPage;
public QWidget basicImagePage;

public QVBoxLayout mainLayout;
public QSpacerItem hSpacer;
public QSpacerItem vSpacer;
public QSize size;

public QMenuBar menuBar;
public QMenu menuFile;
public QMenu menuEdit;
public QMenu menuView;
public QMenu menuGo;
public QMenu menuTools;
public QMenu menuSettings;
public QMenu menuHelp;
public QStatusBar statusBar;
public QToolBar toolBar;

startWin.StartWindow startwin = new startWin.StartWindow();
//Ui.MainWindow win = new Ui.MainWindow();

public MainWindow() {
InitUI();
//win.SetupUi(this);
this.Show();
}

public void InitUI() {
this.WindowTitle = "Start - Cute Giraffe";
size = new QSize(500, 400);
this.Size = size;
this.Move(200,200);
hSpacer = new QSpacerItem(50, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding);
vSpacer = new QSpacerItem(20, 100, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding);
mainWidget = new QWidget(this);
//menuWidget = new QWidget(mainWidget);
//toolWidget = new QWidget(mainWidget);
//statusWidget = new QWidget(mainWidget);
stackWidget = new QStackedWidget(mainWidget);
startPage = new QWidget(stackWidget);
basicVideoPage = new QWidget(stackWidget);
basicAudioPage = new QWidget(stackWidget);
basicImagePage = new QWidget(stackWidget);

startwin.StartUI(this, startPage);

stackWidget.AddWidget(startPage);
stackWidget.AddWidget(basicVideoPage);
stackWidget.AddWidget(basicAudioPage);
stackWidget.AddWidget(basicImagePage);
stackWidget.SetCurrentIndex(0);

mainLayout = new QVBoxLayout(mainWidget);
//mainLayout.AddWidget(menuWidget);
//mainLayout.AddWidget(toolWidget);
mainLayout.AddItem(vSpacer);
mainLayout.AddWidget(stackWidget);
mainLayout.AddItem(vSpacer);
//mainLayout.AddWidget(statusWidget);
mainLayout.sizeConstraint = QLayout.SizeConstraint.SetDefaultConstraint;

mainWidget.SetLayout(mainLayout);
this.SetCentralWidget(mainWidget);

actionNew = new QAction("&New", this);
actionOpen = new QAction("&Open", this);
actionSave = new QAction("&Save", this);
actionSaveAs = new QAction("Save &As...", this);
actionQuit = new QAction("&Quit", this);
actionConfigGiraffe = new QAction("Configure &Giraffe...", this);
actionConvert = new QAction("&Convert", this);
actionRestart = new QAction("&Restart", this);
actionAbout = new QAction("&About", this);

menuBar = new QMenuBar(this);
menuBar.Geometry = new QRect(0, 0, 500, 22);
menuFile = new QMenu(menuBar);
menuEdit = new QMenu(menuBar);
menuView = new QMenu(menuBar);
menuGo = new QMenu(menuBar);
menuTools = new QMenu(menuBar);
menuSettings = new QMenu(menuBar);
menuHelp = new QMenu(menuBar);
/* menuFile.AddAction(actionNew);
menuFile.AddAction(actionOpen);
menuFile.AddAction(actionSave);
menuFile.AddAction(actionSaveAs);
menuFile.AddSeparator();
menuFile.AddAction(actionQuit);
*/ this.SetMenuBar(menuBar);

menuBar.AddAction(menuFile.MenuAction());
menuBar.AddAction(menuEdit.MenuAction());
menuBar.AddAction(menuView.MenuAction());
menuBar.AddAction(menuGo.MenuAction());
menuBar.AddAction(menuTools.MenuAction());
menuBar.AddAction(menuSettings.MenuAction());
menuBar.AddAction(menuHelp.MenuAction());
menuFile.AddAction(actionNew);
menuFile.AddAction(actionOpen);
menuFile.AddAction(actionSave);
menuFile.AddAction(actionSaveAs);
menuFile.AddSeparator();
menuFile.AddAction(actionQuit);
menuHelp.AddAction(actionAbout);

/* menuEdit = new QMenu();
menuEdit = MenuBar().AddMenu("&Edit");
menuView = new QMenu();
menuView = MenuBar().AddMenu("&View");
menuGo = new QMenu();
menuGo = MenuBar().AddMenu("&Go");
menuTools = new QMenu();
menuTools = MenuBar().AddMenu("&Tools");
menuSettings = new QMenu();
menuSettings = MenuBar().AddMenu("&Settings");
menuHelp = new QMenu();
menuHelp = MenuBar().AddMenu("&Help");
menuHelp.AddAction(actionAbout);
*/
toolBar = new QToolBar(this);
toolBar.AddAction(actionQuit);
this.AddToolBar(Qt.ToolBarArea.TopToolBarArea, toolBar);

statusBar = new QStatusBar(this);
this.SetStatusBar(statusBar);


Hand written:


public class Ui_MainWindow
{
public QAction actionQuit;
public QAction actionNew;
public QAction actionOpen;
public QAction actionSave;
public QAction actionSave_As;
public QAction actionConfigure_Giraffe;
public QAction actionConvert;
public QAction actionRestart;
public QAction actionAbout;
public QWidget centralWidget;
public QHBoxLayout hboxLayout;
public QMenuBar menuBar;
public QMenu menuEdit;
public QMenu menuView;
public QMenu menuGo;
public QMenu menuTools;
public QMenu menuSettings;
public QMenu menuHelp;
public QMenu menuFile;
public QStatusBar statusBar;
public QToolBar toolBar;

public void SetupUi(QMainWindow MainWindow)
{
if (MainWindow.ObjectName == "")
MainWindow.ObjectName = "MainWindow";
QSize Size = new QSize(500, 400);
Size = Size.ExpandedTo(MainWindow.MinimumSizeHint());
MainWindow.Size = Size;
actionQuit = new QAction(MainWindow);
actionQuit.ObjectName = "actionQuit";
actionNew = new QAction(MainWindow);
actionNew.ObjectName = "actionNew";
actionOpen = new QAction(MainWindow);
actionOpen.ObjectName = "actionOpen";
actionSave = new QAction(MainWindow);
actionSave.ObjectName = "actionSave";
actionSave_As = new QAction(MainWindow);
actionSave_As.ObjectName = "actionSave_As";
actionConfigure_Giraffe = new QAction(MainWindow);
actionConfigure_Giraffe.ObjectName = "actionConfigure_Giraffe";
actionConvert = new QAction(MainWindow);
actionConvert.ObjectName = "actionConvert";
actionRestart = new QAction(MainWindow);
actionRestart.ObjectName = "actionRestart";
actionAbout = new QAction(MainWindow);
actionAbout.ObjectName = "actionAbout";
centralWidget = new QWidget(MainWindow);
centralWidget.ObjectName = "centralWidget";
hboxLayout = new QHBoxLayout(centralWidget);
hboxLayout.Spacing = 6;
hboxLayout.Margin = 11;
hboxLayout.ObjectName = "hboxLayout";
MainWindow.SetCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar.ObjectName = "menuBar";
menuBar.Enabled = true;
menuBar.Geometry = new QRect(0, 0, 500, 22);
menuEdit = new QMenu(menuBar);
menuEdit.ObjectName = "menuEdit";
menuView = new QMenu(menuBar);
menuView.ObjectName = "menuView";
menuGo = new QMenu(menuBar);
menuGo.ObjectName = "menuGo";
menuTools = new QMenu(menuBar);
menuTools.ObjectName = "menuTools";
menuSettings = new QMenu(menuBar);
menuSettings.ObjectName = "menuSettings";
menuHelp = new QMenu(menuBar);
menuHelp.ObjectName = "menuHelp";
menuFile = new QMenu(menuBar);
menuFile.ObjectName = "menuFile";
MainWindow.SetMenuBar(menuBar);
statusBar = new QStatusBar(MainWindow);
statusBar.ObjectName = "statusBar";
MainWindow.SetStatusBar(statusBar);
toolBar = new QToolBar(MainWindow);
toolBar.ObjectName = "toolBar";
MainWindow.AddToolBar(Qt.ToolBarArea.TopToolBarAre a, toolBar);

menuBar.AddAction(menuFile.MenuAction());
menuBar.AddAction(menuEdit.MenuAction());
menuBar.AddAction(menuView.MenuAction());
menuBar.AddAction(menuGo.MenuAction());
menuBar.AddAction(menuTools.MenuAction());
menuBar.AddAction(menuSettings.MenuAction());
menuBar.AddAction(menuHelp.MenuAction());
menuHelp.AddAction(actionAbout);
menuFile.AddAction(actionNew);
menuFile.AddAction(actionOpen);
menuFile.AddAction(actionSave);
menuFile.AddAction(actionSave_As);
menuFile.AddSeparator();
menuFile.AddAction(actionQuit);
toolBar.AddAction(actionQuit);

waldyrious
28th April 2016, 21:19
This is the weirdest bug i've ever found, but after lots of testing, it seems to me that a QAction whose text starts with the string "config" simply isn't shown in a QMenuBar. I don't know what causes this or what the solution could be, but I thought I'd post here in case someone else has the same problem, especially since it's such a strange one.

d_stranz
29th April 2016, 04:02
And so you brought a 6-year-old post back from the dead that has absolutely no relationship to your "problem" (except that the word QAction appears in it) just to make this incorrect comment? Why?

I think this little bit of code demonstrates that your observation is flawed:



// ActionFoo.h
#pragma once
#include <QtWidgets/QMainWindow>

class ActionFoo : public QMainWindow
{
Q_OBJECT

public:
ActionFoo( QWidget *parent = 0 );
~ActionFoo( );

private slots:
void configSomething();
};

// ActionFoo.cpp

#include "actionfoo.h"
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QMenu>
#include <QtWidgets/QAction>
#include <QtCore/QDebug>

ActionFoo::ActionFoo(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar * pMenuBar = menuBar();
QMenu * pMenu = pMenuBar->addMenu( "File" );

QAction * pAction = new QAction( "config something", this );
pMenu->addAction( pAction );
connect( pAction, &QAction::triggered, this, &ActionFoo::configSomething );

QAction * pOtherAction = new QAction( "config other", this );
pMenuBar->addAction( pOtherAction );
connect( pOtherAction, &QAction::triggered, this, &ActionFoo::configSomething );

resize( 500, 500 );
}


ActionFoo::~ActionFoo()
{
}

void ActionFoo::configSomething()
{
qDebug() << "just configged something";
}


// main.cpp

#include "actionfoo.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ActionFoo w;
w.show();
return a.exec();
}


11912

Note that this works even if you change the strings to simply "config", "Config", "Configuration" or any other strings you care to use. So look somewhere else for the source of your bug.

waldyrious
29th April 2016, 10:10
I ended up finding what the problem was. I don't think it's the same issue as OP's, but since I came here by searching on google for my issue, I'll leave this here in case it helps the next guy.

The issue was a manifestation of Qt's "smart" menu processing in OS X (http://doc.qt.io/qt-5/osx-issues.html#menu-bar), where it detects menus with specific names and automatically assigns them to OS-specific menu items. In this case, any menu whose text starts with "config" (even something like "configfoo") automatically sets the menu entry as the application's Preferences menu -- even if you manually add it to another QMenu! I would say this overeager behavior is a bug, so I'll look for a way to report it, if it hasn't been so.

Hope you managed to solve your own issue, OP -- sorry for hijacking your thread :)

And d_stranz (I composed this reply before seeing your post), I'd ask you to be a little more careful in how you address newcomers, as such a harsh tone may discourage the engagement of those new to the community who may simply not be aware of any implicit rules they may be breaking (or just be generally misinformed, as was the case here), especially when they're commenting in good faith rather than "asking for the codez" or something. This observation is further aggravated by the fact that your additional Qt expertise did not guarantee you the knowledge required to realize that my issue was indeed legitimate, as reflected in the page I linked to in the beginning of my reply. Thanks anyway (genuinely) for taking the time to test the issue.

d_stranz
29th April 2016, 15:53
@waldyrious: My apologies. We have had a rash lately of newcomers resurrecting long-dead threads to post misinformation, and this looked like another of them. It seemed ludicrous that a menu item that happened to start with "config" would be somehow singled out for special treatment by Qt, and I felt the need to post an example to illustrate that it wasn't the case so that others would not come across it and be misled. Most of these "Qt bugs" turn out to be a problem that exists between the chair and the keyboard.

Your first reply said nothing about the behavior being specific to OS/X, it was made to a thread that talked about C# and Qt, and so really should have been posted as a new top-level thread. In any case, I agree that it should be considered a bug if there is no way to override the behavior.

Edit: Upon further investigation into the QMenuBar docs:


Qt for OS X also provides a menu bar merging feature to make QMenuBar conform more closely to accepted OS X menu bar layout. The merging functionality is based on string matching the title of a QMenu entry. These strings are translated (using QObject::tr()) in the "QMenuBar" context. If an entry is moved its slots will still fire as if it was in the original place. The table below outlines the strings looked for and where the entry is placed if matched:

You can override this behavior by using the QAction::menuRole() property.

So basically, it isn't a bug, it's a "feature".

ChrisW67
29th April 2016, 22:03
@waldyrious. It might help if you edit your forum profile to indicate that you use OS X rather than just X and Windows. This helps when you don't specify the platform in your post (that would help too)

I was surprised by the original post: it appears someone is converting generated C++ to C# in order to use it on X11/UNIX presumably in Mono... at least if their profile is to be believed.