Qt处理Windows系统缩放问题,以截图功能为例

背景

最近在做一个软件,需要截图功能,遇到一个问题。由于windows系统缩放问题,比如在125%的缩放下,程序渲染的分辨率会比实际显示器分辨率低。

// 这里通过获取整个屏幕,并将屏幕保存为一个pixmap
void CaptureScreen::loadBackgroundPixmap() {
    QScreen *screen = QGuiApplication::primaryScreen();
    if (const QWindow *window = windowHandle())
        screen = window->screen();
    m_loadPixmap = screen->grabWindow(0);

    m_screenwidth = m_loadPixmap.width();
    m_screenheight = m_loadPixmap.height();
    qDebug() << "screen_w:" << m_screenwidth << " " << "screen_h:" << m_screenheight;
}


// 这里绘制截图界面
void CaptureScreen::paintEvent(QPaintEvent *event) {
    m_painter.begin(this);			//进行重绘;

    QColor shadowColor = QColor(0, 0, 0, 100);						//阴影颜色设置;
    m_painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap));	//设置画笔;
    m_painter.drawPixmap(0, 0, m_loadPixmap);						//将背景图片画到窗体上;
    m_painter.fillRect(m_loadPixmap.rect(), shadowColor);			//画影罩效果;

    if (m_isMousePress) {
        QRect selectedRect = getRect(m_beginPoint, m_endPoint);
        m_capturePixmap = m_loadPixmap.copy(selectedRect);
        m_painter.drawPixmap(selectedRect.topLeft(), m_capturePixmap);
        m_painter.drawRect(selectedRect);
        qDebug() << "selectedRect:" << selectedRect;
    }
    qDebug() << "m_loadPixmap.rect()" << m_loadPixmap.rect() << " : " << this->size();
}

实现效果如下:

可以发现截取区域显示已经错位了,

其中

qDebug() << "m_loadPixmap.rect()" << m_loadPixmap.rect() << " : " << this->size();

打印出来的结果是 

可以看到,通过截取屏幕获得的大小,为2560x1440,这是我屏幕分辨率,也是系统桌面渲染分辨率,而2048x1152 则是 CaptureScreen这个QDialog的实际显示大小,注意,CaptureScreen为全屏显示。

处理方法

那应该怎么做?由于截图软件需要有线保障截图的清晰度,所以建议,将控件坐标映射到屏幕分辨率。

增加两个映射函数

QPoint CaptureScreen::to_screen_point(QPoint p) {
    int x = (p.x() * 1.0 / this->size().width()) *  m_screenwidth;
    int y = (p.y() * 1.0 / this->size().height()) *  m_screenheight;
    return QPoint(x, y);
}

QSize CaptureScreen::to_screen_size(QSize s) {
    int w = (s.width() * 1.0 / this->size().width()) *  m_screenwidth;
    int h = (s.height() * 1.0 / this->size().height()) *  m_screenheight;
    return QSize(w, h);
}

绘画处改成这样:

if (m_isMousePress) {
        QRect selectedRect = getRect(m_beginPoint, m_endPoint);
        auto pix_rel_topleft = to_screen_point(selectedRect.topLeft());
        auto pix_rel_size = to_screen_size(selectedRect.size());
        QRect pix_rel_rect(pix_rel_topleft, pix_rel_size);
        qDebug() << "selectedRect" << selectedRect << " to  pix_rel_rect" << pix_rel_rect;
        m_capturePixmap = m_loadPixmap.copy(pix_rel_rect);
        m_painter.drawPixmap(selectedRect.topLeft(), m_capturePixmap);
        m_painter.drawRect(selectedRect);
    }

效果如图:

总结

如果能后很好的区分不同层级的渲染分辨率,这个问题还是很好解决的。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值