Reputation: 222
A few months ago I wanted to know how to draw on an image (Insert Image into QGridLayout and Draw on top of image in PyQt5). Eyllanesc very kindly gave me a complete solution. I now would like to have this image widget scrollable so I can enlarge it. Howerver, when I add a scroll area the scrollbars do not appear. When I do force the scrollbars to appear, they do not seem to be attached to anything. I've looked at a number of posts on Scroll Areas: /45515445/, /6792862/, /55149412/, /23446855/, /46979944/, /46024724/, /53843836/, /11886908/, /53914267/, /53843836/, /45515445/, /52671838/. These solutions are not in a QGridLayout, but I don't know if this is the source of my problem or not. Could anyone help me? Thank you!
from PyQt5.QtCore import (QPoint, Qt)
from PyQt5.QtGui import (QPainter, QPen, QPixmap)
from PyQt5.QtWidgets import (QApplication, QGridLayout, QMainWindow, QPushButton, QScrollArea, QTextEdit, QWidget) ####NEW
import os; import sys
###########################################################################
# https://stackoverflow.com/questions/56194201
class ImageLabel(QWidget):
# loads a graphic file, inserts it into a QLabel that allows drawing of lines on the surface
def __init__(self, parent=None):
super(ImageLabel, self).__init__(parent)
self.image = QPixmap('image.png')
self.drawing = False
self.lastPoint = QPoint()
def changePixmap(self,img, x, y):
self.image = QPixmap(img).scaled(x, y, Qt.KeepAspectRatio) #/34213021/, /21802868/
self.repaint()
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(QPoint(), self.image)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drawing = True
self.lastPoint = event.pos()
def mouseMoveEvent(self, event):
if (event.buttons() & Qt.LeftButton) and self.drawing:
painter = QPainter(self.image)
painter.setPen(QPen(Qt.red, 1, Qt.SolidLine))
painter.drawLine(self.lastPoint, event.pos())
self.lastPoint = event.pos()
self.update()
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.drawing = False
def sizeHint(self):
return self.image.size()
###########################################################################
class MainWindow(QMainWindow):
#########################################
def ZoomIn(self):
self.width = self.ilabel.image.size().width() *1.25
self.height = self.ilabel.image.size().height() * 1.25
self.ilabel.changePixmap('image.png', self.width, self.height)# SOF: /24106903/
########################################
def ZoomOut(self):
self.width = self.ilabel.image.size().width() / 1.25
self.height = self.ilabel.image.size().height() / 1.25
self.ilabel.changePixmap('image.png', self.width, self.height)# SOF: /24106903/
########################################
def __init__(self, parent = None):
super().__init__(parent)
# Set up main widget
widget = QWidget()
self.setCentralWidget(widget)
self.myLayout = QGridLayout(widget)
# Image
#######
self.width = 564; self.height = 800
self.ilabel = ImageLabel()
# https://stackoverflow.com/questions/45515445/
# Add this custom label to a scroll area
self.scroller = QScrollArea(self)
self.scroller.setWidget(self.ilabel)
self.scroller.setWidgetResizable(True)
self.scroller.adjustSize()
self.myLayout.addWidget(self.scroller, 0, 0, 110, 70)
# PROBLEM: NO SCROLLBARS APPEAR!
# If I add:
self.scroller.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) #https://stackoverflow.com/questions/53914267/
self.scroller.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) # https://stackoverflow.com/questions/53914267/
# The scrollbars appear but do not scroll the image. I imagine they are not actually atached to the scroll area
# ZoomIn button
self.btnzi = QPushButton('Zoom In',self)
self.btnzi.clicked.connect(self.ZoomIn)
self.myLayout.addWidget(self.btnzi, 112, 5, 1, 1)
# ZoomOut button
self.btnzo = QPushButton('Zoom Out',self)
self.btnzo.clicked.connect(self.ZoomOut)
self.myLayout.addWidget(self.btnzo, 112, 10, 1, 1)
# Text
######
self.textedit = QTextEdit()
self.myLayout.addWidget(self.textedit, 0, 70, 111, 100)
if __name__ =='__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
###########################################################################
Upvotes: 1
Views: 225
Reputation: 244212
QScrollArea uses size() and minimumSizeHint() to set when the scrollbar is needed, so in your case it is fixed and does not depend on the size of the image which causes the problem.
class ImageLabel(QWidget):
# ...
def changePixmap(self,img, x, y):
self.image = QPixmap(img).scaled(x, y, Qt.KeepAspectRatio) #/34213021/, /21802868/
self.update()
self.resize(self.image.size())
def sizeHint(self):
return self.image.size()
def minimumSizeHint(self):
return self.sizeHint()
It is also not necessary to force the appearance of the scrollbar so you must remove:
self.scroller.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroller.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
Upvotes: 1