QMenu modeless/async - c++

QMenu can be created by using popup() or exec(). The former creates it asynchrously while the latter blocks. But this isn't useful when you're using a QMenuBar (AFAIK).
My question is, is it possible to tell QMenuBar to only popup asynchrous/modeless QMenus? I'm not sure the terms are correct, but all I want is a Menu that won't block the rest of the application when users click on it.

The workaround you're looking for is to move your objects that can't live with such "abuse" to a separate QThread. If you have a clean interface using signals and slots, this is trivial. Just use moveToThread() and you're done. You don't need to worry about anything else.

Related

Signals and Slots in Qt4

I'm trying to create a signal and slot in Qt4 and I am fairly new to Qt. From what I understand in Qt5 it is just created automatically and this is not the case in Qt4 it seems. I'm trying to create a an action when the user clicks on an option in the menu bar at the to of the UI.= I see that there is a Signal/Slot editor at the bottom of the screen with options "Sender", "Signal", "Receiver", and "Slot". I'm not entirely sure how to use this function. Any help is appreciated.
Basically you need to connect your signal and slot
connect(ui->button1, SIGNAL(clicked()), this, SLOT(yourSlot()));
and in this link there is good example about signals and slot: signals and slots in qt.
You seem to have misunderstood.
The difference in Qt 5 is that it offers new syntax to make the connections.
The connection is "automatic" when you don't specify the connection type, i.e. direct, queued, etc, the default is automatic, which makes Qt check the object's thread ownership and select the appropriate connection type.
Connections must either be explicitly made in code, or be made using the UI editor, and while the latter may save you some typing in some cases, in general most of the connections you end up making are explicit in code, so you better learn how to do it, because the UI editor can help you only in a few corner cases. I haven't really used the UI editor for connections, and have tried it once or twice years ago, but the limitation I think is that you can only make connections between UI elements and signals and slots of the widget.
Consider that signal and slot connections are not merely a UI thing, it is a core principle in Qt and UI is just one of its many uses.

Forcing QDialog to stay open

How should I best go about forcing a QDialog to stay open when the dialog's accept() slot is called? I was thinking of reimplementing that function to get the dialog's exec to return without hiding the dialog, but was wondering if there were any better ways to accomplish this.
Rather than use a QDialog, I would accomplish the effect with a QDockWidget.
Remove the feature that allows the dock to be moved (QDockWidget::DockWidgetMovable)
Set the dock widget to floating (setFloating(true))
Connect items on the dock widget to the appropriate signals and slots on the main window
References
Dock Widgets Example
QDockWidget Documentation
You need to make your QDialog modeless, by calling show instead of exec, and using a custom signal instead of accept, because accept closes the window. And you connect that signal to a slot in the main window with the code you had after the exec call.
And in case that wasn't already the case, you should keep a reference/pointer to your QDialog somewhere (as a member in your main window class, or a static variable within the function that opens it) to be able to avoid creating multiple instances of the dialog, and you need to make sure you only connect the signals/slots once.

Singleton or Signal and Slots?

I am trying to reimplement or modify a tab code in a gui application. They are currently using Qt signal and slots system to handle addition and removal of tabs from the tab bar (For example if a tab was being drag from one tab widget to another, the old tab widget will signal the new tab widget that a new tab is coming). I was thinking rather than using that, I could simplify things using a thread safe singleton class. Then when ever a tab is moved, the widget just call on the singleton rather than emitting a signal.
Thanks
Signals and Slots.
Without even starting why the singleton would be bad, the way the data is updated inside Qt would be messed up by the singleton approach.
Don't do that. You are working within an environment and should use the mechanism the framework provides. What about if the UI in the future will have multiple windows and maybe multiple instances?
If possible you should always try to use the way from the framework you are using. This will also help in the future for the maintenance (upgrades, new hires, etc.)
You want to use a singleton, which will accept messages and dispatch them back ? (note: if you use a garden variety object instead of a singleton, you're essentially implementing an Observer pattern).
Then you are reinventing signals and slots, which use a global state internally. Instead of putting work in reinventing some difficult piece of code, why don't you use the already existing signals and slots ?

How to use the same QAction in two QMenus with different text?

So I have an action I want to expose in multiple menus (one of the main menus, and some context menus). I'd like the menu item text to differ slightly from menu to menu (to make the mnemonic unique, and to be more or less verbose as necessary in each context).
In MFC (which I have the pleasure of migrating away from at the moment) this was easy, as each menu's items were defined separately, and could map to the same ID, which would be linked to the handler. In Qt though, the QAction encapsulates the behaviour as well as the text/icon/etc. So I don't suppose there's straightforward support for it to return a different text dependent on where it's being used.
My thought about how to handle this is, for each location, to create a "proxy" QAction, which has the text specific to that context and simply has its triggered() signal connected to the original QAction's one. But I thought I should check first about whether there's an easier way to approach this.
I don't know about MFC, but in Qt - QAction is just an interface. One QAction object can have only one text to display. But the real action QAction does, you will implement in what Qt calls SLOT. Then you can have as much interfaces(or QActions objects) pointing to the same slot - just connect all QAction objects, that you want to do the same thing, to the same slot.
Hope this helps.
Your suggested solution is the simplest, I think. You can change the text of an action dynamically, when a menu is activated, but this looks more complicated to me.

Qt -how to know whether content in child widgets has been changed?

In QMainWindow I have 2 QSplitters. In that splitters I have QTextEdit, QLineEdits, QTableWinget, Ragio buttons and so on... I want to know if somthing has been chaged after pressing File->New menu button. Is there any general method for doing this?
Somwhere I have read that it is recomended to use isWindowModified() function of QMainWindow, but seems it doesn't work.
setWindowModified() does not propagate the windowModified flag to the parents. This bug is described here: https://bugreports.qt.io/browse/QTBUG-20150. I have just tried it and indeed it did not work.
The isWindowModified() could be useful here since according to http://doc.trolltech.com/4.6/qwidget.html#windowModified-prop it propagates up to the parent.
However, I think you would need to set this yourself. For example, if you clicked the new button which leads to some text being inserted into a QTextEdit, you still need to call QTextEdit's setWindowModified() function - which will then propagate up to your QMainWindow - and you can just check QMainWindow afterwards. (However, you wouldn't know which children were modified)
Maybe you should have a look at QWidget::changeEvent.