Drawing a different image for two objects of the same class
I have two objects, whitepawn and blackpawn, that are of type Piece. Everything about these two objects is the same except for the image used. Currently this is the code I use to draw the white pawn,
void Pawn::paintEvent(QPaintEvent *)
{
pixmap.load(":/whitepawn.png");
QPainter paint(this);
paint.drawPixmap(x, y, pixmap);
}
Is ther开发者_StackOverflowe a way to use a different image for blackpawn with making a new class and overriding the new class's paintEvent function?
Edit: The old title was for a different question, ignore that if you saw it.
Sure, you can
class Pawn {
public:
virtual char const* imageFileName() = 0;
};
Sorry, I was skimpy on the explanation last time and made it look like there weren't extra classes, there really should be:
class WhitePawn : public Pawn {
public:
virtual char const* imageFileName();
};
Then override (+ declaration):
char const* WhitePawn::imageFileName() { return "./whitepawn.png"; }
char const* BlackPawn::imageFilename() { return "./blackpawn.png"; }
and call imageFilename()
from paintEvent()
:
void Pawn::paintEvent(QPaintEvent *)
{
pixmap.load(imageFilename());
QPainter paint(this);
paint.drawPixmap(x, y, pixmap);
}
But I personally like Kerrek's idea of making it a variable. You could even do that without making extra classes:
class Pawn {
public:
Pawn(char const *filename) : filename(filename) { }
private:
char const *filname;
};
Pawn whitePawn("./whitepawn.png");
Virtual functions are the standard solution here:
class Pawn
{
virtual void paintEvent(QPaintEvent *) { }
// ...
};
class WhitePawn : public Pawn
{
virtual voidpaintEvent(QPaintEvent *)
{
pixmap.load(":/whitepawn.png");
QPainter paint(this);
paint.drawPixmap(x, y, pixmap);
}
};
// similar for class BlackPawn
Now you can call Pawn * p = new BlackPawn; p->paintEvent(e);
and get the correct function. (The term here is "overriding", not "overloading", which is something different.)
Edit: Seeing Owen's fine answer, another idea that requires changing the constructors is to make the filename a member variable:
class Pawn
{
public: Pawn(const std::string & filename = "") : m_filename(filename) { }
void paintEvent(QPaintEvent *)
{
if (m_filename == "") return;
pixmap.load(m_filename);
QPainter paint(this);
paint.drawPixmap(x, y, pixmap);
}
// ...
private: std::string m_filename;
};
class BlackPawn : public Pawn
{
public: BlackPawn() : Pawn(":/blackpawn.png") { }
};
精彩评论