<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Force repaint on window move]]></title><description><![CDATA[<p dir="auto">Hi,</p>
<p dir="auto">I am trying to achieve a transparent blurred background (like the acrylic on W10). I succeed to have the desired result visually.<br />
To do so, I just grabbed a screenshot and blurred it. Then I display it in the paint event.<br />
But I struggle to refresh the widget when my window move. I tried to call an update but it looks like when I move the window with the title bar, there is some lag. Which is less (but still) present if I ask and update when we move the window in another way (click+drag in the widget itself make it move).</p>
<p dir="auto">So my question is: Why is it so slow to perform the update (it take less than 10ms on my computer) and also why it is different when I move the window with the title bar.</p>
<p dir="auto">Do you have some hints to make it work faster or maybe I do something really stupid and wrong and there is a magic way to do it :D</p>
<p dir="auto">You can find the code below. Unfortunately, you will need to pip install some packages (numpy and scipy) to run the script</p>
<pre><code class="language-python">from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

import numpy
from scipy.ndimage.filters import gaussian_filter1d  # need to pip install scipy
import typing
import sys
import time



def blurImage(image: QImage, radius: int, toPixmap: bool = False) -&gt; typing.Union[QImage, QPixmap]:
    def arrayToQImage(im: numpy.ndarray, copy: bool = False) -&gt; QImage:
        gray_color_table = [qRgb(i, i, i) for i in range(256)]
        if im is None:
            return QImage()

        if im.dtype == numpy.uint8:
            if len(im.shape) == 2:
                qim = QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QImage.Format_Indexed8)
                qim.setColorTable(gray_color_table)
                return qim.copy() if copy else qim

            elif len(im.shape) == 3:
                if im.shape[2] == 3:
                    qim = QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QImage.Format_RGB888);
                    return qim.copy() if copy else qim
                elif im.shape[2] == 4:
                    qim = QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QImage.Format_ARGB32);
                    return qim.copy() if copy else qim

    if image.format() != QImage.Format_RGB32:
        image = image.convertToFormat(QImage.Format_RGB32)
    
    bits = image.bits() # contain the memory pointer to the pixel color list
    
    # As python is too slow, we use a numpy array to fill the color in a 3d dimenssional array
    array = numpy.frombuffer(bits, numpy.uint8).reshape((image.height(), image.width(), 4))

    blurred = gaussian_filter1d(array, sigma=radius, axis=0)
    blurred = gaussian_filter1d(blurred, sigma=radius, axis=1)

    blurred_image = arrayToQImage(blurred.copy(), True)

    if toPixmap is True:
        return QPixmap.fromImage(blurred_image)
    else: 
        return blurred_image

class Window(QWidget):
    def __init__(self) -&gt; None:
        super().__init__()
        self.screenshot: QPixmap = None
        self.clickedPos: QPoint = QPoint(0, 0)
        self.setLayout(QVBoxLayout())
        for i in range(4):
            self.layout().addWidget(QLabel("plop"))


    def paintEvent(self, event: QPaintEvent) -&gt; None:
        
        start = time.time()
        pos: QPoint = self.pos()

        painter: QPainter = QPainter(self)
        painter.drawPixmap(
            QRect(
                -1920 - pos.x(),
                0 - pos.y()-30,
                self.screenshot.width(),
                self.screenshot.height(),
            ),
            self.screenshot
        )

        painter.setOpacity(0.5)
        painter.setPen(Qt.NoPen)
        painter.setBrush(Qt.black)
        painter.drawRect(event.rect())

        painter.end()

        return super().paintEvent(event)  
        

    def show(self) -&gt; None:
        screen = QApplication.screenAt(QCursor().pos())
        s_geo = screen.geometry()
        screenshot = screen.grabWindow(0, 0, 0, s_geo.width(), s_geo.height())
        
        self.screenshot = blurImage(screenshot.toImage(), 9, True)
        
        return super().show()

    def updateBG(self) -&gt; None:
        self.repaint(QRect(0, 0, self.width(), self.height()))

    def mousePressEvent(self, event: QMouseEvent) -&gt; None:
        self.clickedPos = event.pos() - QPoint(0, -30)
        return super().mousePressEvent(event)

    def mouseMoveEvent(self, event: QMouseEvent) -&gt; None:        
        self.move(self.mapToGlobal(event.pos()) - self.clickedPos)
        # self.updateBG()
        return super().mouseMoveEvent(event)

    def moveEvent(self, event: QMoveEvent) -&gt; None:
        self.updateBG()
        return super().moveEvent(event)

app = QApplication()

w = Window()
w.show()
sys.exit(app.exec_())
</code></pre>
<p dir="auto">Thank you very much for your help. Feel free to ask me any more information if needed :)</p>
]]></description><link>https://forum.qt.io/topic/127008/force-repaint-on-window-move</link><generator>RSS for Node</generator><lastBuildDate>Thu, 22 Oct 2026 20:58:08 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/127008.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 26 May 2021 12:59:07 GMT</pubDate><ttl>60</ttl></channel></rss>