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 control the z-order of QLabel widgets at run-time?
Forum Updated to NodeBB v4.3 + New Features

How to control the z-order of QLabel widgets at run-time?

Scheduled Pinned Locked Moved Unsolved Qt for Python
4 Posts 3 Posters 1.8k Views 1 Watching
  • 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.
  • R Offline
    R Offline
    RaspPieman
    wrote on last edited by
    #1

    I am using Python and PyQt5.QtWidgets to simulate a card game. I have created a card table using QTdesigner and am dynamically creating QLabel widgets then using QPixmap to set them to one of 52 card images.

    I can successfully drag and drop them anywhere on the card table.

    However, when I drop them so they overlap each other, the widget which was created later, in time, is always in front of the one created earlier.

    I still want to see both widgets even if one is partially overlapping the other.

    Is there any way, in PyQt5, to control the z-axis, i.e. so I can decide at run-time which widget is to be on top?

    I have included the python code and qtdesigner .ui xml below. I don't know how to include the 52 card images, but they can be simulated by creating simple .png images with a width of 66 and height of 100 pixels.

    python code:

    # cardTableQT.py
    
    # imports
    from PyQt5.QtWidgets import *
    from PyQt5 import uic
    from PyQt5.Qt import QStandardItemModel, QStandardItem
    from PyQt5.QtGui import QPixmap, QDrag, QPainter
    from PyQt5.QtCore import Qt, QMimeData
    
    # classes
    class DraggableLabel(QLabel):
        def mousePressEvent(self, event):
            if event.button() == Qt.LeftButton:
                self.drag_start_position = event.pos()            
                if len(label_being_dragged) > 0:
                    label_being_dragged[0] = self
                else:
                    label_being_dragged.append(self)
    
        def mouseMoveEvent(self, event):
            if not (event.buttons() & Qt.LeftButton):
                return
            if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
                return
            self.setVisible(False)
            drag = QDrag(self)
            mimedata = QMimeData()
            mimedata.setText(self.text())
            drag.setMimeData(mimedata)
            pixmap = QPixmap(self.size())
            painter = QPainter(pixmap)
            painter.drawPixmap(self.rect(), self.grab())
            painter.end()
            drag.setPixmap(pixmap)
            drag.setHotSpot(event.pos())
            drag.exec_(Qt.CopyAction | Qt.MoveAction)        
            if not self.isVisible(): self.setVisible(True) # if dragged off window, make visible again
    
    class cardTableQTGUI(QMainWindow):
    
        def __init__(self):
            global gui
            super(cardTableQTGUI, self).__init__()
            uic.loadUi('cardTableQT.ui', self)
            self.setAcceptDrops(True)
            gui = self
    
            self.setWindowTitle('cardTableQT V1.0')
    
            green_baise = '#008800' # colour the card table
            self.stackedWidget.setStyleSheet(f"background-color: {green_baise};")
    
            # this folder contains 52 card images (0.png - 51.png)
            cards_path = 'Y:/Downloads/p/PlayingCards/cards_png_zip/deck/renamed'
    
            # create a deck of 52 cards
            self.card_labels = []
            for n in range(52):
                self.card_labels.append(DraggableLabel("",self))
                self.card_labels[-1].setGeometry(10 + n * 22, 10, 66, 100)
                self.card_labels[-1].setScaledContents(True)
                self.card_labels[-1].setPixmap(QPixmap(cards_path + '/' + str(n) + '.png'))
    
            self.show()
    
        def dragEnterEvent(self, event):
            if event.mimeData().hasText():
                event.acceptProposedAction()
    
        def dropEvent(self, event):
            pos = event.pos()
            x = pos.x() - 33 # centre the point on image
            y = pos.y() - 50
            label_dragged = label_being_dragged[0]
            label_dragged.setGeometry(x, y, 66, 100)
            label_dragged.setVisible(True)
            label_being_dragged.pop()
            event.acceptProposedAction()    
    
    # global variables
    label_being_dragged = []
    
    # main program gui
    app = QApplication([])
    gui = cardTableQTGUI()
    
    # start app
    app.exec_()
    
    

    QTdesigner xml file: cardTableQT.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>1255</width>
        <height>672</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <widget class="QStackedWidget" name="stackedWidget">
        <property name="geometry">
         <rect>
          <x>10</x>
          <y>9</y>
          <width>1231</width>
          <height>651</height>
         </rect>
        </property>
        <widget class="QWidget" name="page"/>
        <widget class="QWidget" name="page_2"/>
       </widget>
      </widget>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    JonBJ 1 Reply Last reply
    0
    • R RaspPieman

      I am using Python and PyQt5.QtWidgets to simulate a card game. I have created a card table using QTdesigner and am dynamically creating QLabel widgets then using QPixmap to set them to one of 52 card images.

      I can successfully drag and drop them anywhere on the card table.

      However, when I drop them so they overlap each other, the widget which was created later, in time, is always in front of the one created earlier.

      I still want to see both widgets even if one is partially overlapping the other.

      Is there any way, in PyQt5, to control the z-axis, i.e. so I can decide at run-time which widget is to be on top?

      I have included the python code and qtdesigner .ui xml below. I don't know how to include the 52 card images, but they can be simulated by creating simple .png images with a width of 66 and height of 100 pixels.

      python code:

      # cardTableQT.py
      
      # imports
      from PyQt5.QtWidgets import *
      from PyQt5 import uic
      from PyQt5.Qt import QStandardItemModel, QStandardItem
      from PyQt5.QtGui import QPixmap, QDrag, QPainter
      from PyQt5.QtCore import Qt, QMimeData
      
      # classes
      class DraggableLabel(QLabel):
          def mousePressEvent(self, event):
              if event.button() == Qt.LeftButton:
                  self.drag_start_position = event.pos()            
                  if len(label_being_dragged) > 0:
                      label_being_dragged[0] = self
                  else:
                      label_being_dragged.append(self)
      
          def mouseMoveEvent(self, event):
              if not (event.buttons() & Qt.LeftButton):
                  return
              if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
                  return
              self.setVisible(False)
              drag = QDrag(self)
              mimedata = QMimeData()
              mimedata.setText(self.text())
              drag.setMimeData(mimedata)
              pixmap = QPixmap(self.size())
              painter = QPainter(pixmap)
              painter.drawPixmap(self.rect(), self.grab())
              painter.end()
              drag.setPixmap(pixmap)
              drag.setHotSpot(event.pos())
              drag.exec_(Qt.CopyAction | Qt.MoveAction)        
              if not self.isVisible(): self.setVisible(True) # if dragged off window, make visible again
      
      class cardTableQTGUI(QMainWindow):
      
          def __init__(self):
              global gui
              super(cardTableQTGUI, self).__init__()
              uic.loadUi('cardTableQT.ui', self)
              self.setAcceptDrops(True)
              gui = self
      
              self.setWindowTitle('cardTableQT V1.0')
      
              green_baise = '#008800' # colour the card table
              self.stackedWidget.setStyleSheet(f"background-color: {green_baise};")
      
              # this folder contains 52 card images (0.png - 51.png)
              cards_path = 'Y:/Downloads/p/PlayingCards/cards_png_zip/deck/renamed'
      
              # create a deck of 52 cards
              self.card_labels = []
              for n in range(52):
                  self.card_labels.append(DraggableLabel("",self))
                  self.card_labels[-1].setGeometry(10 + n * 22, 10, 66, 100)
                  self.card_labels[-1].setScaledContents(True)
                  self.card_labels[-1].setPixmap(QPixmap(cards_path + '/' + str(n) + '.png'))
      
              self.show()
      
          def dragEnterEvent(self, event):
              if event.mimeData().hasText():
                  event.acceptProposedAction()
      
          def dropEvent(self, event):
              pos = event.pos()
              x = pos.x() - 33 # centre the point on image
              y = pos.y() - 50
              label_dragged = label_being_dragged[0]
              label_dragged.setGeometry(x, y, 66, 100)
              label_dragged.setVisible(True)
              label_being_dragged.pop()
              event.acceptProposedAction()    
      
      # global variables
      label_being_dragged = []
      
      # main program gui
      app = QApplication([])
      gui = cardTableQTGUI()
      
      # start app
      app.exec_()
      
      

      QTdesigner xml file: cardTableQT.ui

      <?xml version="1.0" encoding="UTF-8"?>
      <ui version="4.0">
       <class>MainWindow</class>
       <widget class="QMainWindow" name="MainWindow">
        <property name="geometry">
         <rect>
          <x>0</x>
          <y>0</y>
          <width>1255</width>
          <height>672</height>
         </rect>
        </property>
        <property name="windowTitle">
         <string>MainWindow</string>
        </property>
        <widget class="QWidget" name="centralwidget">
         <widget class="QStackedWidget" name="stackedWidget">
          <property name="geometry">
           <rect>
            <x>10</x>
            <y>9</y>
            <width>1231</width>
            <height>651</height>
           </rect>
          </property>
          <widget class="QWidget" name="page"/>
          <widget class="QWidget" name="page_2"/>
         </widget>
        </widget>
       </widget>
       <resources/>
       <connections/>
      </ui>
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @RaspPieman
      Look in QWidget for stackUnder(), raise() & lower().

      R 1 Reply Last reply
      1
      • jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by
        #3

        This sounds like a better case for graphics view or Quick use. Both offer an explicit z axis.

        Asking a question about code? http://eel.is/iso-c++/testcase/

        1 Reply Last reply
        1
        • JonBJ JonB

          @RaspPieman
          Look in QWidget for stackUnder(), raise() & lower().

          R Offline
          R Offline
          RaspPieman
          wrote on last edited by
          #4

          @JonB - Thanks, once I have worked out that, in Python, I must use .raise_() instead of .raise() - it all worked as desired - Thank-you for your response.

          1 Reply Last reply
          1

          • Login

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