啦啦啦,终于测试成功啦,由事件过滤器结合move函数制作的可移动窗口。

鼠标可以在指定区域内拖动button。

 

Dumpt.com

 

使用move()函数就可以实现位置的移动啦,再加上Geometry获取本部件在全窗口的坐标。

 

 main.cpp

  1. #include <QtGui/QApplication>  
  2. #include <QTextCodec>  
  3. #include "widget.h"  
  4.  
  5.  
  6. int main(int argc, char *argv[])  
  7. {  
  8.  
  9.     QApplication a(argc, argv);  
  10.  
  11.     QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));  
  12.     QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));  
  13.  
  14.     Widget * widget = new Widget();  
  15.     widget -> show();  
  16.  
  17.     int result = a.exec();  
  18.  
  19.     delete widget;  
  20.     return result;  
  21. }  

 

  1. //头文件 widget.h  
  2.  
  3. #ifndef WIDGET_H  
  4. #define WIDGET_H  
  5.  
  6.  
  7. #include <QtGui/QWidget>  
  8. #include <QPushButton>  
  9. #include <QMouseEvent>  
  10. #include <QEvent>  
  11.  
  12.  
  13. class Widget : public QWidget  
  14. {  
  15.     Q_OBJECT  
  16.  
  17. public:  
  18.     Widget(QWidget *parent = 0);  
  19.     ~Widget();  
  20.  
  21. protected slots:  
  22.     bool eventFilter(QObject *, QEvent *);  
  23.     void mousePressEvent ( QMouseEvent * event ) ;  
  24.  
  25. private:  
  26.     QPushButton* button;  
  27.     QPoint lastPnt;          // 记录鼠标点击时候的位置  
  28.     bool hasPress;  
  29. };  
  30. #endif // WIDGET_H  

 

  1. //源文件 widget.cpp  
  2.  
  3. #include <QDebug>  
  4. #include <qmath.h>  
  5. #include "widget.h"  
  6.  
  7.  
  8. Widget::Widget(QWidget *parent): QWidget(parent)  
  9. {  
  10.     this -> resize(600, 300);  
  11.     hasPress = false;  
  12.     lastPnt = QPoint(0, 0);  
  13.  
  14.     // 初始化button并设置button的大小和位置。  
  15.     button = new QPushButton(" Move In Widget Range ",this);  
  16.     button -> resize(200, 50);  
  17.     button -> setGeometry((width()-button->width())/2, (height()-button->height())/2,  
  18.                           button->width(), button->height());  
  19.  
  20.     //安装事件过滤器  
  21.     button -> installEventFilter(this);  
  22.  
  23.     // 如果有多个部件,事件发生后,需要按钮置于最上方,可用raise()函数  
  24. }  
  25.  
  26. Widget::~Widget()  
  27. {  
  28.     delete button;  
  29. }  
  30.  
  31.  
  32. //事件过滤器定义  
  33. bool Widget::eventFilter(QObject * b, QEvent *evt)  
  34. {  
  35.     if(b == button && evt->type() == QEvent::MouseButtonPress)  // 按下鼠标左键  
  36.     {  
  37.         QMouseEvent* e = static_cast<QMouseEvent*>(evt);  
  38.         if(e->button() == Qt::LeftButton){  //鼠标左键点击  
  39.             lastPnt = e -> pos();  
  40.             hasPress = true;  
  41.          }  
  42.     }else if(button == b && evt->type() == QEvent::MouseMove && hasPress)  
  43.     {  
  44.         QMouseEvent* e = static_cast<QMouseEvent*>(evt);  
  45.         // 计算新的移动后的位置  
  46.         QPoint movePoint = e->pos()-lastPnt + QPoint(button->geometry().x(), button->geometry().y());  
  47.         // 设置可移动的X和Y的范围  
  48.         bool moveX = movePoint.x() > 0 && movePoint.x() < width() - button -> width();  
  49.         bool moveY = movePoint.y() > 0 &&  movePoint.y() < height() - button -> height();  
  50.         if(moveX && moveY){ // 在X和Y的允许范围内  
  51.             button -> move(movePoint);  
  52.         }else if(moveX){   // 在X的允许范围内  
  53.             button -> move(movePoint.x(), button -> pos().y());  
  54.         }else if(moveY){    // 在Y的允许范围内  
  55.             button -> move(button->pos().x(), movePoint.y());  
  56.         }else{  
  57.             // do nothing  
  58.         }  
  59.     }else if(evt->type() == QEvent::MouseButtonRelease && hasPress)  
  60.     {  
  61.         hasPress = false;  
  62.     }  
  63.     return false;  
  64. }  
  65.  
  66.  
  67.  
  68. void Widget::mousePressEvent ( QMouseEvent * )  
  69. {  
  70.     qDebug() << "Widget Mouse Press Event";  
  71.     return;  
  72. }