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. Drawing composed widget
QtWS25 Last Chance

Drawing composed widget

Scheduled Pinned Locked Moved Solved General and Desktop
qpainterqwidgetqpainterpath
5 Posts 2 Posters 462 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.
  • Pl45m4P Offline
    Pl45m4P Offline
    Pl45m4
    wrote on last edited by Pl45m4
    #1

    I'm working on a customly drawn widget right now, which consists out of multiple sub-elements.
    Each child-widget (separate code file / class) has its own paintEvent and is drawn using a QPainterPath or just by simple QPainter::drawRoundedRect.
    One of them is some kind of border/"halo" around the main widget.

    Looks about like this (simplified)

    BorderButton.png

    For that, the sub-element (yellow frame) has the exact same size as the parent (gray rounded rect), since the childs geometry/boundings can't exceed the parents coordinate system (for obvious reasons).

    The problem I have is that I want to interact with the different sections (subwidgets) of the widget.
    Doing that, if I click for example on the yellow border, some signal is emitted... works fine so far.
    However one of the signals (in mousePressEvent of the border child is also emitted when clicking the "hole"... the area where the child border widget is not drawn, because it's within the widget's boundings...

    Maybe my way of doing this is wrong and there is a better way, but I'm looking for a solution to paint the border on top of the main widget with some kind of hole in the middle, so that user interactions (mouse hover, mouse clicks) only affect the actual "painted" area and not the invisible one, which became part of the child widget.
    No problems with the other child widgets, but since this specific one has a ring structure along the edge of the main widget, I don't know any other way than doing it the way I've tried.

    Open for any suggestions :)


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

    ~E. W. Dijkstra

    M 1 Reply Last reply
    0
    • Pl45m4P Pl45m4

      * BUMP *

      No suggestions?!

      I would be happy if someone could confirm that it is not possible what I'm trying to do (no way) or that I am on the wrong track with my approach (possibly).

      It actually seems so simple, but somehow I'm failing to properly draw my widget.

      Edit:

      Will add some code later, showing what I have so far.

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

      Solved.

      For further readers:
      I've added a check to the child widget whether a user interaction happens within its drawn borders (a closed QPainterPath).
      If so, I consume the event and continue from there, if not, I ignore the event and pass it to the parent widget, i.e. the actual MyWidget, so that the overlaying child widget has some transparency for my defined events (some key and mouse interaction).

      Pretty easy if I think about it now.
      The idea of having some kind of a donut shaped widget (yellow part in my sketch), which does not occupy the center of its parent widget was stuck in my head way too long :))


      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
      2
      • Pl45m4P Pl45m4

        I'm working on a customly drawn widget right now, which consists out of multiple sub-elements.
        Each child-widget (separate code file / class) has its own paintEvent and is drawn using a QPainterPath or just by simple QPainter::drawRoundedRect.
        One of them is some kind of border/"halo" around the main widget.

        Looks about like this (simplified)

        BorderButton.png

        For that, the sub-element (yellow frame) has the exact same size as the parent (gray rounded rect), since the childs geometry/boundings can't exceed the parents coordinate system (for obvious reasons).

        The problem I have is that I want to interact with the different sections (subwidgets) of the widget.
        Doing that, if I click for example on the yellow border, some signal is emitted... works fine so far.
        However one of the signals (in mousePressEvent of the border child is also emitted when clicking the "hole"... the area where the child border widget is not drawn, because it's within the widget's boundings...

        Maybe my way of doing this is wrong and there is a better way, but I'm looking for a solution to paint the border on top of the main widget with some kind of hole in the middle, so that user interactions (mouse hover, mouse clicks) only affect the actual "painted" area and not the invisible one, which became part of the child widget.
        No problems with the other child widgets, but since this specific one has a ring structure along the edge of the main widget, I don't know any other way than doing it the way I've tried.

        Open for any suggestions :)

        M Offline
        M Offline
        mpergand
        wrote on last edited by mpergand
        #2

        Hi @Pl45m4

        Maybe Have a try with:

        Qt::WA_TransparentForMouseEvents
        When enabled, this attribute disables the delivery of mouse events to the widget and its children. Mouse events are delivered to other widgets as if the widget and its children were not present in the widget hierarchy; mouse clicks and other events effectively "pass through" them. This attribute is disabled by default.

        Pl45m4P 1 Reply Last reply
        0
        • M mpergand

          Hi @Pl45m4

          Maybe Have a try with:

          Qt::WA_TransparentForMouseEvents
          When enabled, this attribute disables the delivery of mouse events to the widget and its children. Mouse events are delivered to other widgets as if the widget and its children were not present in the widget hierarchy; mouse clicks and other events effectively "pass through" them. This attribute is disabled by default.

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

          @mpergand said in Drawing composed widget:

          Qt::WA_TransparentForMouseEvents
          When enabled, this attribute disables the delivery of mouse events to the widget and its children. Mouse events are delivered to other widgets as if the widget and its children were not present in the widget hierarchy; mouse clicks and other events effectively "pass through" them. This attribute is disabled by default.

          Is this "hacking" or is this how one would do this in general?!
          I mean, my idea overall is pretty standard I would say, but haven't found any example of some custom (not using any QStyle::drawPrimitive or ::drawComplex) composed widget, built the way I thought of...but for sure nothing new.
          So basically MyWidget is parent of widget Border and other painted child widgets, that are hidden from the user of MyWidget.

          I'm actually not that familiar with a more complex and structural use of QPainter.
          My first approach was painting every sub-region (borders etc.) inside the one widget's paintEvent... and then differ where exactly the user interaction has happened... but that was a complete mess and I couldn't catch mouse events as easy as I can now that my widget has its own internal child widgets (as separate classes).

          Edit:
          I think I can't use Qt::WA_TransparentForMouseEvents anyway since all child widgets and including the main widget need to receive mouse events at some point. But only in regions where their painting is active.


          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
          • Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote on last edited by Pl45m4
            #4

            * BUMP *

            No suggestions?!

            I would be happy if someone could confirm that it is not possible what I'm trying to do (no way) or that I am on the wrong track with my approach (possibly).

            It actually seems so simple, but somehow I'm failing to properly draw my widget.

            Edit:

            Will add some code later, showing what I have so far.


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

            ~E. W. Dijkstra

            Pl45m4P 1 Reply Last reply
            0
            • Pl45m4P Pl45m4

              * BUMP *

              No suggestions?!

              I would be happy if someone could confirm that it is not possible what I'm trying to do (no way) or that I am on the wrong track with my approach (possibly).

              It actually seems so simple, but somehow I'm failing to properly draw my widget.

              Edit:

              Will add some code later, showing what I have so far.

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

              Solved.

              For further readers:
              I've added a check to the child widget whether a user interaction happens within its drawn borders (a closed QPainterPath).
              If so, I consume the event and continue from there, if not, I ignore the event and pass it to the parent widget, i.e. the actual MyWidget, so that the overlaying child widget has some transparency for my defined events (some key and mouse interaction).

              Pretty easy if I think about it now.
              The idea of having some kind of a donut shaped widget (yellow part in my sketch), which does not occupy the center of its parent widget was stuck in my head way too long :))


              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
              2
              • Pl45m4P Pl45m4 has marked this topic as solved on

              • Login

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