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 = );
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%==)
w+=;
if(h%==)
h+=;
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=;
QColor color;
QPainter painter(this);
painter.setBrush(Qt::NoBrush);
QPen pen(Qt::SolidLine);
pen.setColor(Qt::black);
pen.setWidthF();
painter.setPen(pen);
painter.drawPoint(,); for(int current=;current<LineCount;current++)
{
for(int i=current;i<(this->width()-current);i+=) //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-+this->y(),color);
pen.setColor(color);
painter.setPen(pen);
painter.drawPoint(i,this->height()-current-); //draw bottom
}
for(int i=current;i<(this->height()-current);i+=) //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-+this->x(),i+this->y(),color);
pen.setColor(color);
painter.setPen(pen);
painter.drawPoint(this->width()-current-,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(-color.red());
color.setBlue(-color.blue());
color.setGreen(-color.green());
}
else
{
color.setRed();
color.setBlue();
color.setGreen();
}
return ret;
}
4.测试UI界面如下图所示
5.拖动时的效果图如下所示
6.针对实线框补充
对于有些不同的windows系统设置,实现的是实线框,如下图所示:
如果想要这种效果,就将上面代码的paintEvent(QPaintEvent *)函数的i+=2改为i++即可.
修改后效果如下所示:
上面的两个不同效果的demo源码地址如下所示:
https://download.csdn.net/download/qq_37997682/10955602
36.QT-解决无边框界面拖动卡屏问题(附带源码)的更多相关文章
- Qt——透明无边框Widget的bug
Experience 最近在封装一些类的时候,打算做一个窗口框架,能实现拖动.缩放.最大最小化.基本样式等功能,可不慎遇见一件无比蛋疼的事情,QWidget最小化后再恢复正常界面,最小化按钮居然仍处于 ...
- WPF 解决无边框产生的相关问题
原文:WPF 解决无边框产生的相关问题 最大化: 在设置WindowStyle="None" AllowsTransparency="True"后,最大化会覆盖 ...
- qt 5 小练习 创建无边框界面
我们大家都知道QT5 自带的界面不是那么美观,并且每个软件我们都发现他们的边框是自定义的,所以我决定写一篇这样的博文,也许已经有许许多多篇大牛写的论文了,但我还是想写一篇记录自己的学习QT的历程 首先 ...
- 让Qt的无边框窗口支持拖拽、Aero Snap、窗口阴影等特性
环境:Desktop Qt 5.4.1 MSVC2013 32bit 需要的库:dwmapi.lib .user32.lib 需要头文件:<dwmapi.h> .<windowsx. ...
- Qt5:无边框窗口拖动
在窗口程序中,无边框窗口程序一般需要特殊处理才能拖动 Qt中,要实现无边框窗口的拖动,需要重新实现 mousePressEvent 和 mouseMoveEvent 俩虚函数 void Widget: ...
- winform无边框窗口拖动
无边框的窗口想拖动,只需要在置顶的容器上添加对应的mousedown 和 mousemove 事件就可以实现了.代码如下: //拖动窗口 private Point mPoint = new Poin ...
- Delphi无边框Form拖动
用Delphi做登陆窗口,如果使用无边框Form,想要拖动窗口,可以在某个控件的OnMouseDown事件中写下以下代码 ReleaseCapture; Perform(WM_SYSCOMMAND, ...
- WPF无边框可拖动窗体
下面主要记录下创建无边框窗体,并且可以拖动.这种窗体主要用于弹出小窗体时. <Window x:Class="WpfApplication1.MainWindow" xmln ...
- C#中无边框窗体拖动
//定义一个bool变量标识是否拖动窗体 private bool isMove = false; //记录鼠标的位置 private Point point; 定义的变量 /// <summa ...
随机推荐
- ggplot2 aes函数map到data笔记
.all_aesthetics <- c("adj", "alpha", "angle", "bg", " ...
- Python爬虫第二天
Python爬虫第二天 超时设置 有时候访问网页时长时间未响应,系统就会判断网页超时,无法打开网页.如果需要自己设置超时时间则: 通过urlopen()打开 ...
- Spring 复习第一天
一.Sping的优点 1.方便解耦,简化开发 ----Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理. 2.AOP编程的支持 ----Spring提供面向切面编程, ...
- 微信小程序发送短信验证码完整实例
微信小程序注册完整实例,发送短信验证码,带60秒倒计时功能,无需服务器端.效果图: 代码: index.wxml <!--index.wxml--> <view class=&quo ...
- ORACLE 查询近一天,近半小时内的数据
SELECT 字段 FROM 表名 WHERE 时间字段 BETWEEN SYSDATE-1 AND SYSDATE; //查询一天内的数据 sysdate+1 加一天sysdate+1/24 ...
- IntelliJ Idea 2017 免费激活方法
1. 到网站 http://idea.lanyus.com/ 获取注册码. 2.填入下面的license server: http://intellij.mandroid.cn/ http://ide ...
- [SQL]LeetCode177. 第N高的薪水 | Nth Highest Salary
Write a SQL query to get the nth highest salary from the Employee table. +----+--------+ | Id | Sala ...
- [Swift]LeetCode263. 丑数 | Ugly Number
Write a program to check whether a given number is an ugly number. Ugly numbers are positive numbers ...
- [Swift]LeetCode279. 完全平方数 | Perfect Squares
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 1 ...
- [Swift]LeetCode725. 分隔链表 | Split Linked List in Parts
Given a (singly) linked list with head node root, write a function to split the linked list into k c ...