tags:

views:

66

answers:

3

I need to place several instances of a custom QPushButton subclass adjacent to one another. For some reason, the buttons overlap one another when painted. A simplified example of the problem is below.

Here is the (incorrect) output:

overlapping

Here is the code:

#include <QtGui>

class MyButton : public QPushButton {
public:
  explicit MyButton(Qt::GlobalColor color, QWidget *parent = NULL)
    : QPushButton(parent), color_(color) {
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  }
  QSize sizeHint() const {
    return QSize(50, 25);
  }
protected:
  void paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setOpacity(0.5);
    painter.fillRect(0, 0, width(), height(), color_);
  }
private:
  Qt::GlobalColor color_;
};

int main(int argc, char **argv) {
  QApplication app(argc, argv);
  QWidget widget;
  QHBoxLayout *layout = new QHBoxLayout;
  layout->setSpacing(0);
  MyButton *w1 = new MyButton(Qt::red);
  MyButton *w2 = new MyButton(Qt::green);
  MyButton *w3 = new MyButton(Qt::blue);
  layout->addWidget(w1);
  layout->addWidget(w2);
  layout->addWidget(w3);
  widget.setLayout(layout);
  widget.show();
  return app.exec();
}

What is causing this, and how do I fix it? BTW, I tried something similar with regular QWidget subclasses (instead of QPushButton subclasses), and there is no problem. It is something peculiar to QPushButton.

UPDATE: I'm really thinking now that this is a bug. I submitted it to the Qt Bug Tracker; we'll see what the Trolls think. In any case, deriving from QAbstractButton fixes the drawing problem ... I just had to re-implement some of the functionality I needed.

UPDATE 2: The Trolls at Qt provided a solution (workaround?); I posted their fix as an answer below. I'm leaving it up to their team to determine if this is a feature or bug. It apparently only behaves differently on the Mac.

A: 

Instead of calling setSizePolicy() and reimplement sizeHint(), I would try to simply call

setFixedSize(50, 25)

in your constructor. This should update the sizeHint on its own.

Hope this helps.

Live
`setFixedSize` causes the same behavior. I'm really starting to think this is just a bug.
Dave
A: 

Your code works fine for me. I have tested it. What version you use? I use Qt 4.6.3 and it is fine.

Narek
I'm on Mac OS X 10.6.4; Qt 4.7.0
Dave
I think that is the problem. Yes may be it is a bug.
Narek
+2  A: 

The solution is to add the following to the subclass:

setAttribute(Qt::WA_LayoutUsesWidgetRect);

Apparently it is only necessary on the Mac platform; Windows and Linux display the layout as expected.

Dave