重叠时PyQt5出现毛刺图像

时间:2020-06-27 07:34:08

标签: pyqt5

enter image description here

因此,我正在使用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)

0 个答案:

没有答案