我有两个物体,whitepawn和blackpawn,都是Piece类型。除了使用的图像之外,关于这两个对象的所有内容都是相同的。目前这是我用来绘制白色棋子的代码,
void Pawn::paintEvent(QPaintEvent *)
{
pixmap.load(":/whitepawn.png");
QPainter paint(this);
paint.drawPixmap(x, y, pixmap);
}
有没有办法为blackpawn使用不同的图像来创建一个新类并覆盖新类的paintEvent函数?
编辑:旧标题是针对不同的问题,如果你看到它,请忽略它。
答案 0 :(得分:4)
当然,你可以
class Pawn {
public:
virtual char const* imageFileName() = 0;
};
对不起,我上次对这个解释很吝啬,看起来没有额外的课程,真的应该有:
class WhitePawn : public Pawn {
public:
virtual char const* imageFileName();
};
然后覆盖(+声明):
char const* WhitePawn::imageFileName() { return "./whitepawn.png"; }
char const* BlackPawn::imageFilename() { return "./blackpawn.png"; }
并从imageFilename()
致电paintEvent()
:
void Pawn::paintEvent(QPaintEvent *)
{
pixmap.load(imageFilename());
QPainter paint(this);
paint.drawPixmap(x, y, pixmap);
}
但我个人非常喜欢Kerrek将其变为变量的想法。你甚至可以在不增加额外课程的情况下这样做:
class Pawn {
public:
Pawn(char const *filename) : filename(filename) { }
private:
char const *filname;
};
Pawn whitePawn("./whitepawn.png");
答案 1 :(得分:2)
虚拟功能是此处的标准解决方案:
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
现在您可以致电Pawn * p = new BlackPawn; p->paintEvent(e);
并获得正确的功能。 (这里的术语是“重写”,而不是“重载”,这是不同的东西。)
编辑:看到欧文的好答案,需要更改构造函数的另一个想法是使文件名成为成员变量:
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") { }
};