jzacks524
19th April 2020, 22:42
Hello, I'm working on a little poker game and I am having a graphical glitch I would like to understand better and fix. For my "Card" class I subclassed QGraphicsPixmap items and added a 52-card "deck" to my QGraphicsScene.
During runtime, I click on a button to deal the cards which then calls setPos() on the first three to simulate a flop.
The problem is, the cards don't appear to fully draw themselves right away (see photos). When I resize the window suddenly they pop into full view. The QGraphicsView is not being updated when a card position changes.
I tested calling setPos() on my background image which is a regular QGraphicsPixmap item and it moves properly and immediately updates the entire QGraphicsScene, so I'm thinking it has to be some error I've made while creating my "Card" class, but I'm not sure what I'm doing wrong.
pokerTable.cpp (relevant portion)
void PokerTable::dealFlop()
{
m_deck->burnCard();
m_flopCard1 = m_deck->dealCard(); // dealCard() returns a pointer to a Card, stored in these data members
m_flopCard2 = m_deck->dealCard();
m_flopCard3 = m_deck->dealCard();
m_flopCard1->setPos(m_flopCard1Position); //QPointF positions
m_flopCard2->setPos(m_flopCard2Position);
m_flopCard3->setPos(m_flopCard3Position);
}
Card.h
#ifndef CARD_H
#define CARD_H
#include <QGraphicsPixmapItem>
#include <QLabel>
class Card : public QGraphicsPixmapItem
{
public:
enum class Rank
{
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING,
ACE,
MAX_RANKS
};
enum class Suit
{
CLUBS,
DIAMONDS,
HEARTS,
SPADES,
MAX_SUITS
};
Card();
Card(const Card &card2);
Card& operator=(const Card &card);
int getCardValue();
void setRank(int rank);
void setSuit(int suit);
void setTexture(QPixmap texture);
void setSprite();
void printCard();
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
virtual QRectF boundingRect() const override;
private:
QPixmap m_texture;
QPointF m_sprite;
Rank m_rank;
Suit m_suit;
};
#endif // CARD_H
Card.cpp (relevant portion)
#include "Card.h"
#include <QPainter>
#include <iostream>
Card::Card()
: m_sprite{ QPointF(0, 0) }
{
setScale(0.2);
setFlag(ItemSendsGeometryChanges, true);
}
Card::Card(const Card &card2)
{
m_texture = card2.m_texture;
m_sprite = card2.m_sprite;
m_rank = card2.m_rank;
m_suit = card2.m_suit;
}
Card& Card::operator=(const Card &card)
{
m_texture = card.m_texture;
m_sprite = card.m_sprite;
m_rank = card.m_rank;
m_suit = card.m_suit;
return *this;
}
void Card::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->drawPixmap(x(), y(), m_texture, m_sprite.x(), m_sprite.y(), 560, 780);
}
QRectF Card::boundingRect() const
{
return QRectF(0, 0, 560, 780);
}
During runtime, I click on a button to deal the cards which then calls setPos() on the first three to simulate a flop.
The problem is, the cards don't appear to fully draw themselves right away (see photos). When I resize the window suddenly they pop into full view. The QGraphicsView is not being updated when a card position changes.
I tested calling setPos() on my background image which is a regular QGraphicsPixmap item and it moves properly and immediately updates the entire QGraphicsScene, so I'm thinking it has to be some error I've made while creating my "Card" class, but I'm not sure what I'm doing wrong.
pokerTable.cpp (relevant portion)
void PokerTable::dealFlop()
{
m_deck->burnCard();
m_flopCard1 = m_deck->dealCard(); // dealCard() returns a pointer to a Card, stored in these data members
m_flopCard2 = m_deck->dealCard();
m_flopCard3 = m_deck->dealCard();
m_flopCard1->setPos(m_flopCard1Position); //QPointF positions
m_flopCard2->setPos(m_flopCard2Position);
m_flopCard3->setPos(m_flopCard3Position);
}
Card.h
#ifndef CARD_H
#define CARD_H
#include <QGraphicsPixmapItem>
#include <QLabel>
class Card : public QGraphicsPixmapItem
{
public:
enum class Rank
{
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING,
ACE,
MAX_RANKS
};
enum class Suit
{
CLUBS,
DIAMONDS,
HEARTS,
SPADES,
MAX_SUITS
};
Card();
Card(const Card &card2);
Card& operator=(const Card &card);
int getCardValue();
void setRank(int rank);
void setSuit(int suit);
void setTexture(QPixmap texture);
void setSprite();
void printCard();
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
virtual QRectF boundingRect() const override;
private:
QPixmap m_texture;
QPointF m_sprite;
Rank m_rank;
Suit m_suit;
};
#endif // CARD_H
Card.cpp (relevant portion)
#include "Card.h"
#include <QPainter>
#include <iostream>
Card::Card()
: m_sprite{ QPointF(0, 0) }
{
setScale(0.2);
setFlag(ItemSendsGeometryChanges, true);
}
Card::Card(const Card &card2)
{
m_texture = card2.m_texture;
m_sprite = card2.m_sprite;
m_rank = card2.m_rank;
m_suit = card2.m_suit;
}
Card& Card::operator=(const Card &card)
{
m_texture = card.m_texture;
m_sprite = card.m_sprite;
m_rank = card.m_rank;
m_suit = card.m_suit;
return *this;
}
void Card::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->drawPixmap(x(), y(), m_texture, m_sprite.x(), m_sprite.y(), 560, 780);
}
QRectF Card::boundingRect() const
{
return QRectF(0, 0, 560, 780);
}