I have cards in my scene. For example in this code i tried to move my ManikenCard object to another position, but can't do this, because my moving methods don't respond to my clicks (i add "print" to this methods ).I noticed, that i can click on my Card and it raise MausePressEvent , and it say that only my drag-and-drop system doesn't work . How can i move my cards on the field. I read this article Drag n Drop inside QgraphicsView doesn't work (PyQt) with the similar problem, but can't do this in my own program .
from PyQt5 import QtCore, QtGui, QtWidgets
import os,random
class PyramideCard(QtWidgets.QLabel):
card_suits = ['♠', '♥', '♦', '♣']
card_ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'B', 'D', 'K']
card_values = {rank: value for value, rank in enumerate(card_ranks, 1)}
def __init__(self,rank,suit):
#----------------Backend_data---------------------
self.__suit = suit
self.__rank = rank
self.__value = PyramideCard.card_values[rank]
# ----------------State-------------------------
self.active = False # back_ground_phone
self.visible = False
#----------------Visual_parameters----------------
self.__img_back = os.path.join(r"C:\Users\user\Desktop\ооп\Programs\Pyramide\Cards_100_150\purple_back")
QtWidgets.QLabel.__init__(self)
self.setGeometry(QtCore.QRect(0, 0, 100, 150))
self.setObjectName(self.__rank + self.__suit)
self.__img = os.path.join(r"C:\Users\user\Desktop\ооп\Programs\Pyramide\Cards_100_150", self.__rank +
self.__suit)
self.setPixmap_()
self.ScaledContents=True
#----------------drag_drop----------------
self.setAcceptDrops(True)
def setPixmap_(self):
if self.visible :
self.setPixmap(QtGui.QPixmap(self.__img))
else :
self.setPixmap(QtGui.QPixmap(self.__img_back))
def change_visible(self):
if self.visible :
self.visible = False
self.setPixmap_()
else :
self.visible = True
self.setPixmap_()
def change_active_state(self):
if self.active :
self.active = False
else :
self.active = True
def __add__(self, other):
return self.value + other.value
class MinikenCard(QtWidgets.QLabel):
#signalChangeDeckCard = QtCore.pyqtSignal()
def __init__(self):
# ----------------Visual_parameters----------------
QtWidgets.QLabel.__init__(self)
self.setGeometry(QtCore.QRect(0, 0, 100, 150))
self.setObjectName("DeckCard")
self.__img = os.path.join(r"C:\Users\user\Desktop\ооп\Programs\Pyramide\Cards_100_150\purple_back")
self.setPixmap(QtGui.QPixmap(self.__img))
self.ScaledContents = True
self.setAcceptDrops(True)
def mouseMoveEvent(self, e):
"""PROBLEM IS HERE """
print("Moving")
if e.buttons() != QtCore.Qt.RightButton:
return
mimeData = QMimeData()
drag = QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
dropAction = drag.exec_(Qt.MoveAction)
def mousePressEvent(self, e):
QtWidgets.QLabel.mousePressEvent(self, e)
if e.button() == QtCore.Qt.LeftButton:
print('press')
class PyramideCardsCreator() :
'''create cards fpr Pyramide game'''
def create_cards_for_game(self) -> list :
'''
:return: list of all the game cards
'''
suits = PyramideCard.card_suits
ranks = PyramideCard.card_ranks
return [ PyramideCard(rank,suit)
for suit in suits
for rank in ranks ]
def optional_components(self):
'''
:return: tuple(deck_cards,playing_layers-cards in the field)
'''
cards = self.create_cards_for_game()
random.shuffle(cards)
playing_cards = cards[:28]
deck_cards = cards[28:]
return deck_cards,self.createPiramideCardsLayers(playing_cards)
def createPiramideCardsLayers(self,cards):
'''
emit from optional_components
:param cards: all cards in the game
:return: list of card in the field : [[0],[0,1]..[0,1,2,4,5]]
'''
f = 0
playing_layers = []
for layer in range(6, -1, -1):
playing_layers.append(cards[f:f + layer + 1])
f += layer + 1
return playing_layers
class PyramideScene(QtWidgets.QGraphicsScene):
def __init__(self):
QtWidgets.QGraphicsScene.__init__(self)
#------------------------scene_parameters----------------------
self.setBackgroundBrush(QtGui.QColor(92,117,97,alpha = 255))
self.setSceneRect(0, 150, 995, 650)
self.addRect(self.sceneRect())
#------------------------adding_cards_to_the_field-------------
self.deck_cards, self.pyramide_layers = PyramideCardsCreator().optional_components()
self.cards_to_the_deck()
maniken_obj=MinikenCard()
self.maniken_card=self.addWidget(maniken_obj)
self.maniken_card.setPos(30,200)
#maniken_obj.signalChangeDeckCard.connect(self.ChangeDeckCard)
# ----------------------------------------------------
@QtCore.pyqtSlot()
def ChangeDeckCard(self):
print("ChangeCardDeck")
def dragEnterEvent(self, e):
"PROBLEM IS HERE "
print('dragEnterEvent')
e.accept()
def dropEvent(self, e):
"PROBLEM IS HERE "
print('dropEvent')
position = e.pos()
self.maniken_card.move(position)
e.setDropAction(Qt.MoveAction)
e.accept()
def cards_to_the_deck(self):
layers =self.pyramide_layers
# make the firs layer visible
for card in layers[0]:
card.change_visible()
# starter point to put card in the field
starter_x=635
for layer in range(len(layers),-1,-1) :
layer_length=7-layer
for card in range(layer_length) :
card_in_the_field=self.addWidget(layers[layer][card])
card_in_the_field.setPos(starter_x-(layer_length-card)*100,(layer_length+1)*80)
starter_x+=50
class Game(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setObjectName('MainWidget')
self.setStyleSheet('''#MainWidget {
background-color: #267;
}''')
# parameters QWIndowWIdget
self.setFixedSize(1050,800 )
self.Initialization()
def Initialization(self):
layout = QtWidgets.QGridLayout()
self.setLayout(layout)
self.PyramideView = QtWidgets.QGraphicsView()
self.PyramideView.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
layout.addWidget(self.PyramideView)
self.PyramideScene = PyramideScene()
self.PyramideView.setScene(self.PyramideScene)
#parameters PyramideView
self.PyramideView.setFixedSize(1000, 655)
self.PyramideView.setRenderHints(QtGui.QPainter.Antialiasing)
self.setAcceptDrops(True)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
Pyramide = Game()
Pyramide.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()