Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to add checkbox to context menu?
QtWS25 Last Chance

How to add checkbox to context menu?

Scheduled Pinned Locked Moved Solved Qt for Python
13 Posts 5 Posters 3.9k 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.
  • M Offline
    M Offline
    midnightdim
    wrote on last edited by
    #1

    I'd like to tri-state checkboxes to my context menu.
    Here's how I'm trying to do it.

    I've implemented a class:

    class CheckBoxAction(QWidgetAction):
        def __init__(self, parent, text):
            super(CheckBoxAction, self).__init__(parent)
            layout = QHBoxLayout()
            self.widget = QWidget()
            label = QLabel(text)
            label.setAlignment(Qt.AlignLeft)
            layout.addWidget(QCheckBox())
            layout.addWidget(label)
            self.widget.setLayout(layout)
    
        def createWidget(self,text):
            return self.widget
    

    Then in my context menu I'm adding this widget like so:

    menu = QMenu()
    open = menu.addAction(CheckBoxAction(self,"sometext"))
    

    But instead of showing this checkbox inside of the menu it shows this widget at the top left corner of the screen.

    Please advise.

    JonBJ 1 Reply Last reply
    0
    • M midnightdim

      I'd like to tri-state checkboxes to my context menu.
      Here's how I'm trying to do it.

      I've implemented a class:

      class CheckBoxAction(QWidgetAction):
          def __init__(self, parent, text):
              super(CheckBoxAction, self).__init__(parent)
              layout = QHBoxLayout()
              self.widget = QWidget()
              label = QLabel(text)
              label.setAlignment(Qt.AlignLeft)
              layout.addWidget(QCheckBox())
              layout.addWidget(label)
              self.widget.setLayout(layout)
      
          def createWidget(self,text):
              return self.widget
      

      Then in my context menu I'm adding this widget like so:

      menu = QMenu()
      open = menu.addAction(CheckBoxAction(self,"sometext"))
      

      But instead of showing this checkbox inside of the menu it shows this widget at the top left corner of the screen.

      Please advise.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @midnightdim
      You are adding your own QCheckBox, widget etc. I don't think you are supposed to do this for a QAction. You can Google for qt context menu checkbox, and/or look at https://doc.qt.io/qt-5/qaction.html#checkable-prop.

      Oohh, are you not able to go this route because of your requirement for tri-state? Then I think https://stackoverflow.com/questions/42846756/how-to-create-tri-state-actions-on-menus-using-qt or https://stackoverflow.com/questions/53812862/tristate-qaction-in-qmenu ?

      M 1 Reply Last reply
      1
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by mrjj
        #3

        HI
        Just as a note. I think a call to setDefaultWidget
        might is missing.
        https://doc.qt.io/qt-5/qwidgetaction.html#setDefaultWidget

        Update: ah you have createWidget override. I miss that.

        1 Reply Last reply
        1
        • JonBJ JonB

          @midnightdim
          You are adding your own QCheckBox, widget etc. I don't think you are supposed to do this for a QAction. You can Google for qt context menu checkbox, and/or look at https://doc.qt.io/qt-5/qaction.html#checkable-prop.

          Oohh, are you not able to go this route because of your requirement for tri-state? Then I think https://stackoverflow.com/questions/42846756/how-to-create-tri-state-actions-on-menus-using-qt or https://stackoverflow.com/questions/53812862/tristate-qaction-in-qmenu ?

          M Offline
          M Offline
          midnightdim
          wrote on last edited by
          #4

          @JonB Thanks.
          I googled for it of course, and I found the solutions you mention. Note that they inherit QWidgetAction.
          My solution is based on the first one, but I'm not sure if I've ported it to Python correctly.

          And yes, if I didn't have the requirement for tri-state I could simply use checkable menu actions.

          JonBJ 1 Reply Last reply
          0
          • M midnightdim

            @JonB Thanks.
            I googled for it of course, and I found the solutions you mention. Note that they inherit QWidgetAction.
            My solution is based on the first one, but I'm not sure if I've ported it to Python correctly.

            And yes, if I didn't have the requirement for tri-state I could simply use checkable menu actions.

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

            @midnightdim
            It helps if you reference where you got your code from when asking the question :)

            That code uses setDefaultWidget(_widget);, which @mrjj called your attention to. So don't you need self.setDefaultWidget(self.widget)? Hmm, OK, I see he has just changed his comment. Your Python code looks equivalent to the C++ to me. I don't know, unless doing it with setDefaultWidget() is better.

            mrjjM 1 Reply Last reply
            1
            • JonBJ JonB

              @midnightdim
              It helps if you reference where you got your code from when asking the question :)

              That code uses setDefaultWidget(_widget);, which @mrjj called your attention to. So don't you need self.setDefaultWidget(self.widget)? Hmm, OK, I see he has just changed his comment. Your Python code looks equivalent to the C++ to me. I don't know, unless doing it with setDefaultWidget() is better.

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @JonB

              OH i miss some many thing with python.

              in c++ the virtual function is like
              https://doc.qt.io/qt-5/qwidgetaction.html#createWidget

              QWidgetAction::createWidget(QWidget *parent)

              but his is like
              def createWidget(self,text):
              return self.widget

              so extra text with. WIll this still override the base version ? ( i guess not)

              JonBJ 1 Reply Last reply
              1
              • mrjjM mrjj

                @JonB

                OH i miss some many thing with python.

                in c++ the virtual function is like
                https://doc.qt.io/qt-5/qwidgetaction.html#createWidget

                QWidgetAction::createWidget(QWidget *parent)

                but his is like
                def createWidget(self,text):
                return self.widget

                so extra text with. WIll this still override the base version ? ( i guess not)

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @mrjj
                Yes, good spot, that does indeed look fluffy. Trouble with Python where you don't actually know whether you're overriding anything :(

                @midnightdim
                (You could put a print() statement into your override to see if it's ever really called.) Follow that advice to change your override method. Or, I don't know, use the setDefaultWidget() like the C++ does instead.

                M 1 Reply Last reply
                1
                • JonBJ JonB

                  @mrjj
                  Yes, good spot, that does indeed look fluffy. Trouble with Python where you don't actually know whether you're overriding anything :(

                  @midnightdim
                  (You could put a print() statement into your override to see if it's ever really called.) Follow that advice to change your override method. Or, I don't know, use the setDefaultWidget() like the C++ does instead.

                  M Offline
                  M Offline
                  midnightdim
                  wrote on last edited by
                  #8

                  @JonB I actually tested it before, and yes, this override does get called. I'll try to change it to setDefaultWidget().

                  1 Reply Last reply
                  1
                  • M Offline
                    M Offline
                    midnightdim
                    wrote on last edited by
                    #9

                    Thanks @JonB and @mrjj
                    I added self.setDefaultWidget(self.widget) at the end of the constructor, removed createWidget, and it does work as expected. Cool!

                    JonBJ 1 Reply Last reply
                    2
                    • M midnightdim

                      Thanks @JonB and @mrjj
                      I added self.setDefaultWidget(self.widget) at the end of the constructor, removed createWidget, and it does work as expected. Cool!

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #10

                      @midnightdim
                      Yes, I did wonder why you chose to adopt different code from that example! :)

                      M 1 Reply Last reply
                      0
                      • JonBJ JonB

                        @midnightdim
                        Yes, I did wonder why you chose to adopt different code from that example! :)

                        M Offline
                        M Offline
                        midnightdim
                        wrote on last edited by
                        #11

                        @JonB I'm not a pro programmer (started Python less than a year ago, have very small experience in C++) and the documentation for PySide6 doesn't look clear to me, also there were no examples for this particular case. So I wasn't sure about setDefaultWidget method in PySide6.
                        Thanks again.

                        1 Reply Last reply
                        1
                        • D Offline
                          D Offline
                          danielcharles
                          wrote on last edited by
                          #12

                          Hi,
                          add checkbox to context menu thorough the video link below
                          https://www.youtube.com/watch?v=TgDKcdC7X3E

                          jsulmJ 1 Reply Last reply
                          -1
                          • D danielcharles

                            Hi,
                            add checkbox to context menu thorough the video link below
                            https://www.youtube.com/watch?v=TgDKcdC7X3E

                            jsulmJ Offline
                            jsulmJ Offline
                            jsulm
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @danielcharles Why do you post a link to a video handling C#? This is Qt forum...

                            https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            2

                            • Login

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