簡體   English   中英

如何拖動和覆蓋 QLabel 小部件,以便最近放置的小部件位於頂部

[英]How to drag and overlay QLabel widgets so that the most recently dropped is on top

我正在使用 Python 和 PyQt5.QtWidgets 來模擬紙牌游戲。 我已經使用 QTdesigner 創建了一個卡片表,並且正在動態創建 QLabel 小部件,然后使用 QPixmap 將它們設置為 52 張卡片圖像之一。

我可以成功地將它們拖放到牌桌上的任何位置。

但是,當我放下它們使它們相互重疊時,后來創建的小部件及時總是在較早創建的小部件的前面。

我仍然希望看到兩個小部件,即使一個小部件與另一個小部件部分重疊。

在 PyQt5 中,有什么方法可以控制 z 軸,這樣我就可以在運行時決定哪個小部件位於頂部?

我在下面包含了 python 代碼和 qtdesigner.ui xml。 我不知道如何包含 52 張卡片圖像,但可以通過創建寬度為 66 像素、高度為 100 像素的 simple.png 圖像來模擬它們。

python 代碼:

# 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“cardTableQT.ui”xml:

<?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>

提供的代碼,如建議的那樣:@Сергей Кох

感謝 @JonB at https://forum.qt.io/topic/141865他向我指出QWidget.raise_()解決了問題,在def dropEvent中使用它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM