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. How to disable the entire widget except for a specific widget in a multi-layered nested widget?
QtWS25 Last Chance

How to disable the entire widget except for a specific widget in a multi-layered nested widget?

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 593 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.
  • J Offline
    J Offline
    John Van
    wrote on last edited by
    #1

    If the parent widget is disabled, all child widgets will become disabled.

    Axel SpoerlA Pl45m4P 2 Replies Last reply
    0
    • J John Van

      @Axel-Spoerl After setParent (nulliptr), the position of the widget will change, which is not what I expected.

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #6

      @John-Van said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

      After setParent (nulliptr), the position of the widget will change, which is not what I expected.

      If you don't want/like the solutions and suggestions we provided, the final answer to your question:

      How to disable the entire widget except for a specific widget in a multi-layered nested widget ?

      is short and simple:

      You cannot.

      @JonB said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

      More work but (presumably) doable.

      Easy ;-)

      QString activeWidget = "button_not2disable"; // objectname
      
      for (auto &w : findChildren<QWidget *>(QRegularExpression(QString("^(?!%1)\\w+").arg(activeWidget)), Qt::FindChildrenRecursively) )
            w->setDisabled(true);
      

      Edit:
      Fixed RegEx
      Solution only valid if your widgets are direct children of current class... else it disables one parent, which also disables your target widget...

      Edit_2:

      Fixed recursion :))
      Now also works when target is some layers deep in the QObject tree behind other widgets, which have to stay enabled

          // ###########################################################
          /// Disable everything recursively, except target widget
          QString targetWidgetName = "button_42"; // objectname of widget that should be active
      
          for (auto &w : findChildren<QWidget *>(QRegularExpression(QString("^(?!%1)\\w+").arg(targetWidgetName)), Qt::FindChildOption::FindChildrenRecursively) ) {
              qDebug() << w->objectName() << "disabled";
              w->setDisabled(true);
          }
      
          // ############################################################
          /// enable everything needed by moving upwards the parent-child hierarchy starting from target
          auto target = findChild<QWidget * >(targetWidgetName);
          while (target->parentWidget() != nullptr) {
      
              target = target->parentWidget();
              qDebug() << target->objectName() << "enabled";
              target->setDisabled(false);
          }
      

      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      J 1 Reply Last reply
      1
      • J John Van

        If the parent widget is disabled, all child widgets will become disabled.

        Axel SpoerlA Offline
        Axel SpoerlA Offline
        Axel Spoerl
        Moderators
        wrote on last edited by
        #2

        @John-Van said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

        If the parent widget is disabled, all child widgets will become disabled.

        That's expected and can't be changed.
        You need one top level (=parentless) widget, to display a window.
        If you disable the top level widget, and display one of its children, call setParent(nullptr), then enable and show it. It will become a top level widget of its own. If you want to restore the previous order, you need to set its old parent and also embed into its previous layout if it was part of one.

        Software Engineer
        The Qt Company, Oslo

        J 1 Reply Last reply
        2
        • J John Van

          If the parent widget is disabled, all child widgets will become disabled.

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote on last edited by Pl45m4
          #3

          @John-Van

          What @Axel-Spoerl described above sounds a little like my solution for this topic here. In addition you can disable the parent, while the child is shown as standalone widget.

          Another solution:
          Don't disable the whole parent widget. Disable only parts of it.
          You can disable a QGroupBox for example, which then does not disable other widgets in the same window that are not part of your groupbox.


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          1 Reply Last reply
          3
          • Axel SpoerlA Axel Spoerl

            @John-Van said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

            If the parent widget is disabled, all child widgets will become disabled.

            That's expected and can't be changed.
            You need one top level (=parentless) widget, to display a window.
            If you disable the top level widget, and display one of its children, call setParent(nullptr), then enable and show it. It will become a top level widget of its own. If you want to restore the previous order, you need to set its old parent and also embed into its previous layout if it was part of one.

            J Offline
            J Offline
            John Van
            wrote on last edited by
            #4

            @Axel-Spoerl After setParent (nulliptr), the position of the widget will change, which is not what I expected.

            JonBJ Pl45m4P 2 Replies Last reply
            0
            • J John Van

              @Axel-Spoerl After setParent (nulliptr), the position of the widget will change, which is not what I expected.

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by
              #5

              @John-Van
              Then what did you expect? If a widget has a parent it is positioned with respect to its parent. If it has no parent it is not positioned with respect to the parent it used to have but no longer has, it is now a "top level" widget. If you want it positioned relative to some other widget (e.g. its old parent) you would have to move it appropriately yourself.

              You can't disable the parent of a non-disabled child/descendant, since disabling a parent by definition disables its descendants. As @Pl45m4 says, it sounds like what you might really mean is to disable all other children of a parent keeping only one child enabled. More work but (presumably) doable.

              1 Reply Last reply
              2
              • J John Van

                @Axel-Spoerl After setParent (nulliptr), the position of the widget will change, which is not what I expected.

                Pl45m4P Offline
                Pl45m4P Offline
                Pl45m4
                wrote on last edited by Pl45m4
                #6

                @John-Van said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

                After setParent (nulliptr), the position of the widget will change, which is not what I expected.

                If you don't want/like the solutions and suggestions we provided, the final answer to your question:

                How to disable the entire widget except for a specific widget in a multi-layered nested widget ?

                is short and simple:

                You cannot.

                @JonB said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

                More work but (presumably) doable.

                Easy ;-)

                QString activeWidget = "button_not2disable"; // objectname
                
                for (auto &w : findChildren<QWidget *>(QRegularExpression(QString("^(?!%1)\\w+").arg(activeWidget)), Qt::FindChildrenRecursively) )
                      w->setDisabled(true);
                

                Edit:
                Fixed RegEx
                Solution only valid if your widgets are direct children of current class... else it disables one parent, which also disables your target widget...

                Edit_2:

                Fixed recursion :))
                Now also works when target is some layers deep in the QObject tree behind other widgets, which have to stay enabled

                    // ###########################################################
                    /// Disable everything recursively, except target widget
                    QString targetWidgetName = "button_42"; // objectname of widget that should be active
                
                    for (auto &w : findChildren<QWidget *>(QRegularExpression(QString("^(?!%1)\\w+").arg(targetWidgetName)), Qt::FindChildOption::FindChildrenRecursively) ) {
                        qDebug() << w->objectName() << "disabled";
                        w->setDisabled(true);
                    }
                
                    // ############################################################
                    /// enable everything needed by moving upwards the parent-child hierarchy starting from target
                    auto target = findChild<QWidget * >(targetWidgetName);
                    while (target->parentWidget() != nullptr) {
                
                        target = target->parentWidget();
                        qDebug() << target->objectName() << "enabled";
                        target->setDisabled(false);
                    }
                

                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                J 1 Reply Last reply
                1
                • Pl45m4P Pl45m4

                  @John-Van said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

                  After setParent (nulliptr), the position of the widget will change, which is not what I expected.

                  If you don't want/like the solutions and suggestions we provided, the final answer to your question:

                  How to disable the entire widget except for a specific widget in a multi-layered nested widget ?

                  is short and simple:

                  You cannot.

                  @JonB said in How to disable the entire widget except for a specific widget in a multi-layered nested widget?:

                  More work but (presumably) doable.

                  Easy ;-)

                  QString activeWidget = "button_not2disable"; // objectname
                  
                  for (auto &w : findChildren<QWidget *>(QRegularExpression(QString("^(?!%1)\\w+").arg(activeWidget)), Qt::FindChildrenRecursively) )
                        w->setDisabled(true);
                  

                  Edit:
                  Fixed RegEx
                  Solution only valid if your widgets are direct children of current class... else it disables one parent, which also disables your target widget...

                  Edit_2:

                  Fixed recursion :))
                  Now also works when target is some layers deep in the QObject tree behind other widgets, which have to stay enabled

                      // ###########################################################
                      /// Disable everything recursively, except target widget
                      QString targetWidgetName = "button_42"; // objectname of widget that should be active
                  
                      for (auto &w : findChildren<QWidget *>(QRegularExpression(QString("^(?!%1)\\w+").arg(targetWidgetName)), Qt::FindChildOption::FindChildrenRecursively) ) {
                          qDebug() << w->objectName() << "disabled";
                          w->setDisabled(true);
                      }
                  
                      // ############################################################
                      /// enable everything needed by moving upwards the parent-child hierarchy starting from target
                      auto target = findChild<QWidget * >(targetWidgetName);
                      while (target->parentWidget() != nullptr) {
                  
                          target = target->parentWidget();
                          qDebug() << target->objectName() << "enabled";
                          target->setDisabled(false);
                      }
                  
                  J Offline
                  J Offline
                  John Van
                  wrote on last edited by
                  #7

                  @Pl45m4
                  Sad. It seems like I have to iterate through child widgets and disable it.
                  Thank you all.

                  Pl45m4P 1 Reply Last reply
                  0
                  • J John Van has marked this topic as solved on
                  • J John Van

                    @Pl45m4
                    Sad. It seems like I have to iterate through child widgets and disable it.
                    Thank you all.

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote on last edited by
                    #8

                    @John-Van

                    Check my updated post. No guarantee that the regex works, but worth a try.


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    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