Shape Analog Clock example
1.
Qt::FramelessWindowHint可以使窗口去掉关闭 最大化 最小化等,但是需要重新自定义move等事件
该flag在Qt里介绍:
Produces a borderless window. The user cannot move or resize a borderless window via the window system
在这个例子里于是我们需要自定义mouseMoveEvent,mousePressEvent,原文如下:
We inform the window manager that the widget is not to be decorated with a window frame by setting the Qt::FramelessWindowHint flag on the widget. As a result, we need to provide a way for the user to move the clock around the screen.
该例子实现后可以在桌面上拖动一个类似于表的widget,同时没有边框,很美观,那么定义mouseMoveEvent()时,我们如何确定该widget应当move到什么地方呢?
例子里定一个一个private data :
QPoint dragPosition;
在mousePressEvent里
dragPosition = event->globalPos() - frameGeometry().topLeft();
在mouseMoveEvent里
move(event->globalPos() - dragPosition);
即把鼠标按下时的位置与控件左上的坐标距离作为一个偏移量

原文介绍如下:
If the left mouse button is pressed over the widget, we record the displacement in global (screen) coordinates between the top-left position of the widget's frame (even when hidden) and the point where the mouse click occurred. This displacement will be used if the user moves the mouse while holding down the left button. Since we acted on the event, we accept it by calling its accept() function.
注意这里时globalPos()~~
2.sizeHint()
刚开始没有弄懂为什么要定义sizeHint()
去掉后对比下图像发现图大了不少,才明白在图像未指定大小时第一次show的时候会自动调用sizeHint()
例子中说明如下
Finally, we implement the sizeHint() for the widget so that it is given a reasonable default size when it is first shown:
去掉sizeHint函数的
用了sizeHint的就比较美观了
3.mask
那么如何是窗口呈现为一个圆形的呢?
其实窗口还是矩形的,不过通过mask设为一部分可见,一部分透明了
setMask有两种形式,不过作用都是类似的
void QWidget::setMask ( const QBitmap & bitmap )
Causes only the pixels of the widget for which bitmap has a corresponding 1 bit to be visible
void QWidget::setMask ( const QRegion & region )
Causes only the parts of the widget which overlap region to be visible.
即是区域内可见,其余不可见。
另外一个关于透明性的函数为
void setWindowOpacity ( qreal level )
windowOpacity : double
This property holds the level of opacity for the window.
The valid range of opacity is from 1.0 (completely opaque) to 0.0 (completely transparent).
该函数控制的是整个widget的透明性~
如果setMask()与setWindowOpacity()一起用了,QREgion外仍是透明的,不过mask的区域透明度因为setWindowOpacity()改变了。
这是我用了该函数之后的例子
 可以看到变得透明了
这张图对比就更明显了
4.如何按下鼠标右键弹出Action的?
直接new一个QAction出来然后add就行了~~
估计是因为在这种widget下没有其他地方放就默认放在右键里了,需要进一步学习才能确定~~