Create capsule-style toolbar controls in Qt
What is the best way to render capsule-style toolbar controls (including the label text below the buttons) in a Qt application?
As far as rendering the buttons, I want to tap into what is provided by Mac OS as much as possible. (I'm not a Mac developer, so do not know if it has an API for this.) That is, I know I can draw them myself, use style sheets for border-image, guess on the font, and set it all up in a layout, but is there a better way that ensures consistent presentation when Mac updates her "look and feel?" I am usi开发者_StackOverflowng C++ in Qt.
I don't hate the idea of using Q_WS_MAC to get the platform-specific rendering, but does Qt already have anything for this? You know, a setCapsuleStyle(true)
method somewhere? :)
Thanks for any suggestions.
There is a segmented button example in the qt-labs repository that looks decent on KDE. It has a fair amount of #ifdef Q_WS_MAC
code, but I don't know how well it renders on Mac. You can find it here.
If you are specifically targeting only Mac, you may use the QMacCocoaViewContainer to render native segmented buttons. Its learning curve is quite steep, so you may find this Qt Labs Blog post about Mac widget interesting: Mac widget style addons. The author provides three Mac-style widgets: QtCocoaPushButton, QtCocoaComboBox and QtCocoaSegmentedButton.
As Qt doesn't provide this type of widget by itself, the best way would be subclassing QPushButton and reimplementing paintEvent
. You can then draw your capsule pixmap by simply painting a QPixmap that contains a screenshot of the capsule button. You can add click behaviour by reimplementing mousePressEvent
and mouseReleaseEvent
.
// CapsuleButton.h
class CapsuleButton : public QPushPutton {
// ...
protected:
void paintEvent(QPaintEvent*);
void mousePressEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
// ...
private:
QPixmap pixmap_;
QPixmap pressedPixmap_;
bool pressed_;
};
// CapsuleButton.cpp
CapsuleButton::CapsuleButton(QObject* parent) :
QPushButton(parent),
pixmap_(":/capsule-button-background.png"),
pressedPixmap_(":/capsule-button-background-pressed.png"),
pressed_(false)
{ /*...*/ }
void CapsuleButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawPixmap(rect(), pressed_? pressedPixmap_ : pixmap_);
}
void CapsuleButton::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton)
pressed_ = true;
update();
}
void CapsuleButton::mouseReleaseEvent(QMouseEvent*)
{
pressed_ = false;
update();
}
I have writte a short tutorial on how to create custom widgets: http://www.serenethinking.com/2010/08/how-to-create-custom-widgets-with-qt/
Maybe that helps.
I have done similar stuff in past. Unfortunately I don't have its source code with me to share with you. However most safest bet is to use Qt Style sheets. They support various properties, pseudo-states, and subcontrols that make it possible to customize the look to any extend.
精彩评论