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. Swapping QWidget child object for another object

Swapping QWidget child object for another object

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 1.2k 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.
  • S Offline
    S Offline
    shavera
    wrote on 23 May 2017, 20:45 last edited by
    #1

    While the question applies generally to QObjects, it becomes more important with QWidgets generated in Qt Designer, so I'll word it in terms of QWidgets.

    Suppose in Designer I am making a FooWidget that has a child widget that is a BarWidget. In designer, I connect up signals and slots, and in the source I may make direct function calls to ui->barWidget->doStuff().

    Suppose further that BarWidget is a base class for multiple implementations. Maybe BallWidget derives from BarWidget. I'd like to be able to do an in-place swap of barWidget to some derived widget type, so that FooWidget's connections now connect to the same signals and slots of ballWidget, FooWidget's calls to ui->barWidget->doStuff() call the ballWidget's override of doStuff().

    In other areas, I would simply pass a BarWidget pointer in the constructor for Foo and just allow that to do dependency injection. But the ui_FooWidget.h file will create its own BarWidget and connect that regardless of what subtype I may pass into Foo's constructor. So that seems a dead end.

    Is there any way to do what I'm trying? Does it help if I restrict the problem to just a problem of unit testing where the dependent class I'd like to inject is a MockBarWidget? (so I don't have to be very respectful of modularity or anything in that case).

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 23 May 2017, 21:01 last edited by
      #2

      Hi,

      What about adding a setter method that will delete the original widget and replace it with the one passed in parameter ? The setup of the signals and slots should be done once the replacement has been made.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • S Offline
        S Offline
        shavera
        wrote on 24 May 2017, 13:10 last edited by
        #3

        A setter method will work, but it rather negates the benefit of Qt Designer, don't you think? I have to go find where the widget is located in layout, remove the existing one, add the new one to the same location. I can't use the Designer signal/slot connection mechanism because I have to manually make those connections when a widget is swapped.

        For example, one thing I tried, but didn't work, is to do something like:

        BarWidget* bar = foo.findChild<BarWidget*>("barWidget");
        bar = new BallWidget(&foo);
        

        I understand why it doesn't work, and I can't say I really expected it would, but it feels like some technique to allow this kind of an in-place swap could be a useful technique.

        S 1 Reply Last reply 24 May 2017, 13:45
        0
        • S shavera
          24 May 2017, 13:10

          A setter method will work, but it rather negates the benefit of Qt Designer, don't you think? I have to go find where the widget is located in layout, remove the existing one, add the new one to the same location. I can't use the Designer signal/slot connection mechanism because I have to manually make those connections when a widget is swapped.

          For example, one thing I tried, but didn't work, is to do something like:

          BarWidget* bar = foo.findChild<BarWidget*>("barWidget");
          bar = new BallWidget(&foo);
          

          I understand why it doesn't work, and I can't say I really expected it would, but it feels like some technique to allow this kind of an in-place swap could be a useful technique.

          S Offline
          S Offline
          shavera
          wrote on 24 May 2017, 13:45 last edited by shavera
          #4

          @shavera
          Another thing that would be more complicated for end users, but could possibly be handled relatively easily from Qt's perspective would be for the uic to generate a virtual setupUi function. This way, instead of trying to replace whichever single element in FooWidget, I could write a class derived from Ui::FooWidget that overrides the setupUi function, and inject this derived class into FooWidget at its construction if needed.

          Edit: Actually, this seems to be the closest to an answer, at least as far as needing to inject mocks for unit testing is concerned. In addition to mocking whatever child class (MockBar from Bar), you can modify Foo's constructor to be

          FooWidget(QWidget* parent = nullptr, Ui::FooWidget* _ui = nullptr) 
              : QWidget{parent}
              , ui{nullptr == _ui ? new Ui::FooWidget{} : _ui}
           {}
          

          And then inject a copy of Ui::FooWidget you maintain in the test where you can directly swap ui's variables

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 24 May 2017, 20:46 last edited by
            #5

            Why would it negate it ? Whether you are using designer or not, the implications are the same: you have to set the widget in the layout and connect it in any case.

            On a side note, you should put parent as last parameter. That's the usual position and makes it coherent with the other Qt classes.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0

            1/5

            23 May 2017, 20:45

            • Login

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