How to disable the context menu of a QDockWidget title bar - qt

I have a couple of QDockWidgets that are all not closabale (using Qt 5.6). Therefore, the context menu that is displayed when right-clicking a title bar of one of them only has disabled entries, and I would like to disable the whole context menu.
I tried to set the contextMenuPolicy to NoContextMenu without success.
I then tried to use a subclass of QDockWidget, override the ContextMenuEvent and ignore it. The menu is still displayed.
I then tried to install an event filter to catch the ContextMenuEvent, but it did not catch any, just PaintEvents, ResizeEvents etc.
I'm out of ideas … any help would be greatly appreciated!

As per the comments it is necessary to set the context menu policy on the QDockWidget to Qt::PreventContextMenu...
dock_widget->setContextMenuPolicy(Qt::PreventContextMenu);
rather than simply Qt::NoContextMenu. From the documentation Qt::NoContextMenu simply defers the context menu handling to the parent widget rather than preventing it entirely.

Related

Is there a way of disabling a WKInterfaceMenu?

I have a WKInterfaceMenu added to the storyboard which is working great. However, once used, I don't want the menu to appear for a second time.
Is there a way of preventing the menu from appearing?
You can definitely do this, but you need to do things a bit differently.
First off, don't set up the context menu in the storyboard. Instead, set up all the menu items programmatically. You can add and remove menu items using the addMenuItemWithImageNamed and clearAllMenuItems methods on your WKInterfaceController instance.
You want to set up all your menu items initially, then remove them in all your callback methods for each menu item. That way, they'll be there at first, and will be removed once you select one of them.

How to update a QLayout and get the new dimensions before returning?

This is driving me nuts. I have a custom menu class that, when set visible, shows a list of items located in a particular folder. When a hardware button is pressed, my application gets the latest list of items, populates the menu with them, and returns.
The menu displaying these items uses a QListWidget filled with custom widgets. Each of the widgets contains one or more QLabels in a horizontal layout, and is created at the time the menu is shown. In order to adjust the text displayed based on the menu width available, I need to get the size of the QLabel AFTER it has been resized according to the layout, but before the menu becomes visible to the user. The problem is, my layout does not get updated until all of the functions constructing my list return.
I have tried QApplication::ProcessEvents() and the layout update functions, but none of them have updated the values of my QLabels before returning. I can set a QTimer when the button is initially pressed, and have it show the menu, update the items, and stop itself, but that seems like a terrible solution.
Any help would really be appreciated! I've spent most of a day on this.
Marlon
I had this exact problem and could not find an answer anywhere on the Internet. Calling Layout.update(), Layout.activate(), or widget.adjustSize() (all suggested in various places) all did not work.
I had a widget with a vertical layout that I wanted to add a QLabel to and then immediately use the size of the QLabel.
The only thing that worked reliably was
layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();
It would seem that layouts will just not recalculate until you either return from a function and allow the Qt event loop to progress or manually call show() yourself.
How to update a QLayout and get the new dimensions before returning?
Don't. You're not meant to do that. It'll drive you "nuts" because you're doing it backwards. Layout updates are handled asynchronously from the event loop. Instead of getting layout dimensions right away, set yourself up to be part of the system. Some options are:
Implement a custom widget that will interact properly with the layout, growing to fill the available width of the layout. Perhaps all you need is a size policy and a way to elide text?
Make a custom layout that takes the special properties of your use case into account.
You want to call QWidget::adjustSize() on your parent widget. This will force the layout recalculations.
Have you tried using layout()->update(); ?
I've tried many but nothing works for me on Qt 5.15.
Only invented little patch - create timer and get size after 20 msec:
QTimer::singleShot(20, this, [this]
{
const auto height = myLayout->contentsRect().height();
// ...
});

QSystemTray problems

I am trying to use QSystemTrayIcon for my application and i am facing some problems.
It is the first time i use qt so i am not really used to it.
I followed this tutorial to make a system tray icon but i fail to customize it.
I want to have a button show/hide and not 3 show, hide, restore. These actions are really confusing for a newbie and i dont know what to do and what to connect.
I tried some things but with no luck.
Also when the system tray menu appears if you click somewhere else, the menu stays open.
Any way to solve this thing too?
If you want to remove one of the menu items, modify the createTrayIcon function so that it only adds the actions you need (and clean up the unused members once you get it to work). It's that simple.
If you want a single menu item or button to toggle between visible and hidden, you'll need to create a custom slot that calls show() or hide() (or setVisible(bool)) depending on whether the widget is hidden or not (use isVisible() for that for example). Then connect your action to that slot.
Read the Signals and Slots documentation and examples for information about how to create a new slot.

Qt Mac multiple menubars/modifiable menubar

I have an application that shows multiple subpanels & the client wants to show different menus for each subpanel.
Mac apps can only have one menuBar per system window, apparently, and it's minimally modifiable (if at all.) I need to remove/add or enable/disable menus on the menubar.
I've thought about making each of the subpanels a system window and attaching a menubar to each, but I don't see any provision for switching to a window's menubar. Besides, I suspect that doing so would create a state/positioning mess for the subpanels.
What I've Found
I've found that if I create the actions as children of the main window, I can add and remove them at will from the menus themselves. So, I can modify the menu contents, but I can't modify the menubar contents.
I've found I can also change the title of the menu to anything at any time. So, if I clear the contents and set the title to an empty string, it has the apparent effect of removing the menu (although it's still there and still highlights).
Barring another solution, have to do that, for now.
Is this possible at all on Mac? If I went down into Cocoa (don't know Cocoa), would I be able to maybe set up multiple menubars, or at least modify the menubar when the subpanel changes?
I was searching something else but as precisely I've just been working this one, what I do is
- delete the current menuBar if there's one
- menuBar=new QMenuBar(0);
- menuBar->setNativeMenuBar(true);
And it seems to work fine. Just for what it's worth.
A Cocoa application has only one menubar active at any given time, and you can modify and replace it. For instance, the (Cocoa) code below adds a new menu (with three items) to the menubar. It is also possible to edit and remove menus as well as menu items.
NSMenu *menubar = [NSApp mainMenu];
NSMenuItem *newBarMenuItem = [[[NSMenuItem alloc] initWithTitle:#"" action:NULL keyEquivalent:#""] autorelease];
NSMenu *newMenu = [[[NSMenu alloc] initWithTitle:#"New Menu"] autorelease];
NSMenuItem *menuItem1 = [[[NSMenuItem alloc] initWithTitle:#"Action 1" action:#selector(action1:) keyEquivalent:#""] autorelease];
NSMenuItem *menuItem2 = [[[NSMenuItem alloc] initWithTitle:#"Action 2" action:#selector(action2:) keyEquivalent:#""] autorelease];
[newMenu addItem:menuItem1];
[newMenu addItem:[NSMenuItem separatorItem]];
[newMenu addItem:menuItem2];
[menubar addItem:newBarMenuItem];
[menubar setSubmenu:newMenu forItem:newBarMenuItem];
[NSApp mainMenu] returns the application menu. A new menu item is added to the main menu/menubar, representing a submenu that contains three items, one of them being a separator.
It is also possible to replace the menubar by crafting an appropriate menu and sending [NSApp setMainMenu:menubarReplacement].
Yes, this is possible in a Qt app, and fairly common. :)
In your app you probably have code to build your menus, and install them into the menubar (using QMenuBar) in the first place. As Juan correctly points out, to alter the menu bar, you can delete that instance and regenerate a new menubar and its menus as needed.
In my own code, I just keep my original QMenuBar around, and call QMenuBar::clear() on the instance. This is an alternative to the delete/re-instantiate that Juan recommends, although either approach is likely valid. Then I repopulate the menubar with the currently needed menus.
I typically only rebuild the whole QMenuBar when the set of top-level menus, or the title of a top-level menu needs to change. More commonly, I am dynamically regenerating the actual menu items (QActions) and/or their state (like their text, whether they are enabled or not, checked or not, etc) within a given menu.
To dynamically regenerate a single menu's contents only, you can connect a method callback to that particular QMenu's aboutToShow signal, and rebuild the menu's items dynamically within that callback (don't forget to start with QMenu::clear() on the instance or you may end up with duplicate items in the menu!). When the QMenu pops up, it will show your dynamically rebuilt items/states. This method also works for dynamic regeneration of popup/context menus.

How to add custom component in context menu of datagrid

How to add custom component in context menu of datagrid.Here custom component like one text box with formatting details.
You cannot put components into the context menu. You can only have menuitems that dispatch a menuclick event. Unfortunately the context menu in the flashplayer is lacking a lot of functionality like that.
You might be able to highjack the context menu all together and display some sort of title window on a right click, but I am not sure if this is possible or how you would go about trying to achieve it.

Resources