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