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

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.
  • K Offline
    K Offline
    kshegunov
    Moderators
    wrote on 27 Jan 2016, 01:47 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

    R 1 Reply Last reply 27 Jan 2016, 07:06
    0
    • K kshegunov
      27 Jan 2016, 01:47

      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.

      R Offline
      R Offline
      raven-worx
      Moderators
      wrote on 27 Jan 2016, 07:06 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

      K 1 Reply Last reply 27 Jan 2016, 10:05
      1
      • R raven-worx
        27 Jan 2016, 07:06

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

        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 27 Jan 2016, 10:05 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

        R 1 Reply Last reply 27 Jan 2016, 10:12
        0
        • K kshegunov
          27 Jan 2016, 10:05

          @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.

          R Offline
          R Offline
          raven-worx
          Moderators
          wrote on 27 Jan 2016, 10:12 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

          K R 3 Replies Last reply 27 Jan 2016, 10:25
          1
          • R raven-worx
            27 Jan 2016, 10:12

            @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
                           }
                  }
            }
            
            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 27 Jan 2016, 10:25 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
            • R raven-worx
              27 Jan 2016, 10:12

              @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
                             }
                    }
              }
              
              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 28 Jan 2016, 05:43 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
              • R raven-worx
                27 Jan 2016, 10:12

                @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
                               }
                      }
                }
                
                R Offline
                R Offline
                raven-worx
                Moderators
                wrote on 28 Jan 2016, 07:01 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

                K 1 Reply Last reply 28 Jan 2016, 07:07
                0
                • R raven-worx
                  28 Jan 2016, 07:01

                  @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
                  }
                  
                  K Offline
                  K Offline
                  kshegunov
                  Moderators
                  wrote on 28 Jan 2016, 07:07 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

                  8/8

                  28 Jan 2016, 07:07

                  • Login

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