-
-
Save ce-dric/eceeae04be1fdf8e9e8f054ad8d3f1bc to your computer and use it in GitHub Desktop.
Two Image Synchronous Scrolling in the window by PyQt5 and Python 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
from PyQt5.QtCore import Qt | |
from PyQt5.QtGui import QImage, QPixmap, QPalette, QPainter | |
from PyQt5.QtPrintSupport import QPrintDialog, QPrinter | |
from PyQt5.QtWidgets import QLabel, QSizePolicy, QScrollArea, QMessageBox, QMainWindow, QMenu, QAction, \ | |
qApp, QFileDialog, QWidget, QHBoxLayout | |
class QImageViewSync(QWidget): | |
def __init__(self, window=None): | |
super().__init__() | |
self.window = window | |
self.printer = QPrinter() | |
self.scaleFactor = 0.0 | |
self.imageLabelLeft = QLabel() | |
self.imageLabelLeft.setBackgroundRole(QPalette.Base) | |
self.imageLabelLeft.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) | |
self.imageLabelLeft.setScaledContents(True) | |
self.scrollAreaLeft = QScrollArea() | |
self.scrollAreaLeft.setBackgroundRole(QPalette.Dark) | |
self.scrollAreaLeft.setWidget(self.imageLabelLeft) | |
self.scrollAreaLeft.setVisible(False) | |
self.imageLabelRight = QLabel() | |
self.imageLabelRight.setBackgroundRole(QPalette.Base) | |
self.imageLabelRight.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) | |
self.imageLabelRight.setScaledContents(True) | |
self.scrollAreaRight = QScrollArea() | |
self.scrollAreaRight.setBackgroundRole(QPalette.Dark) | |
self.scrollAreaRight.setWidget(self.imageLabelRight) | |
self.scrollAreaRight.setVisible(False) | |
self.centralWidget = QWidget() | |
self.layout = QHBoxLayout(self.centralWidget) | |
self.layout.addWidget(self.scrollAreaLeft) | |
self.layout.addWidget(self.scrollAreaRight) | |
self.scrollAreaLeft.verticalScrollBar().valueChanged.connect( | |
self.scrollAreaRight.verticalScrollBar().setValue) | |
self.scrollAreaLeft.horizontalScrollBar().valueChanged.connect( | |
self.scrollAreaRight.horizontalScrollBar().setValue) | |
self.scrollAreaRight.verticalScrollBar().valueChanged.connect( | |
self.scrollAreaLeft.verticalScrollBar().setValue) | |
self.scrollAreaRight.horizontalScrollBar().valueChanged.connect( | |
self.scrollAreaLeft.horizontalScrollBar().setValue) | |
self.scrollAreaLeft.mouseMoveEvent = self.mouseMoveEventLeft | |
self.scrollAreaLeft.mousePressEvent = self.mousePressEventLeft | |
self.scrollAreaLeft.mouseReleaseEvent = self.mouseReleaseEventLeft | |
self.scrollAreaRight.mouseMoveEvent = self.mouseMoveEventRight | |
self.scrollAreaRight.mousePressEvent = self.mousePressEventRight | |
self.scrollAreaRight.mouseReleaseEvent = self.mouseReleaseEventRight | |
self.imageLabelLeft.setCursor(Qt.OpenHandCursor) | |
self.imageLabelRight.setCursor(Qt.OpenHandCursor) | |
def mousePressEventLeft(self, event): | |
self.pressed = True | |
self.imageLabelLeft.setCursor(Qt.ClosedHandCursor) | |
self.initialPosX = self.scrollAreaLeft.horizontalScrollBar().value() + event.pos().x() | |
self.initialPosY = self.scrollAreaLeft.verticalScrollBar().value() + event.pos().y() | |
def mouseReleaseEventLeft(self, event): | |
self.pressed = False | |
self.imageLabelLeft.setCursor(Qt.OpenHandCursor) | |
self.initialPosX = self.scrollAreaLeft.horizontalScrollBar().value() | |
self.initialPosY = self.scrollAreaLeft.verticalScrollBar().value() | |
def mouseMoveEventLeft(self, event): | |
if self.pressed: | |
self.scrollAreaLeft.horizontalScrollBar().setValue(self.initialPosX - event.pos().x()) | |
self.scrollAreaLeft.verticalScrollBar().setValue(self.initialPosY - event.pos().y()) | |
def mousePressEventRight(self, event): | |
self.pressed = True | |
self.imageLabelRight.setCursor(Qt.ClosedHandCursor) | |
self.initialPosX = self.scrollAreaRight.horizontalScrollBar().value() + event.pos().x() | |
self.initialPosY = self.scrollAreaRight.verticalScrollBar().value() + event.pos().y() | |
def mouseReleaseEventRight(self, event): | |
self.pressed = False | |
self.imageLabelRight.setCursor(Qt.OpenHandCursor) | |
self.initialPosX = self.scrollAreaRight.horizontalScrollBar().value() | |
self.initialPosY = self.scrollAreaRight.verticalScrollBar().value() | |
def mouseMoveEventRight(self, event): | |
if self.pressed: | |
self.scrollAreaRight.horizontalScrollBar().setValue(self.initialPosX - event.pos().x()) | |
self.scrollAreaRight.verticalScrollBar().setValue(self.initialPosY - event.pos().y()) | |
def open(self): | |
options = QFileDialog.Options() | |
# fileName = QFileDialog.getOpenFileName(self, "Open File", QDir.currentPath()) | |
fileName, _ = QFileDialog.getOpenFileName(self, 'QFileDialog.getOpenFileName()', '', | |
'Images (*.png *.jpeg *.jpg *.bmp *.gif)', options=options) | |
if fileName: | |
print(fileName) | |
image = QImage(fileName) | |
if image.isNull(): | |
QMessageBox.information(self, "Image Viewer", "Cannot load %s." % fileName) | |
return | |
self.imageLabelLeft.setPixmap(QPixmap.fromImage(image)) | |
self.imageLabelRight.setPixmap(QPixmap.fromImage(image)) | |
self.scaleFactor = 1.0 | |
self.scrollAreaLeft.setVisible(True) | |
self.scrollAreaRight.setVisible(True) | |
self.window.printLeftAct.setEnabled(True) | |
self.window.printRightAct.setEnabled(True) | |
self.window.fitToWindowAct.setEnabled(True) | |
self.updateActions() | |
if not self.window.fitToWindowAct.isChecked(): | |
self.imageLabelLeft.adjustSize() | |
self.imageLabelRight.adjustSize() | |
def openLeft(self): | |
options = QFileDialog.Options() | |
# fileName = QFileDialog.getOpenFileName(self, "Open File", QDir.currentPath()) | |
fileName, _ = QFileDialog.getOpenFileName(self, 'QFileDialog.getOpenFileName()', '', | |
'Images (*.png *.jpeg *.jpg *.bmp *.gif)', options=options) | |
if fileName: | |
print(fileName) | |
image = QImage(fileName) | |
if image.isNull(): | |
QMessageBox.information(self, "Image Viewer", "Cannot load %s." % fileName) | |
return | |
self.imageLabelLeft.setPixmap(QPixmap.fromImage(image)) | |
self.scaleFactor = 1.0 | |
self.scrollAreaLeft.setVisible(True) | |
self.window.printLeftAct.setEnabled(True) | |
self.window.fitToWindowAct.setEnabled(True) | |
self.updateActions() | |
if not self.window.fitToWindowAct.isChecked(): | |
self.imageLabelLeft.adjustSize() | |
def openRight(self): | |
options = QFileDialog.Options() | |
# fileName = QFileDialog.getOpenFileName(self, "Open File", QDir.currentPath()) | |
fileName, _ = QFileDialog.getOpenFileName(self, 'QFileDialog.getOpenFileName()', '', | |
'Images (*.png *.jpeg *.jpg *.bmp *.gif)', options=options) | |
if fileName: | |
print(fileName) | |
image = QImage(fileName) | |
if image.isNull(): | |
QMessageBox.information(self, "Image Viewer", "Cannot load %s." % fileName) | |
return | |
self.imageLabelRight.setPixmap(QPixmap.fromImage(image)) | |
self.scaleFactor = 1.0 | |
self.scrollAreaRight.setVisible(True) | |
self.window.printRightAct.setEnabled(True) | |
self.window.fitToWindowAct.setEnabled(True) | |
self.updateActions() | |
if not self.window.fitToWindowAct.isChecked(): | |
self.imageLabelRight.adjustSize() | |
def printLeft(self): | |
dialog = QPrintDialog(self.printer, self) | |
if dialog.exec_(): | |
painter = QPainter(self.printer) | |
rect = painter.viewport() | |
size = self.imageLabelLeft.pixmap().size() | |
size.scale(rect.size(), Qt.KeepAspectRatio) | |
painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) | |
painter.setWindow(self.imageLabelLeft.pixmap().rect()) | |
painter.drawPixmap(0, 0, self.imageLabelLeft.pixmap()) | |
def printRight(self): | |
dialog = QPrintDialog(self.printer, self) | |
if dialog.exec_(): | |
painter = QPainter(self.printer) | |
rect = painter.viewport() | |
size = self.imageLabelRight.pixmap().size() | |
size.scale(rect.size(), Qt.KeepAspectRatio) | |
painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) | |
painter.setWindow(self.imageLabelRight.pixmap().rect()) | |
painter.drawPixmap(0, 0, self.imageLabelRight.pixmap()) | |
def zoomIn(self): | |
self.scaleImage(1.25) | |
def zoomOut(self): | |
self.scaleImage(0.8) | |
def normalSize(self): | |
self.imageLabelLeft.adjustSize() | |
self.imageLabelRight.adjustSize() | |
self.scaleFactor = 1.0 | |
def about(self): | |
QMessageBox.about(self, "Image View in the Main Window", | |
"<p>The <b>Image Viewer</b> example shows how to combine " | |
"QLabel and QScrollArea to display an image. QLabel is " | |
"typically used for displaying text, but it can also display " | |
"an image. QScrollArea provides a scrolling view around " | |
"another widget. If the child widget exceeds the size of the " | |
"frame, QScrollArea automatically provides scroll bars.</p>" | |
"<p>The example demonstrates how QLabel's ability to scale " | |
"its contents (QLabel.scaledContents), and QScrollArea's " | |
"ability to automatically resize its contents " | |
"(QScrollArea.widgetResizable), can be used to implement " | |
"zooming and scaling features.</p>" | |
"<p>In addition the example shows how to use QPainter to " | |
"print an image.</p>") | |
def updateActions(self): | |
self.window.zoomInAct.setEnabled(not self.window.fitToWindowAct.isChecked()) | |
self.window.zoomOutAct.setEnabled(not self.window.fitToWindowAct.isChecked()) | |
self.window.normalSizeAct.setEnabled(not self.window.fitToWindowAct.isChecked()) | |
def scaleImage(self, factor): | |
self.scaleFactor *= factor | |
self.imageLabelLeft.resize(self.scaleFactor * self.imageLabelLeft.pixmap().size()) | |
self.imageLabelRight.resize(self.scaleFactor * self.imageLabelRight.pixmap().size()) | |
self.adjustScrollBar(self.scrollAreaLeft.horizontalScrollBar(), factor) | |
self.adjustScrollBar(self.scrollAreaLeft.verticalScrollBar(), factor) | |
self.adjustScrollBar(self.scrollAreaRight.horizontalScrollBar(), factor) | |
self.adjustScrollBar(self.scrollAreaRight.verticalScrollBar(), factor) | |
self.window.zoomInAct.setEnabled(self.scaleFactor < 3.0) | |
self.window.zoomOutAct.setEnabled(self.scaleFactor > 0.333) | |
def adjustScrollBar(self, scrollBar, factor): | |
scrollBar.setValue(int(factor * scrollBar.value() | |
+ ((factor - 1) * scrollBar.pageStep() / 2))) | |
class MainWindow(QMainWindow): | |
def __init__(self): | |
super().__init__() | |
self.imageViewSync = QImageViewSync(window=self) | |
self.setCentralWidget(self.imageViewSync.centralWidget) | |
self.createActions(self.imageViewSync) | |
self.createMenus() | |
self.setWindowTitle("Image View Sync in the Main Window") | |
self.resize(1200, 600) | |
def fitToWindow(self): | |
fitToWindow = self.fitToWindowAct.isChecked() | |
self.imageViewSync.scrollAreaLeft.setWidgetResizable(fitToWindow) | |
self.imageViewSync.scrollAreaRight.setWidgetResizable(fitToWindow) | |
if not fitToWindow: | |
self.imageViewSync.normalSize() | |
self.imageViewSync.updateActions() | |
def createActions(self, view): | |
self.openLeftAct = QAction("&Open Left...", self, shortcut="Ctrl+O", triggered=view.openLeft) | |
self.openRightAct = QAction("&Open Right...", self, shortcut="Shift+Ctrl+O", triggered=view.openRight) | |
self.printLeftAct = QAction("&Print Left...", self, shortcut="Ctrl+P", enabled=False, triggered=view.printLeft) | |
self.printRightAct = QAction("&Print Right...", self, | |
shortcut="Shift+Ctrl+P", enabled=False, triggered=view.printRight) | |
# self.exitAct = QAction("E&xit", self, shortcut="Ctrl+Q", triggered=image.close) | |
self.zoomInAct = QAction("Zoom &In (25%)", self, shortcut="Ctrl++", enabled=False, triggered=view.zoomIn) | |
self.zoomOutAct = QAction("Zoom &Out (25%)", self, shortcut="Ctrl+-", enabled=False, triggered=view.zoomOut) | |
self.normalSizeAct = QAction("&Normal Size", self, shortcut="Ctrl+S", enabled=False, triggered=view.normalSize) | |
self.fitToWindowAct = QAction("&Fit to Window", self, | |
enabled=False, checkable=True, shortcut="Ctrl+F", triggered=self.fitToWindow) | |
self.aboutAct = QAction("&About", self, triggered=view.about) | |
self.aboutQtAct = QAction("About &Qt", self, triggered=qApp.aboutQt) | |
def createMenus(self): | |
self.fileMenu = QMenu("&File", self) | |
self.fileMenu.addAction(self.openLeftAct) | |
self.fileMenu.addAction(self.openRightAct) | |
self.fileMenu.addSeparator() | |
self.fileMenu.addAction(self.printLeftAct) | |
self.fileMenu.addAction(self.printRightAct) | |
self.fileMenu.addSeparator() | |
# self.fileMenu.addAction(self.exitAct) | |
self.viewMenu = QMenu("&View", self) | |
self.viewMenu.addAction(self.zoomInAct) | |
self.viewMenu.addAction(self.zoomOutAct) | |
self.viewMenu.addAction(self.normalSizeAct) | |
self.viewMenu.addSeparator() | |
self.viewMenu.addAction(self.fitToWindowAct) | |
self.helpMenu = QMenu("&Help", self) | |
self.helpMenu.addAction(self.aboutAct) | |
self.helpMenu.addAction(self.aboutQtAct) | |
self.menuBar().addMenu(self.fileMenu) | |
self.menuBar().addMenu(self.viewMenu) | |
self.menuBar().addMenu(self.helpMenu) | |
if __name__ == '__main__': | |
import sys | |
from PyQt5.QtWidgets import QApplication | |
app = QApplication(sys.argv) | |
win = MainWindow() | |
win.show() | |
sys.exit(app.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://github.com/Odin-son/pruebas-de-validacion