[英]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.