为同一个类的两个对象绘制不同的图像

时间:2011-08-28 02:27:48

标签: c++ qt

我有两个物体,whitepawn和blackpawn,都是Piece类型。除了使用的图像之外,关于这两个对象的所有内容都是相同的。目前这是我用来绘制白色棋子的代码,

void Pawn::paintEvent(QPaintEvent *)
{
    pixmap.load(":/whitepawn.png");

    QPainter paint(this);
    paint.drawPixmap(x, y, pixmap);
}

有没有办法为blackpawn使用不同的图像来创建一个新类并覆盖新类的paintEvent函数?

编辑:旧标题是针对不同的问题,如果你看到它,请忽略它。

2 个答案:

答案 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") { }
};