This question already has an answer here:
How to disable automatic mnemonics in a Qt application on KDE?
(1 answer)
Closed 7 years ago.
I am creating a QPushButton as follows, with no explicit shortcut (&):
testButton = new QPushButton(tr("Start"));
I can correctly read the button's text just after its construction:
testButton.text() returns 'Start' (without single quotes)
Then I create a signal/slot connection:
QObject::connect(
testButton, &QPushButton::clicked,
this, &Dialog::actionRequest
);
In the Dialog::actionRequest slot, testButton.text() returns '&Start', as if a shortcut had been created "somewhere", under the hood.
If I name the button 'Foo', the same phenomenon occurs, but testButton.text() would return 'F&oo'. That's because I already have a "File" menu, that has an explicit shortcut -- created as:
fileMenu = new QMenu(tr("&File"), this);
and, possibly, Alt+O would be the next "available" shortcut?
I do not want this implicit shortcut creation for my QPushButton. What's the solution to this problem? I'm running Fedora 22 ( with plasma 5), with stock qt 5.5 packages.
There is a default QShortcut object associated with menu options, buttons, etc. Unfortunately there is no way to directly access and disable them after creation that I know of.
You can attempt to call the Qt global function qt_set_sequence_auto_mnemonic(false); to disable this behavior dynamically but I'm not sure if it's available on every platform.
Related
There is a change between QT4 and QT5 when handling Menubar menus access keys and QActions shortcuts that have conflicting key combinations.
In Qt4 when a MenuBar contains a menu with an ampersand like &File it can be opened by tapping on Alt and then tapping F. If a QAction is created using the same hotkey combination like Alt+F then the QAction ‘s signal will be fired if Alt and F are pushed simultaneously or alt is held down and F is pushed.
This is similar functionality to Visual Studios and other MS programs.
In Qt5.4 and Qt5.5 when a MenuBar contains a menu with an ampersand like &File it can be opened by tapping on Alt and then tapping F. If a QAction is created using the same hotkey combination like Alt+F then the QAction ‘s signal will be NOT fired. Instead nothing happens and a warning message is sent to the application output.
QAction::eventFilter: Ambiguous shortcut overload: Alt+F
This issue can be duplicated using a QTcreator example like menus and changing the setshortcut for newAct to Alt+F or another shortkey that is the same as a menubar.
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct);
void MainWindow::createActions()
{
newAct = new QAction(tr("&New"), this);
newAct->setShortcut(tr("Alt+F")); // This will work in QT4 but not in QT5 and will send a message QAction::eventFilter: Ambiguous shortcut overload: Alt+F
newAct->setStatusTip(tr("Create a new file"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
My question is what is the correct functionality for windows QT4 or Qt5. If QT5 is correct is there a way to setup Qt so it acts like QT4 instead.
TL;DR: Don't hate your users. Don't do that.
Application-global key shortcuts must be unambiguous. Qt5's behavior is correct. Qt4 failed to detect this, and would let you horribly mislead the user. When a user sees an underline keyboard shortcut for the menu or a menu item, they have every right to believe that the shortcut is application global and won't depend on the context. What you observed in Qt 4 was "allowed", but very bad from usability perspective and had no place in polished, professional applications.
To get the behavior you're after, you must make the action unambiguous: you must remove the shortcut from the menu action. That will work correctly: the menu loses the shortcut, and your application-global shortcut takes over that key sequence.
Alas, I'm very much doubtful that it is a good idea to take over a very common menu shortcut - one that is present in most Windows applications that have menus. If I was your user, I would not like you for taking over Alt-F.
I've been watching a Qt tutorial series on YouTube, in which the author shows how to call a function, when a button is pressed. He right-clicked on the button in Qt Creator IDE and chose "Go to slot", from where he chose the signal which would fire the generated function. Since I am used to develop with Netbeans, I simply tried to follow his example using the embedded Qt Designer. Unfortunately, there is no "Go to slot..." entry when I right-click on my button or any widget. I could, of course, create a new slot for my main window and then connect the button's signal to it, but doing it with a single function just seems way more convenient and clean to me. Is there a way to fix is, or if not, at least a way to do with via code entirely, without having to add a new slot to the main window for every single button that servers a different purpose? Thanks for your help.
While I don't know why the QtDesigner in Netbeans doesn't provide this feature, I know what the feature does: It just creates a slot with a special name in your widget class. Note that it does not add a connect statement. It uses the automatic connection feature, which works like this:
For each slot which name matches this pattern:
void on_X_Y(...)
it will be connected to the signal named Y of the object named X. So if you have a QPushButton named button, and you want to handle the signal pressed, simply create a slot with the following signature:
void on_button_pressed()
If you wonder how this slot gets connected to the signal: This happens in the ui_...h file at the end of setupUi():
QMetaObject::connectSlotsByName(WidgetName);
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Qt - initializing the form
I tried to look for a description for the setupUi() method but couldn't find especially in the Qt documentation.
What does this method do? For example, if I write in a class setupUi(this), what will this do? What does setting up a user interface mean at the end?
Thanks.
setupUi() creates the actual instances of widgets for you. A form that you create in QtDesigner is stored just as XML file. So to be able to build the actual "window" with all the elements that you put on it in QtDesigner and display it in your application, setupUi() is created for you automatically by UIC (UI compiler - a Qt tool) so you don't have to do that manually. All the properties that you set in QtDesigner and all elements you put there will be "translated" in C++ code like this:
QLabel *label1 = new QLabel(tr("Start"), this);
QTableView *view1 = new QTableView(this);
...
Having seen earlier existing discussion on "stackoverflow" forum about designing and managing menus and actions under an application being designed & developped under Qt Creator (see "How to connect menu click with action in Qt Creator?" : How to connect menu click with action in Qt Creator?), I'm afraid I have same questions about action buttons in a toolbar I'm trying to create & populate with Qt creator...
So, let's go !
(1) I create at least one action in the Action Editor...
(2) I drag&drop that action to the toolbar
(steps 1 & 2 are ok, no difficulties with these ones, although it is a quite unusal way of doing such things for me, because other UIM designing tools usually propose inverse steps 2 & 1 to do the same, which is more "natural" in my opinion, but, I know, many many things exist and co-exist in our world of software designing & programming...)
=> (3) How to associate (connect) the function (which I'm going to implement) that is supposed to be called when clicking the given toolbar button ?
I mean, how to connect the "triggered" signal for the given action (toolbar button) to the desired slot (function) to be implementing later... ? Is it possible to do such things with the "Signals and slots editor" inside Qt Creator, or do I have to call "connect()" by myself somewhere in the code to achieve this ? Many thanks in advance for any help/suggestion/detailed example for perfect beginner at this point...
In fact, I would to know wether it is possible not to call connect() by myself for such need and wether Qt Creator will create slot (function) prototype by itself or do we have to create such slot (function) prototypes by ourselves before Qt Creator can take the new slot (function) prototype into account and really assist/help user/developper in this usual/normal UIM design step / designing capability... ?
Best regards.
Alain-Pierre
If the QAction is a member if your window, then the normal
QMetaObject::connectSlotsByName(SettingsDialog);
...will connect an action's trigger signal with an appropriately named slot method. This is normally called automatically by GUI classes created using the designer. So if the action is named actionSomething for example, creating a slot in your GUI class with a signature like:
void on_actionSomething_triggered();
...will mean that you don't have to manually connect the signals and slots.
Also, right-clicking on the action in the action editor and selecting 'Go to slot...' will allow you to create a slot function for any signal that the action may emit.
I'm using Qt 4.7 on Windows 7 Ultimate 32 bit.
The QMainWindow of my program has a QDockWidget. I've noticed that if I minimize the main window by the minimize button on the title bar, after restoring it the dock widget is closed. I didn't write any support for a feature like this!
How does this happen and how to prevent this?
Thanks.
I encountered this error when writing my own application. I have QDockWidget with options for my application. Using Qt Creator I created menu with QAction actionMenu which was checkable. Then I connected QDockWidget and QAction like this:
QObject::connect(ui->dockWidget, SIGNAL(visibilityChanged(bool)),
ui->actionMenu, SLOT(setChecked(bool)));
QObject::connect(ui->actionMenu, SIGNAL(toggled(bool)),
ui->dockWidget, SLOT(setVisible(bool)));
The order of connection is not important. And then when I minimized application with QDockWidget being visible, after I restored it QDockWidget was closed and actionMenu was unchecked.
In fact there are two solutions. First which works for me is to use SIGNAL(triggered(bool)) instead of SIGNAL(toggled(bool)):
QObject::connect(ui->dockWidget, SIGNAL(visibilityChanged(bool)),
ui->actionMenu, SLOT(setChecked(bool)));
QObject::connect(ui->actionMenu, SIGNAL(triggered(bool)),
ui->dockWidget, SLOT(setVisible(bool)));
The second solution uses action which you can obtain from QDockWidget:
// Retrieve action from QDockWidget.
QAction *action = ui->dockWidget->toggleViewAction();
// Adjust any parameter you want.
action->setText(QString("&Menu"));
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
action->setStatusTip(QString("Press to show/hide menu widget."));
action->setChecked(true);
// Install action in the menu.
ui->menuOptions->addAction(action);
I know for sure that SIGNAL(toggled(bool)) was causing in my application closure of QDockWidget.
I faced the same problem... I managed to get rid of it by using a method called StoreWindowsLayout and RestoreWindowsLayout.
StoreWindowsLayout will save the content of the ByteArray returned by the Method QMainwindow::saveState().
RestoreWindowsLayout will restore that bytearray, and therefore your windows layout, the qdockwidget visibility state and so on...
I call StoreWindowsLayout on ApplicationMainFrm::changeEvent, on ApplicationMainFrm::closeEvent (it's likely this one you'll need) and in ApplicationMainFrm::hide().
Then I use restoreWindowsLayout in ApplicationMainFrm::showEvent.
Exemple of use of restoreWindowsLayout in my MainForm :
void ApplicationMainFrm::showEvent(QShowEvent* pEvent)
{
QMainWindow::showEvent(pEvent);
restoreWindowsLayout();
}
Hope it helps !