常规的组合方向键或者功能键大多是四四方方、中规中矩的。在编程方面也没有太多值挖掘的地方。而对于不规则的组合键来说,却是可以让我们模拟出诸如控制台、不规则键盘这样的布局与效果。下面是常规键与不规则键的比较图,如果你对不规则组合方向键或者功能键感兴趣的话,可以试着慢慢往下读。
(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;
};