QPaint with mouse Event panning
up vote
1
down vote
favorite
I have created a paint widget, that I want to implement a pan event with hand icon tool, which usually sees in many softwares. it is when user press on mouse button and hold it then move over within Qpainter canvas
, the drawing follows the mouse movement. I can't find out how to do it in PyQt5.
VISUAL EXAMPLE
The current screen:
The desired screen event:
The Code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 1200, 600))
self.paint = Paint()
self.sizeHint()
self.lay = QtWidgets.QVBoxLayout()
self.lay.addWidget(self.paint)
self.setLayout(self.lay)
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self.rect().center())
painter.drawRect(r)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
I appreciate any help and thanks in advance.
Update of code:
Visualization:
Well,that's what happens when I implement the updated code in my central code.
it is when user clicks and picks section from circular then plots within the widget, right after click and select another section from rectangular. The widget should update and erase previous drawing. But it does't do that. In my previous code the section drawing appears directly in the center of widget, now it sticks to upperleft edge of canvas.
A part of code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 800, 800))
self.button = Button()
self.paint = Createpaintwidget()
self.button.valuesChanged.connect(self.paint.set_size_squares)
self.button.valueChanged.connect(self.paint.set_size_round)
self.lay = QtWidgets.QVBoxLayout(self)
self.lay.addWidget(self.paint)
self.lay.addWidget(self.button)
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int,int)
def set_size_squares(self, w, h):
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
class Button(QtWidgets.QWidget):
valueChanged = QtCore.pyqtSignal(int)
valuesChanged = QtCore.pyqtSignal(int,int)
def __init__(self, parent=None):
super(Button, self).__init__(parent)
roundbutton = QtWidgets.QPushButton('Round')
squarebutton = QtWidgets.QPushButton('Square')
Alay = QtWidgets.QVBoxLayout(self)
Alay.addWidget(roundbutton)
Alay.addWidget(squarebutton)
self.value = QtWidgets.QLabel()
roundbutton.clicked.connect(self.getbuttonfunc)
squarebutton.clicked.connect(self.sqaurebuttonfunc)
@QtCore.pyqtSlot()
def getbuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valueChanged.emit(number)
@QtCore.pyqtSlot()
def sqaurebuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valuesChanged.emit(number, number)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
python pyqt pyqt5 qpainter pan
add a comment |
up vote
1
down vote
favorite
I have created a paint widget, that I want to implement a pan event with hand icon tool, which usually sees in many softwares. it is when user press on mouse button and hold it then move over within Qpainter canvas
, the drawing follows the mouse movement. I can't find out how to do it in PyQt5.
VISUAL EXAMPLE
The current screen:
The desired screen event:
The Code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 1200, 600))
self.paint = Paint()
self.sizeHint()
self.lay = QtWidgets.QVBoxLayout()
self.lay.addWidget(self.paint)
self.setLayout(self.lay)
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self.rect().center())
painter.drawRect(r)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
I appreciate any help and thanks in advance.
Update of code:
Visualization:
Well,that's what happens when I implement the updated code in my central code.
it is when user clicks and picks section from circular then plots within the widget, right after click and select another section from rectangular. The widget should update and erase previous drawing. But it does't do that. In my previous code the section drawing appears directly in the center of widget, now it sticks to upperleft edge of canvas.
A part of code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 800, 800))
self.button = Button()
self.paint = Createpaintwidget()
self.button.valuesChanged.connect(self.paint.set_size_squares)
self.button.valueChanged.connect(self.paint.set_size_round)
self.lay = QtWidgets.QVBoxLayout(self)
self.lay.addWidget(self.paint)
self.lay.addWidget(self.button)
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int,int)
def set_size_squares(self, w, h):
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
class Button(QtWidgets.QWidget):
valueChanged = QtCore.pyqtSignal(int)
valuesChanged = QtCore.pyqtSignal(int,int)
def __init__(self, parent=None):
super(Button, self).__init__(parent)
roundbutton = QtWidgets.QPushButton('Round')
squarebutton = QtWidgets.QPushButton('Square')
Alay = QtWidgets.QVBoxLayout(self)
Alay.addWidget(roundbutton)
Alay.addWidget(squarebutton)
self.value = QtWidgets.QLabel()
roundbutton.clicked.connect(self.getbuttonfunc)
squarebutton.clicked.connect(self.sqaurebuttonfunc)
@QtCore.pyqtSlot()
def getbuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valueChanged.emit(number)
@QtCore.pyqtSlot()
def sqaurebuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valuesChanged.emit(number, number)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
python pyqt pyqt5 qpainter pan
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have created a paint widget, that I want to implement a pan event with hand icon tool, which usually sees in many softwares. it is when user press on mouse button and hold it then move over within Qpainter canvas
, the drawing follows the mouse movement. I can't find out how to do it in PyQt5.
VISUAL EXAMPLE
The current screen:
The desired screen event:
The Code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 1200, 600))
self.paint = Paint()
self.sizeHint()
self.lay = QtWidgets.QVBoxLayout()
self.lay.addWidget(self.paint)
self.setLayout(self.lay)
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self.rect().center())
painter.drawRect(r)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
I appreciate any help and thanks in advance.
Update of code:
Visualization:
Well,that's what happens when I implement the updated code in my central code.
it is when user clicks and picks section from circular then plots within the widget, right after click and select another section from rectangular. The widget should update and erase previous drawing. But it does't do that. In my previous code the section drawing appears directly in the center of widget, now it sticks to upperleft edge of canvas.
A part of code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 800, 800))
self.button = Button()
self.paint = Createpaintwidget()
self.button.valuesChanged.connect(self.paint.set_size_squares)
self.button.valueChanged.connect(self.paint.set_size_round)
self.lay = QtWidgets.QVBoxLayout(self)
self.lay.addWidget(self.paint)
self.lay.addWidget(self.button)
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int,int)
def set_size_squares(self, w, h):
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
class Button(QtWidgets.QWidget):
valueChanged = QtCore.pyqtSignal(int)
valuesChanged = QtCore.pyqtSignal(int,int)
def __init__(self, parent=None):
super(Button, self).__init__(parent)
roundbutton = QtWidgets.QPushButton('Round')
squarebutton = QtWidgets.QPushButton('Square')
Alay = QtWidgets.QVBoxLayout(self)
Alay.addWidget(roundbutton)
Alay.addWidget(squarebutton)
self.value = QtWidgets.QLabel()
roundbutton.clicked.connect(self.getbuttonfunc)
squarebutton.clicked.connect(self.sqaurebuttonfunc)
@QtCore.pyqtSlot()
def getbuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valueChanged.emit(number)
@QtCore.pyqtSlot()
def sqaurebuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valuesChanged.emit(number, number)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
python pyqt pyqt5 qpainter pan
I have created a paint widget, that I want to implement a pan event with hand icon tool, which usually sees in many softwares. it is when user press on mouse button and hold it then move over within Qpainter canvas
, the drawing follows the mouse movement. I can't find out how to do it in PyQt5.
VISUAL EXAMPLE
The current screen:
The desired screen event:
The Code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 1200, 600))
self.paint = Paint()
self.sizeHint()
self.lay = QtWidgets.QVBoxLayout()
self.lay.addWidget(self.paint)
self.setLayout(self.lay)
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self.rect().center())
painter.drawRect(r)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
I appreciate any help and thanks in advance.
Update of code:
Visualization:
Well,that's what happens when I implement the updated code in my central code.
it is when user clicks and picks section from circular then plots within the widget, right after click and select another section from rectangular. The widget should update and erase previous drawing. But it does't do that. In my previous code the section drawing appears directly in the center of widget, now it sticks to upperleft edge of canvas.
A part of code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 800, 800))
self.button = Button()
self.paint = Createpaintwidget()
self.button.valuesChanged.connect(self.paint.set_size_squares)
self.button.valueChanged.connect(self.paint.set_size_round)
self.lay = QtWidgets.QVBoxLayout(self)
self.lay.addWidget(self.paint)
self.lay.addWidget(self.button)
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int,int)
def set_size_squares(self, w, h):
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
class Button(QtWidgets.QWidget):
valueChanged = QtCore.pyqtSignal(int)
valuesChanged = QtCore.pyqtSignal(int,int)
def __init__(self, parent=None):
super(Button, self).__init__(parent)
roundbutton = QtWidgets.QPushButton('Round')
squarebutton = QtWidgets.QPushButton('Square')
Alay = QtWidgets.QVBoxLayout(self)
Alay.addWidget(roundbutton)
Alay.addWidget(squarebutton)
self.value = QtWidgets.QLabel()
roundbutton.clicked.connect(self.getbuttonfunc)
squarebutton.clicked.connect(self.sqaurebuttonfunc)
@QtCore.pyqtSlot()
def getbuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valueChanged.emit(number)
@QtCore.pyqtSlot()
def sqaurebuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valuesChanged.emit(number, number)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
python pyqt pyqt5 qpainter pan
python pyqt pyqt5 qpainter pan
edited 2 days ago
asked Nov 21 at 18:56
Zar Kha
43111
43111
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
To make the pan you must follow the following steps:
Get the initial position in mousePressEvent
In mouseMoveEvent move the rectangle with the difference between the current position and the initial position, and update the initial position with the current position.
The implementation is as follows:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._rect = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._rect.moveCenter(self.rect().center())
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
painter.drawRect(self._rect)
def mousePressEvent(self, event):
if self._rect.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if self._rect.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
But instead of doing it Qt already offers classes that allow you to do the tasks that you point out in a simple way, in this case it is to use QGraphicsView with the QGraphicsItem:
class GraphicsRectItem(QtWidgets.QGraphicsRectItem):
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
super(GraphicsRectItem, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(GraphicsRectItem, self).mouseReleaseEvent(event)
class Paint(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
rect_item = GraphicsRectItem(0, 0, 350, 250)
rect_item.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
rect_item.setPen(QtCore.Qt.darkCyan)
rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
self.scene().addItem(rect_item)
UPDATE:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
self._pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._pos = self.rect().center()
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
painter.drawRect(r)
def mousePressEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._pos += delta
self._initial_pos = event.pos()
self.update()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
Update:
One way to implement the task is to have an element or set connected element, in this case it is a QPainterPath plus a QRectF, the first will draw the arrows, lines, etc. and the second the rectangle or central circle. After that, it is enough to move those elements according to the case.
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int, int)
def set_size_squares(self, w, h):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
Great, you are indeed clever. Thanks. I notes whenQGraphicsView
runs and autoscrolles appears but this is not the case whenQpainter
uses, can a scroll add toQpainter
?.But what is the difference betweenQPainter
andQGraphicsView
. I have seenQGraphicsView
is been used widely?
– Zar Kha
Nov 21 at 20:13
@ZarKha QGraphicsView is a widget specialized in handling items that internally uses QPainter, that is, it is a high level way to paint. The scrollbar appears because QGraphiscView is designed to handle items that may be in larger positions on your screen, it can be disabled. In conclusion with QPainter are in the stone age where it was painted manually and with QGraphicsView you are using MS paint or similar
– eyllanesc
Nov 21 at 20:19
@ZarKha If my answer helps you do not forget to mark it as correct, if you do not know how to do it then review the tour, that is the best way to thank.
– eyllanesc
Nov 21 at 20:20
My last question according to your answer, I had this code lineself._rect =
withindef paint
, in your answer you have brought it outside of function, that indeed gives some errors which I have in my private code. The event wont run! is it a way to keep it inside the function? I really need this to be solved?
– Zar Kha
Nov 21 at 20:31
@ZarKha Surely in the old answer do not point out that the rectangle was movable so the rectangle is fixed and used in the paintEvent, but in this case is dynamic although I think it can maintain the previous logic, at a time I will give an alternative. On the other hand I do not know the implementation of your private code so I will not think since you probably have other errors.
– eyllanesc
Nov 21 at 20:38
|
show 13 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
To make the pan you must follow the following steps:
Get the initial position in mousePressEvent
In mouseMoveEvent move the rectangle with the difference between the current position and the initial position, and update the initial position with the current position.
The implementation is as follows:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._rect = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._rect.moveCenter(self.rect().center())
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
painter.drawRect(self._rect)
def mousePressEvent(self, event):
if self._rect.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if self._rect.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
But instead of doing it Qt already offers classes that allow you to do the tasks that you point out in a simple way, in this case it is to use QGraphicsView with the QGraphicsItem:
class GraphicsRectItem(QtWidgets.QGraphicsRectItem):
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
super(GraphicsRectItem, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(GraphicsRectItem, self).mouseReleaseEvent(event)
class Paint(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
rect_item = GraphicsRectItem(0, 0, 350, 250)
rect_item.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
rect_item.setPen(QtCore.Qt.darkCyan)
rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
self.scene().addItem(rect_item)
UPDATE:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
self._pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._pos = self.rect().center()
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
painter.drawRect(r)
def mousePressEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._pos += delta
self._initial_pos = event.pos()
self.update()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
Update:
One way to implement the task is to have an element or set connected element, in this case it is a QPainterPath plus a QRectF, the first will draw the arrows, lines, etc. and the second the rectangle or central circle. After that, it is enough to move those elements according to the case.
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int, int)
def set_size_squares(self, w, h):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
Great, you are indeed clever. Thanks. I notes whenQGraphicsView
runs and autoscrolles appears but this is not the case whenQpainter
uses, can a scroll add toQpainter
?.But what is the difference betweenQPainter
andQGraphicsView
. I have seenQGraphicsView
is been used widely?
– Zar Kha
Nov 21 at 20:13
@ZarKha QGraphicsView is a widget specialized in handling items that internally uses QPainter, that is, it is a high level way to paint. The scrollbar appears because QGraphiscView is designed to handle items that may be in larger positions on your screen, it can be disabled. In conclusion with QPainter are in the stone age where it was painted manually and with QGraphicsView you are using MS paint or similar
– eyllanesc
Nov 21 at 20:19
@ZarKha If my answer helps you do not forget to mark it as correct, if you do not know how to do it then review the tour, that is the best way to thank.
– eyllanesc
Nov 21 at 20:20
My last question according to your answer, I had this code lineself._rect =
withindef paint
, in your answer you have brought it outside of function, that indeed gives some errors which I have in my private code. The event wont run! is it a way to keep it inside the function? I really need this to be solved?
– Zar Kha
Nov 21 at 20:31
@ZarKha Surely in the old answer do not point out that the rectangle was movable so the rectangle is fixed and used in the paintEvent, but in this case is dynamic although I think it can maintain the previous logic, at a time I will give an alternative. On the other hand I do not know the implementation of your private code so I will not think since you probably have other errors.
– eyllanesc
Nov 21 at 20:38
|
show 13 more comments
up vote
1
down vote
accepted
To make the pan you must follow the following steps:
Get the initial position in mousePressEvent
In mouseMoveEvent move the rectangle with the difference between the current position and the initial position, and update the initial position with the current position.
The implementation is as follows:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._rect = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._rect.moveCenter(self.rect().center())
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
painter.drawRect(self._rect)
def mousePressEvent(self, event):
if self._rect.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if self._rect.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
But instead of doing it Qt already offers classes that allow you to do the tasks that you point out in a simple way, in this case it is to use QGraphicsView with the QGraphicsItem:
class GraphicsRectItem(QtWidgets.QGraphicsRectItem):
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
super(GraphicsRectItem, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(GraphicsRectItem, self).mouseReleaseEvent(event)
class Paint(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
rect_item = GraphicsRectItem(0, 0, 350, 250)
rect_item.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
rect_item.setPen(QtCore.Qt.darkCyan)
rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
self.scene().addItem(rect_item)
UPDATE:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
self._pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._pos = self.rect().center()
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
painter.drawRect(r)
def mousePressEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._pos += delta
self._initial_pos = event.pos()
self.update()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
Update:
One way to implement the task is to have an element or set connected element, in this case it is a QPainterPath plus a QRectF, the first will draw the arrows, lines, etc. and the second the rectangle or central circle. After that, it is enough to move those elements according to the case.
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int, int)
def set_size_squares(self, w, h):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
Great, you are indeed clever. Thanks. I notes whenQGraphicsView
runs and autoscrolles appears but this is not the case whenQpainter
uses, can a scroll add toQpainter
?.But what is the difference betweenQPainter
andQGraphicsView
. I have seenQGraphicsView
is been used widely?
– Zar Kha
Nov 21 at 20:13
@ZarKha QGraphicsView is a widget specialized in handling items that internally uses QPainter, that is, it is a high level way to paint. The scrollbar appears because QGraphiscView is designed to handle items that may be in larger positions on your screen, it can be disabled. In conclusion with QPainter are in the stone age where it was painted manually and with QGraphicsView you are using MS paint or similar
– eyllanesc
Nov 21 at 20:19
@ZarKha If my answer helps you do not forget to mark it as correct, if you do not know how to do it then review the tour, that is the best way to thank.
– eyllanesc
Nov 21 at 20:20
My last question according to your answer, I had this code lineself._rect =
withindef paint
, in your answer you have brought it outside of function, that indeed gives some errors which I have in my private code. The event wont run! is it a way to keep it inside the function? I really need this to be solved?
– Zar Kha
Nov 21 at 20:31
@ZarKha Surely in the old answer do not point out that the rectangle was movable so the rectangle is fixed and used in the paintEvent, but in this case is dynamic although I think it can maintain the previous logic, at a time I will give an alternative. On the other hand I do not know the implementation of your private code so I will not think since you probably have other errors.
– eyllanesc
Nov 21 at 20:38
|
show 13 more comments
up vote
1
down vote
accepted
up vote
1
down vote
accepted
To make the pan you must follow the following steps:
Get the initial position in mousePressEvent
In mouseMoveEvent move the rectangle with the difference between the current position and the initial position, and update the initial position with the current position.
The implementation is as follows:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._rect = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._rect.moveCenter(self.rect().center())
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
painter.drawRect(self._rect)
def mousePressEvent(self, event):
if self._rect.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if self._rect.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
But instead of doing it Qt already offers classes that allow you to do the tasks that you point out in a simple way, in this case it is to use QGraphicsView with the QGraphicsItem:
class GraphicsRectItem(QtWidgets.QGraphicsRectItem):
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
super(GraphicsRectItem, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(GraphicsRectItem, self).mouseReleaseEvent(event)
class Paint(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
rect_item = GraphicsRectItem(0, 0, 350, 250)
rect_item.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
rect_item.setPen(QtCore.Qt.darkCyan)
rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
self.scene().addItem(rect_item)
UPDATE:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
self._pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._pos = self.rect().center()
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
painter.drawRect(r)
def mousePressEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._pos += delta
self._initial_pos = event.pos()
self.update()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
Update:
One way to implement the task is to have an element or set connected element, in this case it is a QPainterPath plus a QRectF, the first will draw the arrows, lines, etc. and the second the rectangle or central circle. After that, it is enough to move those elements according to the case.
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int, int)
def set_size_squares(self, w, h):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
To make the pan you must follow the following steps:
Get the initial position in mousePressEvent
In mouseMoveEvent move the rectangle with the difference between the current position and the initial position, and update the initial position with the current position.
The implementation is as follows:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._rect = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._rect.moveCenter(self.rect().center())
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
painter.drawRect(self._rect)
def mousePressEvent(self, event):
if self._rect.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if self._rect.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
But instead of doing it Qt already offers classes that allow you to do the tasks that you point out in a simple way, in this case it is to use QGraphicsView with the QGraphicsItem:
class GraphicsRectItem(QtWidgets.QGraphicsRectItem):
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
super(GraphicsRectItem, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(GraphicsRectItem, self).mouseReleaseEvent(event)
class Paint(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
rect_item = GraphicsRectItem(0, 0, 350, 250)
rect_item.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
rect_item.setPen(QtCore.Qt.darkCyan)
rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
self.scene().addItem(rect_item)
UPDATE:
class Paint(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Paint, self).__init__(parent)
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._width = 350
self._height = 250
self._initial_flag = False
self._initial_pos = QtCore.QPoint()
self._pos = QtCore.QPoint()
def showEvent(self, event):
if not self._initial_flag:
# set initial pos
self._pos = self.rect().center()
self._initial_flag = True
super(Paint, self).showEvent(event)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QBrush( QtCore.Qt.cyan))
painter.setPen(QtCore.Qt.darkCyan)
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
painter.drawRect(r)
def mousePressEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super(Paint, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
r = QtCore.QRect(QtCore.QPoint(), QtCore.QSize(self._width, self._height))
r.moveCenter(self._pos)
if r.contains(event.pos()):
delta = event.pos() - self._initial_pos
self._pos += delta
self._initial_pos = event.pos()
self.update()
super(Paint, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super(Paint, self).mouseReleaseEvent(event)
Update:
One way to implement the task is to have an element or set connected element, in this case it is a QPainterPath plus a QRectF, the first will draw the arrows, lines, etc. and the second the rectangle or central circle. After that, it is enough to move those elements according to the case.
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int, int)
def set_size_squares(self, w, h):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(w, h)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(v, v)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
r.moveCenter(QtCore.QPointF())
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(self._size.width()/2 + 75 ,0)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, -16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.lineTo(p)
self._path.addText(p + QtCore.QPoint(16, 0) , self.font(), "x")
self._path.moveTo(QtCore.QPointF())
p = QtCore.QPointF(0, -self._size.height()/2 - 75)
self._path.lineTo(p)
self._path.lineTo(p + QtCore.QPoint(16, 16))
self._path.lineTo(p)
self._path.moveTo(p)
self._path.lineTo(p + QtCore.QPoint(-16, 16))
self._path.addText(p + QtCore.QPoint(0, -16) , self.font(), "y")
if self._type == QtGui.QRegion.Rectangle:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -40))
self._path.lineTo(p+ QtCore.QPoint(0, 20))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
pt = r.topLeft() + QtCore.QPointF(-75, 0)
pb = r.bottomLeft() + QtCore.QPointF(-75, 0)
self._path.moveTo(pt)
self._path.lineTo(pb)
for p in (pt, pb):
self._path.moveTo(p+ QtCore.QPoint(40, 0))
self._path.lineTo(p+ QtCore.QPoint(-20, 0))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.height())
p = QtCore.QPointF(r.left() -80 - fm.width(word) , r.center().y() + 0.5*fm.height())
self._path.addText(p , self.font(), word)
if self._type == QtGui.QRegion.Ellipse:
pl = r.bottomLeft() + QtCore.QPointF(0, 75)
pr = r.bottomRight() + QtCore.QPointF(0, 75)
self._path.moveTo(pl)
self._path.lineTo(pr)
for p in (pl, pr):
self._path.moveTo(p+ QtCore.QPoint(0, -self._size.height()/2 - 20))
self._path.lineTo(p+ QtCore.QPoint(0, 10))
self._path.moveTo(p+ QtCore.QPoint(10, -10))
self._path.lineTo(p+ QtCore.QPoint(-10, 10))
word = "{}".format(self._size.width())
p = QtCore.QPointF(r.center().x() - 0.5*fm.width(word) , r.bottom() + 100)
self._path.addText(p , self.font(), word)
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
edited 2 days ago
answered Nov 21 at 19:25
eyllanesc
68.6k93052
68.6k93052
Great, you are indeed clever. Thanks. I notes whenQGraphicsView
runs and autoscrolles appears but this is not the case whenQpainter
uses, can a scroll add toQpainter
?.But what is the difference betweenQPainter
andQGraphicsView
. I have seenQGraphicsView
is been used widely?
– Zar Kha
Nov 21 at 20:13
@ZarKha QGraphicsView is a widget specialized in handling items that internally uses QPainter, that is, it is a high level way to paint. The scrollbar appears because QGraphiscView is designed to handle items that may be in larger positions on your screen, it can be disabled. In conclusion with QPainter are in the stone age where it was painted manually and with QGraphicsView you are using MS paint or similar
– eyllanesc
Nov 21 at 20:19
@ZarKha If my answer helps you do not forget to mark it as correct, if you do not know how to do it then review the tour, that is the best way to thank.
– eyllanesc
Nov 21 at 20:20
My last question according to your answer, I had this code lineself._rect =
withindef paint
, in your answer you have brought it outside of function, that indeed gives some errors which I have in my private code. The event wont run! is it a way to keep it inside the function? I really need this to be solved?
– Zar Kha
Nov 21 at 20:31
@ZarKha Surely in the old answer do not point out that the rectangle was movable so the rectangle is fixed and used in the paintEvent, but in this case is dynamic although I think it can maintain the previous logic, at a time I will give an alternative. On the other hand I do not know the implementation of your private code so I will not think since you probably have other errors.
– eyllanesc
Nov 21 at 20:38
|
show 13 more comments
Great, you are indeed clever. Thanks. I notes whenQGraphicsView
runs and autoscrolles appears but this is not the case whenQpainter
uses, can a scroll add toQpainter
?.But what is the difference betweenQPainter
andQGraphicsView
. I have seenQGraphicsView
is been used widely?
– Zar Kha
Nov 21 at 20:13
@ZarKha QGraphicsView is a widget specialized in handling items that internally uses QPainter, that is, it is a high level way to paint. The scrollbar appears because QGraphiscView is designed to handle items that may be in larger positions on your screen, it can be disabled. In conclusion with QPainter are in the stone age where it was painted manually and with QGraphicsView you are using MS paint or similar
– eyllanesc
Nov 21 at 20:19
@ZarKha If my answer helps you do not forget to mark it as correct, if you do not know how to do it then review the tour, that is the best way to thank.
– eyllanesc
Nov 21 at 20:20
My last question according to your answer, I had this code lineself._rect =
withindef paint
, in your answer you have brought it outside of function, that indeed gives some errors which I have in my private code. The event wont run! is it a way to keep it inside the function? I really need this to be solved?
– Zar Kha
Nov 21 at 20:31
@ZarKha Surely in the old answer do not point out that the rectangle was movable so the rectangle is fixed and used in the paintEvent, but in this case is dynamic although I think it can maintain the previous logic, at a time I will give an alternative. On the other hand I do not know the implementation of your private code so I will not think since you probably have other errors.
– eyllanesc
Nov 21 at 20:38
Great, you are indeed clever. Thanks. I notes when
QGraphicsView
runs and autoscrolles appears but this is not the case when Qpainter
uses, can a scroll add to Qpainter
?.But what is the difference between QPainter
and QGraphicsView
. I have seen QGraphicsView
is been used widely?– Zar Kha
Nov 21 at 20:13
Great, you are indeed clever. Thanks. I notes when
QGraphicsView
runs and autoscrolles appears but this is not the case when Qpainter
uses, can a scroll add to Qpainter
?.But what is the difference between QPainter
and QGraphicsView
. I have seen QGraphicsView
is been used widely?– Zar Kha
Nov 21 at 20:13
@ZarKha QGraphicsView is a widget specialized in handling items that internally uses QPainter, that is, it is a high level way to paint. The scrollbar appears because QGraphiscView is designed to handle items that may be in larger positions on your screen, it can be disabled. In conclusion with QPainter are in the stone age where it was painted manually and with QGraphicsView you are using MS paint or similar
– eyllanesc
Nov 21 at 20:19
@ZarKha QGraphicsView is a widget specialized in handling items that internally uses QPainter, that is, it is a high level way to paint. The scrollbar appears because QGraphiscView is designed to handle items that may be in larger positions on your screen, it can be disabled. In conclusion with QPainter are in the stone age where it was painted manually and with QGraphicsView you are using MS paint or similar
– eyllanesc
Nov 21 at 20:19
@ZarKha If my answer helps you do not forget to mark it as correct, if you do not know how to do it then review the tour, that is the best way to thank.
– eyllanesc
Nov 21 at 20:20
@ZarKha If my answer helps you do not forget to mark it as correct, if you do not know how to do it then review the tour, that is the best way to thank.
– eyllanesc
Nov 21 at 20:20
My last question according to your answer, I had this code line
self._rect =
within def paint
, in your answer you have brought it outside of function, that indeed gives some errors which I have in my private code. The event wont run! is it a way to keep it inside the function? I really need this to be solved?– Zar Kha
Nov 21 at 20:31
My last question according to your answer, I had this code line
self._rect =
within def paint
, in your answer you have brought it outside of function, that indeed gives some errors which I have in my private code. The event wont run! is it a way to keep it inside the function? I really need this to be solved?– Zar Kha
Nov 21 at 20:31
@ZarKha Surely in the old answer do not point out that the rectangle was movable so the rectangle is fixed and used in the paintEvent, but in this case is dynamic although I think it can maintain the previous logic, at a time I will give an alternative. On the other hand I do not know the implementation of your private code so I will not think since you probably have other errors.
– eyllanesc
Nov 21 at 20:38
@ZarKha Surely in the old answer do not point out that the rectangle was movable so the rectangle is fixed and used in the paintEvent, but in this case is dynamic although I think it can maintain the previous logic, at a time I will give an alternative. On the other hand I do not know the implementation of your private code so I will not think since you probably have other errors.
– eyllanesc
Nov 21 at 20:38
|
show 13 more comments
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418848%2fqpaint-with-mouse-event-panning%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown