Se você quiser criar um estilo personalizado para suas aplicações, o primeiro passo é escolher um dos estilos fornecidos junto com a biblioteca Qt para a partir dele criar seu estilo personalizado. Sua escolha dependerá de qual estilo mais de assemelha ao estilo que você quiser criar. A classe mais genérica que você pode usar como base é QCommonStyle.
Dependendo de qual partes do estilo base você quer alterar, você precisa reimplementar as funções que desenham cada parte da interface. para ilustrar isso, nós modificaremos a aparência da seta da spinbox, que é desenhada pela classe QWindowsStyle. A seta é um elemento primitivo que é desenhado pela função drawPrimitive(), então nós iremos reimplementar essa função. Nós precisaremos da seguinte declaração de classe:
class CustomStyle : public QWindowsStyle { Q_OBJECT public: CustomStyle() ~CustomStyle() {} void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; };
Para desenhar as setas para cima e para baixo, o QSpinBox usa os elementos PE_IndicatorSpinUp and PE_IndicatorSpinDown. Abaixo está a reimplementação da função que faz o novo desenho do elemento:
void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) { QPolygon points(3); int x = option->rect.x(); int y = option->rect.y(); int w = option->rect.width() / 2; int h = option->rect.height() / 2; x += (option->rect.width() - w) / 2; y += (option->rect.height() - h) / 2; if (element == PE_IndicatorSpinUp) { points[0] = QPoint(x, y + h); points[1] = QPoint(x + w, y + h); points[2] = QPoint(x + w / 2, y); } else { // PE_SpinBoxDown points[0] = QPoint(x, y); points[1] = QPoint(x + w, y); points[2] = QPoint(x + w / 2, y + h); } if (option->state & State_Enabled) { painter->setPen(option->palette.mid().color()); painter->setBrush(option->palette.buttonText()); } else { painter->setPen(option->palette.buttonText().color()); painter->setBrush(option->palette.mid()); } painter->drawPolygon(points); } else { QWindowsStyle::drawPrimitive(element, option, painter, widget); } }
Observe que nós não usamos o argumento widget, exceto para chamar a função QWindowStyle::drawPrimitive(). Como mencionado antes, a informação sobre o que será desenhado e como deve ser desenhado é especificado por um objeto QStyleOption, então não há necessidade de chamar p widget.
Se você precisar usar o argumento widget para obter informações adicionais, tome o cuidado de se garantir que o tipo correto está sendo usado. Por exemplo:
QSpinBox *spinBox = qobject_cast<QSpinBox *>(widget); if (spinBox) { ... }
Quando for implementar um estilo personalizado, você não pode assumir que o widget é um QSpinBox somente pelo fato de que o valor do enum é PE_IndicatorSpinUp or PE_IndicatorSpinDown.
A documentação dos exemplos de Estilos cobrem esse tópico com mais detalhes.
Traduzido de http://doc.trolltech.com/4.4/qstyle.html#creating-a-custom-style