常規的組合方向鍵或者功能鍵大多是四四方方、中規中矩的。在編程方面也沒有太多值挖掘的地方。而對於不規則的按鍵組合來說,卻是可以讓我們類比出諸如控制台、不規則鍵盤這樣的布局與效果。下面是常規鍵與不規則鍵的比較圖,如果你對不規則群組合方向鍵或者功能鍵感興趣的話,可以試著慢慢往下讀。
(2009.12.24記)很抱歉上次發表這篇blog的時候圖片一直粘不上,本想過幾天來補充完整,但忙起來就忘了。
對於規則的和不規則的按鈕,我覺得有這麼幾個區別:
1.規則的按鈕通常用QPushButton或者QToolButton這些原生態的Qt類就可以搞定
2.不規則的按鈕通常用衍生的類,從繪圖的角度說,目前我有兩種方法:
a.與不規則視窗類別似,用圖片輪廓的掩碼(mask)載入實現
b.用svg格式的圖片,通過QSvgRenderer實現
就效果而言,推薦使用svg格式的圖片。比如你想用到按鈕大小縮放、overlay效果
3.對於布局(layout)而言:規則按鈕布局簡單。不規則按鈕布局稍微複雜點,特別是第一次使用時,經常會因為映像剪下不合理或者布局中margin等設定不合理,造成按鈕布局混亂的情況。下面的布局對應面板裡--上下左右按鈕及中間旋轉按鈕--的不規則按鈕組合
4.對於高層次(按鈕之上)的布局而言,實質上規則與不規則等效。不同的只是顯示地區與相應地區。
下面給出部分實現代碼:
/********************************************
用QSvgrenderer實現的不規則按鈕類,繼承自QAbstractButton
*******************************************/
class NavigationButton : public QAbstractButton
{
public:
NavigationButton(QWidget* parent) : QAbstractButton(parent)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_normal = new QSvgRenderer(this);
m_pressed = new QSvgRenderer(this);
m_hovered = new QSvgRenderer(this);
}
virtual ~NavigationButton() {}
void setSkin(const QString& name)
{
const QString base = ":/src/" + name;
m_normal->load(base + ".svg");
m_pressed->load(base + "_pressed.svg");
m_hovered->load(base + "_hover.svg");
}
void paint(QPainter* painter)
{
if (isDown() || isChecked()) {
m_pressed->render(painter, geometry());
} else if (underMouse()) {
m_hovered->render(painter, geometry());
} else {
m_normal->render(painter, geometry());
}
}
void updateMask()
{
QPixmap pixmap(size());
pixmap.fill();
QPainter painter(&pixmap);
m_normal->render(&painter, rect());
painter.end();
QBitmap bitmap = pixmap.createHeuristicMask();
setMask(bitmap);
update();
}
protected:
// Implemented to sacrifice pure virtual
virtual void paintEvent(QPaintEvent*) {}
virtual void enterEvent(QEvent*)
{
parentWidget()->update();
}
virtual void leaveEvent(QEvent * event)
{
Q_UNUSED(event);
parentWidget()->update();
}
private:
QSvgRenderer *m_normal;
QSvgRenderer *m_pressed;
QSvgRenderer *m_hovered;
};