QT:窗口最小化时显示一个小浮标


有些窗口在自身最小化时要在桌面上显示一个小浮标,让用户利用这个小浮标进行各种操作(例如迅雷的悬浮窗一样),我试着用QT实现一下这个功能。

PS:本来以为这个功能很简单,却搞了我两个晚上,泪奔。。。

思路:

1:制作一个由一个小图标组成的,可点击,可拖动,背景透明的Widget

2:重载主窗口(在此例子中是QLabel)的changeEvent(详情见代码)

截图:(浅绿色的部分是桌面背景)

主窗体:

小浮标:

代码:

  1. #include <QtGui>   
  2. #include <Windows.h>   
  3.   
  4. //   
  5. class MinIconWidget : public QWidget      
  6. {      
  7.     Q_OBJECT      
  8. private:      
  9.     QPoint m_CurrentPos;      
  10.     QPixmap m_Pixmap;         
  11. protected:      
  12.     void mousePressEvent(QMouseEvent *event);      
  13.     void mouseMoveEvent(QMouseEvent *event);      
  14.     void paintEvent(QPaintEvent *event);      
  15.     void enterEvent(QEvent *event);      
  16.     void leaveEvent(QEvent *event);  
  17.     void mouseDoubleClickEvent(QMouseEvent *event);  
  18. public:      
  19.     MinIconWidget(QWidget *parent = 0);    
  20.     void SetPixmap(const QPixmap &pixmap);  
  21. signals:  
  22.     void DoubleClickedSignal();  
  23. };  
  24.   
  25. MinIconWidget::MinIconWidget(QWidget *parent)      
  26. : QWidget(parent)      
  27. {      
  28.     //将浮标Widget设置为:顶层窗口;无标题栏;工具条模式;背景透明;无输入焦点   
  29.     setWindowFlags( Qt::FramelessWindowHint   
  30.         | Qt::WindowStaysOnTopHint | Qt::Tool );         
  31.     setAttribute(Qt::WA_TranslucentBackground, true);  
  32.     setFocusPolicy(Qt::NoFocus);  
  33. }      
  34.   
  35. void MinIconWidget::mousePressEvent(QMouseEvent *event)      
  36. {      
  37.     //按住左键移动可以拖动窗口       
  38.     if(event->button() == Qt::LeftButton)      
  39.     {  
  40.         m_CurrentPos = event->globalPos() - frameGeometry().topLeft();      
  41.         event->accept();      
  42.     }         
  43. }      
  44.   
  45. void MinIconWidget::mouseMoveEvent(QMouseEvent *event)      
  46. {      
  47.     if (event->buttons() && Qt::LeftButton)      
  48.     {      
  49.         move(event->globalPos() - m_CurrentPos);      
  50.         event->accept();      
  51.     }      
  52. }      
  53.   
  54. void MinIconWidget::paintEvent(QPaintEvent *event)      
  55. {      
  56.     QPainter painter(this);      
  57.     painter.drawPixmap(0, 0, m_Pixmap);      
  58. }      
  59.   
  60. void MinIconWidget::leaveEvent(QEvent *event)      
  61. {      
  62.     //鼠标离开窗口时是普通的指针       
  63.     setCursor(Qt::ArrowCursor);      
  64. }      
  65.   
  66. void MinIconWidget::enterEvent(QEvent *event)      
  67. {      
  68.     //鼠标留在窗口上时是一个手指       
  69.     setCursor(Qt::PointingHandCursor);      
  70. }      
  71.   
  72. void MinIconWidget::mouseDoubleClickEvent(QMouseEvent *event)  
  73. {  
  74.     emit DoubleClickedSignal();  
  75. }  
  76.   
  77. void MinIconWidget::SetPixmap(const QPixmap &pixmap)  
  78. {  
  79.     m_Pixmap = pixmap;  
  80.     update();  
  81. }  
  82.   
  83.   
  84. class MyLabel : public QLabel  
  85. {  
  86.     Q_OBJECT  
  87. private:  
  88.     MinIconWidget *m_minIcon;  
  89. protected:  
  90.     void changeEvent(QEvent *event);  
  91. public:  
  92.     MyLabel(QWidget *parent = 0);  
  93.     public slots:  
  94.         void ShowMainWindow();  
  95.         void HideMainWindow();  
  96. };   
  97.   
  98. MyLabel::MyLabel(QWidget *parent /* = 0 */)  
  99. : QLabel(parent)  
  100. {  
  101.   
  102.     m_minIcon = new MinIconWidget;  
  103.     m_minIcon->SetPixmap( QPixmap("delete.png") );  
  104.     setWindowFlags( Qt::WindowStaysOnTopHint );  
  105.     //双击浮动时,隐藏浮标,还原主窗口(这里是一个LABEL)   
  106.     connect(m_minIcon, SIGNAL(DoubleClickedSignal()), this, SLOT(ShowMainWindow()));  
  107. }  
  108.   
  109. void MyLabel::changeEvent(QEvent *event)  
  110. {  
  111.     //重点,窗口最小化时最小化窗口(废话),显示浮标   
  112.     //窗口还原时,隐藏浮标,还原主窗口(这里是一个LABEL)   
  113.     if(event->type()==QEvent::WindowStateChange)  
  114.     {  
  115.         //changeEvent会在窗口最小化之前调用,如果不加QTimer,   
  116.         //我们把窗口隐藏了,但是Qt还以为窗口正要最小化,这样就会出错   
  117.         if(windowState() & Qt::WindowMinimized)  
  118.             QTimer::singleShot(0, this, SLOT(HideMainWindow()));  
  119.         else if(windowState() & Qt::WindowNoState)  
  120.             QTimer::singleShot(0, this, SLOT(ShowMainWindow()));  
  121.     }  
  122.     QLabel::changeEvent(event);  
  123. }  
  124.   
  125. void MyLabel::ShowMainWindow()  
  126. {  
  127.     m_minIcon->hide();  
  128.     move( m_minIcon->pos() );  
  129.     show();  
  130.     setWindowState(Qt::WindowNoState);  
  131. }  
  132.   
  133. void MyLabel::HideMainWindow()  
  134. {  
  135.     hide();  
  136.     m_minIcon->move( pos() );  
  137.     m_minIcon->show();  
  138.     setWindowState(Qt::WindowMinimized);  
  139. }  
  140.   
  141.   
  142. #include "main.moc"   
  143.   
  144. int main(int argc, char **argv)  
  145. {  
  146.     QApplication app(argc, argv);  
  147.     MyLabel label;  
  148.     label.setStyleSheet("QLabel{font-size:30px;color:red;}");  
  149.     label.resize(400, 200);  
  150.     label.setText("This is a simple demo.");  
  151.     label.show();  
  152.     return app.exec();  
  153. }  

相关内容