QTimer
的一般性使用
QTimer *timer = new QTimer( myObject );
connect( timer, SIGNAL(timeout()),
myObject, SLOT(timerDone()) );
timer->start( 2000, TRUE ); // 2 seconds single-shot
注意: 1 当myObject销毁时,Qtimer会自动销毁。不需要手工删除。
2
QTimer
的
int start ( int msec, bool sshot = FALSE )
方法第二个参数sshot如果
为ture,则myObject的槽方法只会执行一次。不然的话会一直执行直到QTimer停止或者对象被销毁为止。
|
//
头文件
class MainPanel : public QWidget { // MainPanel
为被测试面板,测试弹出属性框
Q_OBJECT
public:
MainPanel(QWidget *parent=0, const char *name=0, WFlags fl = 0);
~MainPanel() {}
public slots:
void holdMouseToPopupDialog(); //
供
QTimer
链接的槽,确定是否弹出属性框
protected:
virtual void mousePressEvent ( QMouseEvent * ); //
这三个虚函数需要被覆盖用作计时
virtual void mouseReleaseEvent(QMouseEvent *);
virtual void mouseMoveEvent(QMouseEvent *);
private:
QPoint* __popupPoint; //
弹出面板的坐标,也就是要显示属性的物体
PopupInfoDialog* __propDialog;
//
这个属性框的制作放到后面
QTimer* __mouseHoldClicker; //
创建一个
Qtimer
类成员对象
};
|
//
代码文件
MainPanel::MainPanel(QWidget *parent, const char *name, WFlags fl) :QWidget(parent, name, fl) {
__propDialog = new PopupInfoDialog(720,480,this,0,0,QDialog::WStyle_Customize | QDialog::WStyle_NoBorder | QDialog::WStyle_StaysOnTop);
__mouseHoldClicker = new QTimer(this);
__popupPoint = new QPoint(); //
创建一个默认弹出点
connect(__mouseHoldClicker, SIGNAL(timeout()), this, SLOT(holdMouseToPopupDialog())); //
链接
QTimer
和面板
}
void MainPanel::mousePressEvent(QMouseEvent * e) { //
这个方法的意思是如果当鼠标按下(触摸屏的话就是手指按下)
__popupPoint->setX(e->x()); //
保存当前的坐标点
__popupPoint->setY(e->y());
__propDialog->hide(); //
隐藏以前出现的弹出式属性框
__mouseHoldClicker->start(500, true); //
以
0.5
秒计时,如果手指没有离开这个点,或者没有移动,则
//
触发
holdMouseToPopupDialog()
槽一次。
}
void MainPanel::mouseReleaseEvent(QMouseEvent * e) { //
这个方法的意思是如果手指离开触摸屏,就。。。
__mouseHoldClicker->stop(); //
如果在槽还没有触发前就停止计时器,这样不用弹出属性框了
}
void MainPanel::mouseMoveEvent(QMouseEvent * e) { //
这个方法的意思是如果手指移动了的话,就。。。。。。。。
if (e->x()-__popupPoint->x()>5 || e->y()- __popupPoint->y()>5) { //
如果手指在
5
个像素内移动,就认为可接受的,如果超过
5
个
__mouseHoldClicker->stop(); //
像素,则不予弹出对话框
}
}
void MainPanel::holdMouseToPopupDialog() { //
测试面板的槽,用来弹出属性框
__propDialog->popupAtPoint(__popupPoint->x(), __popupPoint->y());
__propDialog->show();
}
|
class PopupInfoDialog : public QDialog {
Q_OBJECT
public:
PopupInfoDialog (int areaWidth = 800 ,int areaHeight = 600,QWidget * parent=0, const char * name=0, bool modal=FALSE, WFlags f=0 );
void popupAtPoint(int x,int y);
private:
void __refreshMask(int popX, int popY); //
重新刷新蒙板,隐藏对话框该的一些不需要显示的地方。
void __fillArrow(QPainter&,int,int,int,int,int,int); //
这个是画这个东东的
---
à
|
void PopupInfoDialog::popupAtPoint(int x, int y) { //
对话框就弹出在这个点,在测试面板的
//holdMouseToPopupDialog()
中调用此方法。
this->__refreshMask(x, y);
this->show();
}
/*
在这里,大致的实现过程是这样,
QWidget
可以通过一个
QBitmap
蒙板来大致决定需要显示哪些部分,我们就通过绘制蒙板来让
QWidget
显示蒙板同样大小区域来实现绘制任意形状的对话框的效果
*/
void PopupInfoDialog::__refreshMask(int popX, int popY) { //
重新刷新蒙板
QBitmap mask(__PopupWidth, __PopupHeight, true); //
创建一个蒙板
QPainter painter(&mask);
painter.setPen(popupBorder);
painter.setBrush(blackBrush); //
必须设置笔刷,得把绘制区域全部填充满
painter.drawRoundRect(50, 0, 300, 300, 10, 10);//300
是实际显示内容框,
10
为圆角矩形圆角半径
int distanceToBorder;
if (__areaWidth-popX >= __PopupWidth-50) {//
右边能容纳弹出框
//
这是一个简单的算法,在对象右边能显示对话框就在右边
if (popY <= __areaHeight/2) {//
三角符号在弹出框的上边
//
绘制属性对话框,不然就在左边绘制属性对话框。
if (popY <= __DialogToBorderDistance) {
distanceToBorder = popY;
} else {
distanceToBorder = __DialogToBorderDistance;
}
__fillArrow(painter, 0, popY-distanceToBorder+20, 50, 100-20, 50, 100+20);
this->move(popX, distanceToBorder);
} else {//
三角符号在弹出框的下边
int dx = popX;
int dy = __areaHeight-__PopupHeight-__DialogToBorderDistance;
if ((__areaHeight - popY) <= __DialogToBorderDistance) {
dy = __areaHeight-__PopupHeight-(__areaHeight - popY)+20;
}
__fillArrow(painter, 0, popY-(dy-20), 50, 200-20, 50, 200+20);
this->move(dx, dy);
}
} else {//
弹出框放在左边
if (popY <= __areaHeight/2) {//
三角符号在弹出框的上边
if (popY <= __DialogToBorderDistance) {
distanceToBorder = popY;
} else {
distanceToBorder = __DialogToBorderDistance;
}
__fillArrow(painter, __PopupWidth, popY-distanceToBorder+20, __PopupWidth-51, 100-20, __PopupWidth-51,
100+20);
this->move(popX-__PopupWidth, distanceToBorder);
} else {//
三角符号在弹出框的下边
int dx = popX-__PopupWidth;
int dy = __areaHeight-__PopupHeight-__DialogToBorderDistance;
if ((__areaHeight - popY) <= __DialogToBorderDistance) {
dy = __areaHeight-__PopupHeight-(__areaHeight - popY)+20;
}
__fillArrow(painter, __PopupWidth, popY-dy+20, __PopupWidth-51, 200-20, __PopupWidth-51, 200+20);
this->move(dx, dy);
}
}
this->clearMask(); //
清除原来的蒙板效果
this->setMask(mask); //
添加新的蒙板效果
}
/*
这个方法通过在给定的三点绘制多边形,达到绘制属性框箭头的效果
*/
void PopupInfoDialog::__fillArrow(QPainter& painter, int p1x, int p1y, int p2x, int p2y, int p3x, int p3y) {
QPointArray points;
points.setPoints(3, p1x, p1y, p2x, p2y, p3x, p3y);
painter.drawPolygon(points);
}
|