开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜