I'm trying to use PyQt5 to create a GUI that has a scrollable area with a large picture. The picture is in the scrollable area and I want to use my mouse to smoothly click and drag the image around. I have it working, to where I can click and drag, but it's extremely laggy/noisy. I have some debug print statements, and it looks like the problem lies in wildly imprecise results from PyQt5's mouse event member:
Been racking my brains for a long time and idk how to fix it so any help is greatly appreciated.
Main program:
event.pos().x()
.Been racking my brains for a long time and idk how to fix it so any help is greatly appreciated.
Main program:
import sys from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QApplication, QMainWindow from gui import Ui_MainWindow class AppWindow(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.label.moved.connect(self.move_image) pixmap = QPixmap('color.jpg') self.ui.label.setPixmap(pixmap) self.ui.hsb = self.ui.scrollArea.horizontalScrollBar() self.show() @pyqtSlot(list) def move_image(self, data): try: self.prev_points = self.cur_points except: self.cur_points = data self.prev_points = self.cur_points return self.cur_points = data hsb = self.ui.scrollArea.horizontalScrollBar() vsb = self.ui.scrollArea.verticalScrollBar() scroll_x = self.cur_points[0] - self.prev_points[0] scroll_y = self.cur_points[1] - self.prev_points[1] hsb_pos = hsb.value() - scroll_x vsb_pos = vsb.value() - scroll_y print('pre: \t {}'.format(self.prev_points)) print('cur: \t {}'.format(self.cur_points)) print('scr X: \t [{}, {}]'.format(scroll_x, scroll_y)) print('pre val: [{}, {}]'.format(hsb.value(), vsb.value())) if hsb_pos >= hsb.minimum() and hsb_pos <= hsb.maximum(): hsb.setValue(hsb.value() - scroll_x) if vsb_pos >= vsb.minimum() and vsb_pos <= vsb.maximum(): vsb.setValue(vsb.value() - scroll_y) print('pos val: [{}, {}]'.format(hsb.value(), vsb.value())) print('\n') def main(): app = QApplication(sys.argv) w = AppWindow() w.show() sys.exit(app.exec_()) if __name__ == '__main__': main()gui.py:
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'gui.ui' # # Created by: PyQt5 UI code generator 5.12.2 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(270, 224) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout.setObjectName("gridLayout") self.scrollArea = QtWidgets.QScrollArea(self.centralwidget) self.scrollArea.setWidgetResizable(True) self.scrollArea.setObjectName("scrollArea") self.scrollAreaWidgetContents = QtWidgets.QWidget() self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 250, 163)) self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.gridLayout_2 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents) self.gridLayout_2.setObjectName("gridLayout_2") self.label = mouseLabel(self.scrollAreaWidgetContents) self.label.setText("") self.label.setObjectName("label") self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) self.scrollArea.setWidget(self.scrollAreaWidgetContents) self.gridLayout.addWidget(self.scrollArea, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 270, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) from customlabel import mouseLabel if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())customlabel.py:
from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * class mouseLabel(QLabel): moved = pyqtSignal(list) def __init__(self, parent=None): super(mouseLabel, self).__init__(parent) self.setMouseTracking(True) self.clicked = False def mouseMoveEvent(self, event): if self.clicked: self.moved.emit([event.pos().x(), event.pos().y()]) def mousePressEvent(self, event): if event.button() == 1: self.clicked = True def mouseReleaseEvent(self, event): if event.button() == 1: self.clicked = False