因此,我正在使用PyQt5为学校项目制作UNO游戏。每张卡都是一个QAbstractButton,当我重叠它们时会发生这种奇怪的事情。反正有解决的办法,还是有人可以解释为什么会发生这种情况?
这是Button类。
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class cardBtn(QAbstractButton):
def __init__(self, pixmap, card=None, parent=None):
super(cardBtn, self).__init__(parent)
self.pixmap = QtGui.QPixmap(pixmap)
self.setMaximumSize(self.sizeHint())
self.setMinimumSize(self.sizeHint())
self.card = card
self.pressed.connect(self.update)
self.released.connect(self.update)
self.isSelected = False
timer = QTimer(self)
timer.timeout.connect(self.update)
timer.start(10)
def paintEvent(self, event):
pix = self.pixmap
painter = QPainter(self)
painter.drawPixmap(event.rect(), pix)
def enterEvent(self, event):
self.update()
def leaveEvent(self, event):
self.update()
def sizeHint(self):
return QSize(195, 275)
def selected(self):
self.isSelected = not self.isSelected
return self.isSelected
这是显示卡片的类
class Board(QMainWindow):
def __init__(self, username):
super().__init__()
self.title = 'UNO - Version 0.2'
self.top = 0
self.left = 0
self._login = False
self.username = username
# self.screenShape = QtWidgets.QDesktopWidget().screenGeometry()
# self.width = self.screenShape.width()
# self.height = self.screenShape.height()
self.width = 1920
self.height = 1080
self.playerDeck_cards = []
self.playerDeck_img = []
self.playerDeck_btn = []
self.drawDeck = Button.cardBtn("image/cover1.png", parent=self)
self.deck = []
self.playedCards = []
self.selectedCards = []
self.initDeck()
self.populateHandDeck()
self.setStyleSheet("background-image:url(image/background2.png); background-repeat:no-repeat; background-position:center;")
self.InitWindow()
# Implement the resizeEvent for relative positioning
def resizeEvent(self, event):
self.drawDeck.move(int(self.frameGeometry().width()*0.8), int(self.frameGeometry().height()*0.4))
for card in self.playerDeck_btn:
card.move(card.x(), self.frameGeometry().height()-310)
def InitWindow(self):
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.drawDeck.move(int(self.frameGeometry().width()*0.8), int(self.frameGeometry().height()*0.4))
self.drawDeck.clicked.connect(self.drawCardFromDeck)
self.showHandDeck()
while True:
startingCard = random.choice(self.deck)
if not(startingCard.isWild() or startingCard.isAction()):
break
self.playedCards.append(startingCard)
self.deck.remove(startingCard)
self.playedDeck = Button.cardBtn(self.playedCards[-1].imgPath, parent=self)
self.playedDeck.move(int(self.frameGeometry().width()*0.5), int(self.frameGeometry().height()*0.4))
# self.infoField = QLabel(parent=self)
# self.infoField.move(int(self.frameGeometry().width()-300), int(self.frameGeometry().height()-300))
# self.infoField.setText("INFO FIELD")
# self.infoField.setFont(QFont('Arial', 30))
# self.infoField.setFixedSize(300, 300)
# self.infoField.setStyleSheet("background-color:#848484; color:black")
self.show()
def initDeck(self):
self.deck = []
for _ in range(4):
self.deck.append(Card.wildCard('image/wild_draw4.png', 'draw4'))
self.deck.append(Card.wildCard('image/wild.png', 'changeColor'))
for _ in range(2):
for j in range(1,10):
r_card = Card.numberCard(f'image/r{j}.png', 'red', j)
g_card = Card.numberCard(f'image/g{j}.png', 'green', j)
b_card = Card.numberCard(f'image/b{j}.png', 'blue', j)
y_card = Card.numberCard(f'image/y{j}.png', 'yellow', j)
self.deck.extend([r_card, g_card, b_card, y_card])
self.deck.append(Card.actionCard('image/r_draw2.png', 'draw2', 'red'))
self.deck.append(Card.actionCard('image/g_draw2.png', 'draw2', 'green'))
self.deck.append(Card.actionCard('image/b_draw2.png', 'draw2', 'blue'))
self.deck.append(Card.actionCard('image/y_draw2.png', 'draw2', 'yellow'))
self.deck.append(Card.actionCard('image/r_rev.png', 'reverse', 'red'))
self.deck.append(Card.actionCard('image/g_rev.png', 'reverse', 'green'))
self.deck.append(Card.actionCard('image/b_rev.png', 'reverse', 'blue'))
self.deck.append(Card.actionCard('image/y_rev.png', 'reverse', 'yellow'))
self.deck.append(Card.actionCard('image/r_skip.png', 'skip', 'red'))
self.deck.append(Card.actionCard('image/g_skip.png', 'skip', 'green'))
self.deck.append(Card.actionCard('image/b_skip.png', 'skip', 'blue'))
self.deck.append(Card.actionCard('image/y_skip.png', 'skip', 'yellow'))
self.deck.append(Card.numberCard('image/r0.png', 'red', 0))
self.deck.append(Card.numberCard('image/g0.png', 'green', 0))
self.deck.append(Card.numberCard('image/b0.png', 'blue', 0))
self.deck.append(Card.numberCard('image/y0.png', 'yellow', 0))
def showHandDeck(self):
for btn in reversed(self.playerDeck_btn):
self.playerDeck_btn.remove(btn)
btn.deleteLater()
overlap = 210 if len(self.playerDeck_cards) <= 7 else (1440//len(self.playerDeck_cards))
offset = 150
for card in self.playerDeck_cards:
cardbtn = Button.cardBtn(card.imgPath, card=card, parent=self)
cardbtn.clicked.connect(partial(self.selectCard, cardbtn))
cardbtn.move(offset, self.frameGeometry().height()-310)
offset += overlap
cardbtn.show()
self.playerDeck_btn.append(cardbtn)
def reset(self):
self.playedCard = []
self.initDeck()
def populateHandDeck(self):
for i in range(10):
self.drawCardFromDeck()
def drawCardFromDeck(self):
card = random.choice(self.deck)
self.playerDeck_cards.append(card)
self.deck.remove(card)
self.showHandDeck()
def selectCard(self, btn):
lastCard = self.playedCards[-1]
selectedCard = btn.card
print(selectedCard.getNumber())
print(lastCard.getNumber())
numberMatch = selectedCard.getNumber() == lastCard.getNumber()
colorMatch = selectedCard.getColor() == lastCard.getColor()
print(numberMatch, colorMatch)
if colorMatch or numberMatch or selectedCard.isWild():
self.anim = QPropertyAnimation(btn, b"geometry")
self.anim.setDuration(250)
if btn.selected():
self.anim.setStartValue(QRect(btn.x(), btn.y(), 195, 275))
self.anim.setEndValue(QRect(btn.x(), btn.y()-100, 195, 275))
else:
self.anim.setStartValue(QRect(btn.x(), btn.y(), 195, 275))
self.anim.setEndValue(QRect(btn.x(), btn.y()+100, 195, 275))
self.anim.start()
一开始它会很好地显示出来,但是当我单击抽奖卡上的一张卡片时,它将开始出现故障。
万一有人需要,下面是Card类
class Card():
def __init__(self, imgPath, number=None, color=None, action=None, _isWild=False, _isAction=False):
self.imgPath = imgPath
self.number = number
self.color = color
self.action = action
self._isWild = _isWild
self._isAction = _isAction
def isWild(self):
return self._isWild
def isAction(self):
return self._isAction
def getNumber(self):
return self.number
def getColor(self):
return self.color
def getAction(self):
return self.action
def __str__(self):
if self._isWild:
return f'Wild Card: {self.action}'
elif self._isAction:
return f'Action Card: {self.color}, {self.action}'
else:
return f'Number Card: {self.color}, {self.number}'
class wildCard(Card):
def __init__(self, imgPath, action):
super().__init__(imgPath, _isWild=True, action=action)
def setColor(self, color):
self.color = color
class numberCard(Card):
def __init__(self, imgPath, color, number):
super().__init__(imgPath, number=number, color=color)
class actionCard(Card):
def __init__(self, imgPath, action, color):
super().__init__(imgPath, color=color, action=action, _isAction=True)