Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Tap into QWidget::create
QtWS25 Last Chance

Tap into QWidget::create

Scheduled Pinned Locked Moved Solved General and Desktop
widgetscustom widgetnotificationsqstackedwidget
8 Posts 2 Posters 3.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • kshegunovK Offline
    kshegunovK Offline
    kshegunov
    Moderators
    wrote on last edited by
    #1

    Hello,
    I have a push button dial custom widget derived from QStackedWidget and I wish to lay it out (create the buttons) depending on the QAction instances attached to the widget. Currently I do that in a separate function that initializes the widget, but I want that to be done after the widget is created. Unfortunately, QWidget::create is not virtual so reimplementing it seems impossible, are there any workarounds? Could I use one of the change events handled in QWidget::changeEvent instead?

    Kind regards.

    Read and abide by the Qt Code of Conduct

    raven-worxR 1 Reply Last reply
    0
    • kshegunovK kshegunov

      Hello,
      I have a push button dial custom widget derived from QStackedWidget and I wish to lay it out (create the buttons) depending on the QAction instances attached to the widget. Currently I do that in a separate function that initializes the widget, but I want that to be done after the widget is created. Unfortunately, QWidget::create is not virtual so reimplementing it seems impossible, are there any workarounds? Could I use one of the change events handled in QWidget::changeEvent instead?

      Kind regards.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @kshegunov
      there is a QEvent::ActionAdded (QActionEvent) event which is fired to the widget where addAction() is called on.
      Does this help you?

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      kshegunovK 1 Reply Last reply
      1
      • raven-worxR raven-worx

        @kshegunov
        there is a QEvent::ActionAdded (QActionEvent) event which is fired to the widget where addAction() is called on.
        Does this help you?

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by kshegunov
        #3

        @raven-worx
        Hello,
        I don't see how I could use it, but maybe I shouldn't have been so laconic in my original post. I'll give the whole picture and hopefully it'll become clear what and why exactly I'm needing this. I have a push button dial but it's not "flat" as one might ordinarily expect. What I mean is that some of the buttons are actually opening another dial with another set of buttons and a return button. The tree-like behaviour is similar to what you might expect from a menu. Some actions have subactions and some subactions can have subactions and so on. This is the reason I'm actually deriving from QStackedWidget and am not initializing the dial ui in the ordinary fashion (with a form), but instead am building the pages recursively. The hierarchy of actions I simply build through QObject's parent, in the conventional manner. Everything is fine and dandy, except I have to explicitly call my method that creates the stacked pages, the layouts and the buttons based on the actions. This is what I'd wish to avoid. Obviously I couldn't do it in the constructor of my widget, since there are no actions added at that point. I was thinking to maybe intercept the show event and do a lazy init there, but was unsure if there isn't a better way. It just occurred to me while typing that your suggestion might be viable if I build the pages incrementally at each ActionAdded event, so I'll try that and if in the meantime anyone has another idea I'd appreciate it.

        Thanks for the help!
        Kind regards.

        Read and abide by the Qt Code of Conduct

        raven-worxR 1 Reply Last reply
        0
        • kshegunovK kshegunov

          @raven-worx
          Hello,
          I don't see how I could use it, but maybe I shouldn't have been so laconic in my original post. I'll give the whole picture and hopefully it'll become clear what and why exactly I'm needing this. I have a push button dial but it's not "flat" as one might ordinarily expect. What I mean is that some of the buttons are actually opening another dial with another set of buttons and a return button. The tree-like behaviour is similar to what you might expect from a menu. Some actions have subactions and some subactions can have subactions and so on. This is the reason I'm actually deriving from QStackedWidget and am not initializing the dial ui in the ordinary fashion (with a form), but instead am building the pages recursively. The hierarchy of actions I simply build through QObject's parent, in the conventional manner. Everything is fine and dandy, except I have to explicitly call my method that creates the stacked pages, the layouts and the buttons based on the actions. This is what I'd wish to avoid. Obviously I couldn't do it in the constructor of my widget, since there are no actions added at that point. I was thinking to maybe intercept the show event and do a lazy init there, but was unsure if there isn't a better way. It just occurred to me while typing that your suggestion might be viable if I build the pages incrementally at each ActionAdded event, so I'll try that and if in the meantime anyone has another idea I'd appreciate it.

          Thanks for the help!
          Kind regards.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by raven-worx
          #4

          @kshegunov
          analog there is also a QEvent::ChildAdded event (QChildEvent) which is triggered when a QObject parent/child relation is created.

          Something like this?

          void childEvent(QChildEvent * event)
          {
                BaseClass::childEvent( event );
          
                if( event->added() )
                {
                         if( MyObj* obj = qobject_cast<MyObj*>( event->child() ) )
                         {
                                  // add page
                         }
                }
          }
          

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          kshegunovK raven-worxR 3 Replies Last reply
          1
          • raven-worxR raven-worx

            @kshegunov
            analog there is also a QEvent::ChildAdded event (QChildEvent) which is triggered when a QObject parent/child relation is created.

            Something like this?

            void childEvent(QChildEvent * event)
            {
                  BaseClass::childEvent( event );
            
                  if( event->added() )
                  {
                           if( MyObj* obj = qobject_cast<MyObj*>( event->child() ) )
                           {
                                    // add page
                           }
                  }
            }
            
            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @raven-worx
            Hm, this also could possibly be useful to monitor the QAction instances for changes in the hierarchy, but for this I'll have to install an event filter on each of them, which I'm reluctant to do. Still, I might go with it in the end. Thanks!

            Kind regards.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • raven-worxR raven-worx

              @kshegunov
              analog there is also a QEvent::ChildAdded event (QChildEvent) which is triggered when a QObject parent/child relation is created.

              Something like this?

              void childEvent(QChildEvent * event)
              {
                    BaseClass::childEvent( event );
              
                    if( event->added() )
                    {
                             if( MyObj* obj = qobject_cast<MyObj*>( event->child() ) )
                             {
                                      // add page
                             }
                    }
              }
              
              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by kshegunov
              #6

              @raven-worx
              Hello,
              The QEvent::ActionAdded worked wondrously, however your second suggestion with QEvent::ChildAdded is a bit more involved. I have put an event filter to each of my attached actions to capture the ChildAdded/ChildRemoved events but the handling of these events should be scheduled through the event loop, because at the point where QWidget::childEvent is invoked the object returned by event->child() is not completely constructed! I'm writing this only to let you know that this line MyObj* obj = qobject_cast<MyObj*>( event->child() ) will not work and for further reference to anyone reading this thread. Still, I thank you for the input, it helped me quite a lot!

              Kind regards.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • raven-worxR raven-worx

                @kshegunov
                analog there is also a QEvent::ChildAdded event (QChildEvent) which is triggered when a QObject parent/child relation is created.

                Something like this?

                void childEvent(QChildEvent * event)
                {
                      BaseClass::childEvent( event );
                
                      if( event->added() )
                      {
                               if( MyObj* obj = qobject_cast<MyObj*>( event->child() ) )
                               {
                                        // add page
                               }
                      }
                }
                
                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by raven-worx
                #7

                @kshegunov
                a workaround for this would be not to continue processing with the child pointer immediately , but access it delayed:

                void childEvent(QChildEvent * event)
                {
                      BaseClass::childEvent( event );
                
                      if( event->added() )
                      {
                               QMetaObject::invokeMethod( this, "childAdded", Qt::QueuedConnection,  Q_ARG(QObject*,event->child() );
                      }
                } 
                
                // this method must be a SLOT or have the Q_INVOKABLE macro set
                void childAdded( QObject* child )
                {
                      MyObj* obj = qobject_cast<MyObj*>( chidl );  // fully constructed by now
                }
                

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                kshegunovK 1 Reply Last reply
                0
                • raven-worxR raven-worx

                  @kshegunov
                  a workaround for this would be not to continue processing with the child pointer immediately , but access it delayed:

                  void childEvent(QChildEvent * event)
                  {
                        BaseClass::childEvent( event );
                  
                        if( event->added() )
                        {
                                 QMetaObject::invokeMethod( this, "childAdded", Qt::QueuedConnection,  Q_ARG(QObject*,event->child() );
                        }
                  } 
                  
                  // this method must be a SLOT or have the Q_INVOKABLE macro set
                  void childAdded( QObject* child )
                  {
                        MyObj* obj = qobject_cast<MyObj*>( chidl );  // fully constructed by now
                  }
                  
                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #8

                  @raven-worx
                  Hello,
                  Thanks for the code, but I know how to do the scheduling. I actually went with QPointer<QObject> since the QObject might be deleted while waiting in the event loop. Like this:

                  bool AgDial::eventFilter(QObject * object, QEvent * event)
                  {
                  	switch (event->type())
                  	{
                  	case QEvent::ChildAdded:
                  		QMetaObject::invokeMethod(this, "scheduleChildAdd", Qt::QueuedConnection, Q_ARG(QPointer<QObject>, QPointer<QObject>(reinterpret_cast<QChildEvent *>(event)->child())));
                  		break;
                  	case QEvent::ChildRemoved:
                  		d()->detachAction(reinterpret_cast<QChildEvent *>(event)->child());
                  		break;
                  	}
                  
                  	return QStackedWidget::eventFilter(object, event);
                  }
                  

                  Thanks for taking the time though!

                  Kind regards.

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved