zoukankan      html  css  js  c++  java
  • 36.QT-解决无边框界面拖动卡屏问题(附带源码)

    1.简介

    • 看到很多才学QT的人都会问为啥无边框拖动为啥会花屏?

    那是因为你每次拖动的过程中都一直在调用move()函数让QT重新绘制界面,如果资源过大,就会导致当前图形还未绘制完,便又重新改变坐标了,从而导致花屏.


    2.如何解决
    我们参考其它软件,比如QQ,浏览器等,可以看到我们如果在拖动它们的时候,会出现一个虚线框.

    • 如下图所示,可以看到在白色背景下,拖出的虚线框是黑色的

    • 而在黑色背景时,拖出的虚线框是白色的

    显然这个虚线框会根据当前桌面的像素点而去取反(也就是255-currentRGB).
    解决的过程有两种方法:

    • 1) 调用win库来实现
    • 2) 自己动手写一个

    既然我们已经知道它的实现过程.那我们还是自己动手写一个,只需要写一个虚线框类即可

    3.虚线框类代码
    DragShadow.h

    #ifndef DRAGSHADOW_H
    #define DRAGSHADOW_H
    #include <QtGui>
    class DragShadow : public QWidget
    {
      Q_OBJECT
    private:
      QImage m_image;
    protected:
      bool getInvertColor(int x, int y, QColor &color);
      void paintEvent(QPaintEvent *);
      void showEvent( QShowEvent * event );
    public:
      explicit DragShadow(QWidget *parent = 0);
      void setSizePos(int x, int y, int w, int h);
      void setPos(int x,int y );
      void setPos(QPoint pos );
    signals:
    
    public slots:
    
    };
    #endif // DRAGSHADOW_H

    DragShadow.cpp

    #include "DragShadow.h"
    
    DragShadow::DragShadow(QWidget
    *parent) : QWidget(NULL) {   setWindowFlags(Qt::FramelessWindowHint|Qt::Tool);   setAttribute(Qt::WA_TranslucentBackground); }
    void DragShadow::setSizePos(int x, int y, int w, int h) {   if(w%2==0)     w+=1;   if(h%2==0)     h+=1;   this->setGeometry(x,y,w,h); }
    void DragShadow::setPos(int x,int y ) {   this->move(x,y);   this->update(); }
    void DragShadow::setPos(QPoint pos ) {   this->move(pos);   this->update(); }
    void DragShadow::showEvent( QShowEvent * event ) {

       #if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
            m_image = QPixmap::grabWindow(QApplication::desktop()->winId()).toImage();
       #else
            QScreen *screen = QGuiApplication::primaryScreen();
            m_image = screen->grabWindow(0).toImage();
       #endif

    }
    void DragShadow::paintEvent(QPaintEvent *) {   int LineCount=4;   QColor color;   QPainter painter(this);   painter.setBrush(Qt::NoBrush);   QPen pen(Qt::SolidLine);   pen.setColor(Qt::black);   pen.setWidthF(1);   painter.setPen(pen);   painter.drawPoint(0,0);

      
    for(int current=0;current<LineCount;current++)   {     for(int i=current;i<(this->width()-current);i+=2) //x     {       this->getInvertColor(this->x()+i,this->y()+current,color);       pen.setColor(color);       painter.setPen(pen);       painter.drawPoint(i,current);            //draw top       this->getInvertColor(i+this->x(),this->height()-current-1+this->y(),color);       pen.setColor(color);       painter.setPen(pen);       painter.drawPoint(i,this->height()-current-1); //draw bottom     }     for(int i=current;i<(this->height()-current);i+=2) //y     {       this->getInvertColor(current+this->x(),i+this->y(),color);       pen.setColor(color);       painter.setPen(pen);       painter.drawPoint(current,i);           //draw left       this->getInvertColor(this->width()-current-1+this->x(),i+this->y(),color);       pen.setColor(color);       painter.setPen(pen);       painter.drawPoint(this->width()-current-1,i); //draw right     }   } }
    bool DragShadow::getInvertColor(int x, int y, QColor &color) {   int ret=m_image.valid(x,y);   if(ret)   {     QRgb rgb = m_image.pixel(x,y);     color.setRgb(rgb);     color.setRed(255-color.red());     color.setBlue(255-color.blue());     color.setGreen(255-color.green());   }   else   {     color.setRed(0);     color.setBlue(0);     color.setGreen(0);   }   return ret; }

    4.测试UI界面如下图所示

    5.拖动时的效果图如下所示

    6.针对实线框补充
    对于有些不同的windows系统设置,实现的是实线框,如下图所示:

    如果想要这种效果,就将上面代码的paintEvent(QPaintEvent *)函数的i+=2改为i++即可.

    修改后效果如下所示:

     

    上面的两个不同效果的demo源码地址如下所示:

     https://download.csdn.net/download/qq_37997682/10955602

  • 相关阅读:
    20130912对象生命周期基础
    ASP.Net 提交表单 post 方式代码
    Design Service Develop Created new Field(1)
    asp.net 调用存储过程(带有输入,输出参数 ,思路)二
    工作流概述
    asp.net 调用存储过程(带有输入,输出参数 范例)二
    如何配置服务器上面的Excel组件访问权限
    C# 模拟网站登陆
    NPOI创建DOCX常用操作
    SQL CPU高排查
  • 原文地址:https://www.cnblogs.com/lifexy/p/10370105.html
Copyright © 2011-2022 走看看