Search code examples
c++qtqt-creatorqt-designer

Displaying QActions in QWidgets


QActions are great because then can be designed and managed in one place, then displayed and interfaced with in QMenus, QToolBars, and in theory, any QWidget (every QWidget has an addAction() function, after all). In addition, they are convenient because they can be manipulated in the designer (I need to keep the bulk of my interface in the designer so that people can tweak it).

I've run into problems, however :\

What I want to do is simply display some actions (maybe with icons and text, etc) in a group. There are a couple ways I can do this.

  1. Using a QToolBar: This could be perfect because a QToolBar already has a bunch of configuration options (icons, text, both, etc). Unfortunately, I can't seem to add QToolBars to things other than the the main window (when using the designer). I can do it programmatically, but then then the toolbar must also be populated in code (no good).

  2. Using a regular QWidget: I've been trying this for a while with no success at all. Not only am I having problems adding actions to QWidgets in the designer, but even when I add them programmatically I can't get them to display (I've tried setting the contextMenuPolicy to ActionsContextMenu).

Does anyone have any suggestions as to which of these paths might lead to something flexible (useful options to tweak) but also accessible from the designer?

Thanks!


Solution

  • So, the truth of the matter is that the QToolBar class just wasn't exposed as a widget to designer. Once loaded, you have full access to it. There are 2 relatively simple solutions to your problem - depends on how often you need to do it.

    1: Hack the UI File

    1. If you create a UI file, drag a new, blank QWidget into it.
    2. Save the file out to disk
    3. Open it with a text editor and change the QWidget class to QToolBar
    4. Re-open in designer, you now have a QToolBar in your UI file to work with.

    If you only do this once in a while - this isn't a bad way to go about it.

    2: Make a QToolBar Designer Plugin

    The slightly longer way to do it (but better if you use this a lot) is to just expose the QToolBar to the Designer yourself. The only thing that is a bit annoying about this tho is that you cannot move it via drag/drop...but whatever, you can still use it and put in layouts and everything.

    I mostly deal with PyQt, so this is what the plugin would look like in PyQt - but you can read through the standard docs for how to do it in C++.

    #!/usr/bin/python
    
    ''' Auto-generated ui widget plugin '''
    
    from PyQt4.QtDesigner import QPyDesignerCustomWidgetPlugin
    from PyQt4.QtGui import QIcon
    from PyQt4.QtGui import QToolBar as WidgetClass
    
    class QToolBarPlugin( QPyDesignerCustomWidgetPlugin ):
        def __init__( self, parent = None ):
            super(QToolBarPlugin, self).__init__( parent )
    
            self.initialized = False
    
        def initialize( self, core ):
            if ( self.initialized ):
                return
    
            self.initialized = True
    
        def isInitialized( self ):
            return self.initialized
    
        def createWidget( self, parent ):
            return WidgetClass(parent)
    
        def name( self ):
            if ( hasattr( WidgetClass, '__designer_name__' ) ):
                return WidgetClass.__designer_name__
            return WidgetClass.__name__
    
        def group( self ):
            if ( hasattr( WidgetClass, '__designer_group__' ) ):
                return WidgetClass.__designer_group__
            return 'ProjexUI'
    
        def icon( self ):
            if ( hasattr( WidgetClass, '__designer_icon__' ) ):
                return QIcon(WidgetClass.__designer_icon__)
            return QIcon()
    
        def toolTip( self ):
            if ( hasattr( WidgetClass, '__designer_tooltip__' ) ):
                return WidgetClass.__designer_tooltip__
            elif ( hasattr( WidgetClass, '__doc__' ) ):
                return str(WidgetClass.__doc__)
            return ''
    
        def whatsThis( self ):
            return ''
    
        def isContainer( self ):
            if ( hasattr( WidgetClass, '__designer_container__' ) ):
                return WidgetClass.__designer_container__
            return False
    
        def includeFile( self ):
            return 'PyQt4.QtGui'
    
        def domXml( self ):
            if ( hasattr( WidgetClass, '__designer_xml__' ) ):
                return WidgetClass.__designer_xml__
    
            return '<widget class="QToolBar" name="toolbar"/>'