In QMainWindow, I draw an image from a QPixmap in PaintEvent as follows:
painter.begin(self.pixmapHolder) painter.drawPixmap(0, 0, self.imageWidth, self.imageHeight, self.cellPixmap, self.x0, self.y0, self.xe, self.ye) painter.end() self.lbl.setPixmap(self.pixmapHolder) self.lbl.resize(min(width, self.maxImageWidth), min(height, self.maxImageHeight)) The variables self.x0 and self.y0 are responsible for the beginning of the rectangle to be displayed on the image if it does not fit completely, and self.xe and self.ye are its end. The resulting image: 
When dragging an image, traces remain as in the winXP lagging: 
Dragging is done by changing x0, y0, xe, ye:
def mouseMoveEvent(self, event): if self.isDraged and self.isImageLoaded: self.isMoving = True self.x0 -= event.x() - self.cursorX self.y0 -= event.y() - self.cursorY self.xe -= event.x() - self.cursorX self.ye -= event.y() - self.cursorY self.cursorX = event.x() self.cursorY = event.y() As far as I understand, the problem is precisely in cleaning the "form". How can this be realized?
import sys from collections import namedtuple from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5.QtGui import qRgb from PyQt5.QtGui import QPixmap, QPainter, QBrush, QColor, QImage, QPalette from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QAction, qApp, QMessageBox from PyQt5.QtWidgets import QFileDialog, QLabel, QPushButton, QSlider, QCheckBox from PyQt5.QtCore import Qt, QSize from utils.targetbuild import * class ImageClickEvents(QMainWindow): def __init__(self, screen_width, screen_height, isImageLoaded=False): super(ImageClickEvents, self).__init__() self.isImageLoaded = False self.isDrawingRect = False self.newRectCoord = None self.isDraged = False self.isMoving = False self.x0 = 0 self.y0 = 0 self.xe = screen_width self.ye = screen_height self.xScaled = 1.0 # ΠΌΠ΅ΡΡΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΊΡΡΡΠΎΡΠ° ΠΌΡΡΠΈ Π΄Π»Ρ drag self.cursorX = 0 self.cursorY = 0 self.lbl = QLabel(self) self.cellPixmap = QPixmap(screen_width, screen_height) self.cellPixmapUnscaled = QPixmap(screen_width, screen_height) self.pixmapHolder = QPixmap(700, 400) self.imageWidth = 700 self.imageHeight = 400 self.resize(QSize(875, 400)) # const codes of button in qt # here's mouse buttons: self.NoneButton = 0x00000000 self.LeftButton = 0x00000001 self.RightButton = 0x00000002 self.AllButtons = 0x07ffffff self.initGUI() def initGUI(self): self.lbl.setGeometry(0, 0, 700, 400) openImageBtn = QPushButton('&ΠΡΠΊΡΡΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅', self) openImageBtn.setGeometry(720, 100, 130, 25) openImageBtn.clicked.connect(self.showOpenFileDialog) saveImageBtn = QPushButton('&Π‘ΠΎΡ
ΡΠ°Π½ΠΈΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅', self) saveImageBtn.setGeometry(720, 210, 130, 25) saveImageBtn.clicked.connect(self.showSaveFileDialog) self.update() self.show() def wheelEvent(self, event): numPixels = event.pixelDelta() numDegrees = event.angleDelta() if not numPixels.isNull(): self.xScaled += 0.1*signum(numPixels.y()) elif not numDegrees.isNull(): self.xScaled += 0.1*signum(numDegrees.y()) if self.xScaled < 0.5: self.xScaled = 0.5 elif self.xScaled >= 10.0: self.xScaled = 10.0 self.lbl.setPixmap(QPixmap(1, 1)); self.cellPixmap = self.cellPixmapUnscaled.scaled(self.xScaled * self.imageWidth, self.xScaled * self.imageHeight, Qt.KeepAspectRatioByExpanding) def mousePressEvent(self, event): btn = event.button() if self.isImageLoaded and btn == self.LeftButton: self.isDraged = True print(event.x()) self.cursorX = event.x() self.cursorY = event.y() def mouseMoveEvent(self, event): if self.isDraged and self.isImageLoaded: self.isMoving = True self.x0 -= event.x() - self.cursorX self.y0 -= event.y() - self.cursorY self.xe -= event.x() - self.cursorX self.ye -= event.y() - self.cursorY self.cursorX = event.x() self.cursorY = event.y() def mouseReleaseEvent(self, QMouseEvent): if not self.isImageLoaded: return mx, my = QMouseEvent.pos().x(), QMouseEvent.pos().y() if mx > 700: return pressedButton = QMouseEvent.button() if not self.isImageLoaded: return if self.isDraged and self.isMoving: self.isDraged = False self.isMoving = False return if not self.isDrawingRect: self.isDraged = False def showOpenFileDialog(self): file_name = QFileDialog.getOpenFileName(self, 'Open image', '.')[0] print(file_name) if file_name == '': return self.cellPixmapUnscaled = QPixmap(file_name) self.cellPixmap = self.cellPixmapUnscaled.copy() self.isImageLoaded = True self.x0 = 0 self.y0 = 0 self.xe = min(self.cellPixmap.width(), self.imageWidth) self.ye = min(self.cellPixmap.height(), self.imageHeight) self.xScaled = 1.0 self.update() def showSaveFileDialog(self): if not self.isImageLoaded: nope = QMessageBox() nope.setText("ΠΠ°ΡΡΠ·ΠΈΡΠ΅ ΠΈΠ·Π±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅") nope.exec() return file_name = QFileDialog.getSaveFileName(self, 'Save image', '.')[0] if file_name == '': return if file_name[-4:] != '.png': file_name += '.png' print(file_name) saving_image = QPixmap.toImage(self.cellPixmap) saving_image.save(file_name, 'PNG') def paintEvent(self, event): super().paintEvent(event) painter = QPainter() painter.begin(self.pixmapHolder) painter.drawPixmap(0, 0, self.imageWidth, self.imageHeight, self.cellPixmap, self.x0, self.y0, self.xe, self.ye) painter.end() if self.isImageLoaded: self.lbl.setPixmap(self.pixmapHolder) height = self.cellPixmap.height() width = self.cellPixmap.width() self.lbl.resize(min(width, self.imageWidth), min(height, self.imageHeight)) start_x = 0 start_y = 0 if width < self.imageWidth: start_x = (self.imageWidth - width) / 2 if height < self.imageHeight: start_y = (self.imageHeight - height) / 2 self.lbl.move(start_x, start_y) if __name__ == '__main__': app = QApplication(sys.argv) image_click = ImageClickEvents(700, 400, False) sys.exit(app.exec_()) 