For this question, I am referring to the code from https://gist.github.com/zhanglongqi/78d7b5cd24f7d0c42f5d116d967923e7
The code above shows how to draw an overlay onto current widget, which works fine. But I want to transfer parameters into the overlay class, and use these variables to trigger the paintEvent there in the overlay class.
I modified the code as follows...
# -*- coding:utf-8 -*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class overlay(QWidget):
def __init__(self, parent=None):
super(overlay, self).__init__(parent)
palette = QPalette(self.palette())
palette.setColor(palette.Background, Qt.transparent)
self.setPalette(palette)
#pyqtSlot(int)
def getValue(self, a): # variable is received.
self.a = a
print(self.a)
self.update()
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(event.rect(), QBrush(QColor(255, 255, 255, 127)))
painter.drawLine(self.width() / 8, self.height() / 8, 7 * self.width() / 8, 7 * self.height() / 8)
painter.drawLine(self.width() / 8, 7 * self.height() / 8, 7 * self.width() / 8, self.height() / 8)
painter.drawLine(self.a , self.a+50, self.a +10, self.a + 100) #Here I want to draw the line using parameter.
painter.setPen(QPen(Qt.NoPen))
class windowOverlay(QWidget):
signal = pyqtSignal(int)
def __init__(self, parent=None):
super(windowOverlay, self).__init__(parent)
self.editor = QTextEdit()
self.editor.setPlainText("OVERLAY" * 100)
self.button = QPushButton("Toggle Overlay")
self.verticalLayout = QVBoxLayout(self)
self.verticalLayout.addWidget(self.editor)
self.verticalLayout.addWidget(self.button)
self.overlay = overlay(self.editor)
self.overlay.hide()
self.button.clicked.connect(self.switch_and_send_signal)
def switch_and_send_signal(self):
if self.overlay.isVisible():
self.overlay.setVisible(False)
else:
self.overlay.setVisible(True)
self.obj = overlay()
a = 100
self.signal.connect(self.obj.getValue)
self.signal.emit(a)
self.signal.disconnect(self.obj.getValue)
def resizeEvent(self, event):
self.overlay.resize(event.size())
event.accept()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = windowOverlay()
main.show()
sys.exit(app.exec_())
The Problem:
It seems the parameter is transferred, but the paintEvent is not updated. The parameter does not arrive the paintEvent. What am I doing wrong?
Thanks for the help!
The problem is caused because you are creating an overlay object that is not connected, what you must do is use the same object as I show below:
class windowOverlay(QWidget):
signal = pyqtSignal(int)
def __init__(self, parent=None):
super(windowOverlay, self).__init__(parent)
self.editor = QTextEdit()
self.editor.setPlainText("OVERLAY" * 100)
self.button = QPushButton("Toggle Overlay")
self.verticalLayout = QVBoxLayout(self)
self.verticalLayout.addWidget(self.editor)
self.verticalLayout.addWidget(self.button)
self.overlay = overlay(self.editor)
self.overlay.hide()
self.signal.connect(self.overlay.getValue)
self.button.clicked.connect(self.switch_and_send_signal)
def switch_and_send_signal(self):
self.overlay.setVisible(not self.overlay.isVisible())
a = 100
self.signal.emit(a)
def resizeEvent(self, event):
self.overlay.resize(event.size())
event.accept()
Related
I want to update the opacity of some QGraphicsItem after the mouse clicking. As suggested from other solution, the QGraphicScene manually update the GraphicsItem after the mouser press event. I have tried different setOpacity() and update() in QGraphicsScene and QGraphicsItem. But none works and do not know what is wrong.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
CUBE_POS = {
"a":( 8.281, 18.890),
"b":( 8.668, 23.692),
"c":( 21.493, 23.423),
"d":( 21.24, 15.955),
}
class CubeItem(QGraphicsItem):
def __init__(self, x, y, parent=None):
super(CubeItem,self).__init__(parent)
self.x = x
self.y = y
self.polygon = QPolygonF([
QPointF(self.x-10, self.y-10), QPointF(self.x-10, self.y+10),
QPointF(self.x+10, self.y+10), QPointF(self.x+10, self.y-10),
])
self._painter = QPainter()
##Estimate the drawing area
def boundingRect(self):
return QRectF(self.x-10, self.y-10, 20, 20)
##Real Shape of drawing area
def shape(self):
path = QPainterPath()
path.addRect(self.x-10, self.y-10, 20, 20)
return path
##paint function called by graphicview
def paint(self, painter, option, widget):
painter.setBrush(Qt.red)
painter.setOpacity(0.2)
painter.drawRect(self.x-10, self.y-10, 20, 20)
self._painter = painter
def activate(self):
try:
#self._painter.setOpacity(1.0)
self.setOpacity(1.0)
self.update()
except ValueError as e:
print(e)
class TagScene(QGraphicsScene):
def __init__(self, parent=None):
super(TagScene, self).__init__(parent)
self.cubes_items_ref = {}
self.addCubes()
def addCubes(self):
for cube in CUBE_POS:
newCube = CubeItem(CUBE_POS[cube][0]*15,
CUBE_POS[cube][1]*15)
self.addItem(newCube)
self.cubes_items_ref[cube] = newCube
def mousePressEvent(self, event):
print("mouse pressed")
#for cube in self.cubes_items_ref:
# self.cubes_items_ref[cube].setOpacity(1.0)
# #self.cubes_items_ref[cube].activate()
#self.update(QRectF(0,0,500,500))
for cube in self.items():
cube.setOpacity(1.0)
self.update(QRectF(0,0,500,500))
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
layout = QHBoxLayout()
self.scene = TagScene()
self.view = QGraphicsView(self.scene)
self.scene.setSceneRect(QRectF(0,0,500,500))
layout.addWidget(self.view)
self.widget = QWidget()
self.widget.setLayout(layout)
self.setCentralWidget(self.widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
test = MainWindow()
test.show()
sys.exit(app.exec_())
The problem is that when you overwrite the paint method of the QGraphicsItem you are setting a constant opacity
def paint(self, painter, option, widget):
painter.setBrush(Qt.red)
painter.setOpacity(0.2) # <-- this line is the problem
painter.drawRect(self.x-10, self.y-10, 20, 20)
self._painter = painter
And you will not use the opacity that the QPainter already passes paint() method.
If you want to set an initial opacity you must do it in the constructor.On the other hand the setOpacity() method already calls update() so it is not necessary to make an explicit call.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CUBE_POS = {
"a": (8.281, 18.890),
"b": (8.668, 23.692),
"c": (21.493, 23.423),
"d": (21.24, 15.955),
}
class CubeItem(QtWidgets.QGraphicsItem):
def __init__(self, x, y, parent=None):
super(CubeItem, self).__init__(parent)
self.x = x
self.y = y
self.polygon = QtGui.QPolygonF(
[
QtCore.QPointF(self.x - 10, self.y - 10),
QtCore.QPointF(self.x - 10, self.y + 10),
QtCore.QPointF(self.x + 10, self.y + 10),
QtCore.QPointF(self.x + 10, self.y - 10),
]
)
self.setOpacity(0.2) # initial opacity
##Estimate the drawing area
def boundingRect(self):
return QtCore.QRectF(self.x - 10, self.y - 10, 20, 20)
##Real Shape of drawing area
def shape(self):
path = QtGui.QPainterPath()
path.addRect(self.boundingRect())
return path
##paint function called by graphicview
def paint(self, painter, option, widget):
painter.setBrush(QtCore.Qt.red)
painter.drawRect(self.x - 10, self.y - 10, 20, 20)
class TagScene(QtWidgets.QGraphicsScene):
def __init__(self, parent=None):
super(TagScene, self).__init__(parent)
self.cubes_items_ref = {}
self.addCubes()
def addCubes(self):
for cube in CUBE_POS:
newCube = CubeItem(CUBE_POS[cube][0] * 15, CUBE_POS[cube][1] * 15)
self.addItem(newCube)
self.cubes_items_ref[cube] = newCube
def mousePressEvent(self, event):
for cube in self.items():
cube.setOpacity(1.0) # update opacity
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
layout = QtWidgets.QHBoxLayout()
self.scene = TagScene()
self.view = QtWidgets.QGraphicsView(self.scene)
self.scene.setSceneRect(QtCore.QRectF(0, 0, 500, 500))
layout.addWidget(self.view)
self.widget = QtWidgets.QWidget()
self.widget.setLayout(layout)
self.setCentralWidget(self.widget)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
test = MainWindow()
test.show()
sys.exit(app.exec_())
I have the following PyQtGraph program, which makes a red square "move" when moving a slider:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QSlider
from pyqtgraph import (
mkBrush,
mkPen,
GraphicsObject,
QtGui,
PlotWidget,
)
class SquareItem(GraphicsObject):
def __init__(self):
super().__init__()
self.position_picture = QtGui.QPicture()
def paint(self, p, *args):
p.drawPicture(0, 0, self.position_picture)
def boundingRect(self):
return QtCore.QRectF(-5, -5, 20, 10)
def update_position(self, x):
self.position_picture = QtGui.QPicture()
painter = QtGui.QPainter(self.position_picture)
painter.scale(1, -1)
painter.setBrush(mkBrush('r'))
painter.setPen(mkPen(None))
painter.drawRect(QtCore.QRectF(x, 0, 1, 1))
painter.end()
self.informViewBoundsChanged()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle('Micromouse maze simulator')
self.resize(600, 600)
frame = QtWidgets.QFrame()
layout = QtWidgets.QVBoxLayout(frame)
self.graphics = PlotWidget()
self.graphics.setAspectLocked()
self.item = SquareItem()
self.graphics.addItem(self.item)
self.slider = QSlider(QtCore.Qt.Horizontal)
self.slider.setSingleStep(1)
self.slider.setPageStep(10)
self.slider.setRange(0, 10)
self.slider.setTickPosition(QSlider.TicksAbove)
self.slider.valueChanged.connect(self.slider_value_changed)
self.slider.setValue(1)
layout.addWidget(self.graphics)
layout.addWidget(self.slider)
self.setCentralWidget(frame)
def slider_value_changed(self, value):
self.item.update_position(value)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
Everything seems to work fine, but if I zoom in/out and then move the slider again the square position is no longer updated (i.e.: the square is not re-drawn).
How can I fix that?
Updates
I am using a square to simplify the problem. In reality, I do not only change position, but I can also draw different shapes, so using setPos() is not really an option.
You should not update the painting if you want to change position, you should only use setPos(). the paint() function takes boundingRect() as a reference so when moving the graph you are moving it in that coordinate system instead of the coordinate system of PlotWidget.
class SquareItem(GraphicsObject):
def paint(self, p, *args):
p.setBrush(mkBrush('r'))
p.setPen(mkPen(None))
p.drawRect(self.boundingRect())
def boundingRect(self):
return QtCore.QRectF(0, 0, 1, 1)
def update_position(self, x):
self.setPos(x, 0)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle('Micromouse maze simulator')
self.resize(600, 600)
frame = QtWidgets.QFrame()
layout = QtWidgets.QVBoxLayout(frame)
self.graphics = PlotWidget()
self.graphics.setAspectLocked()
self.item = SquareItem()
self.graphics.addItem(self.item)
self.graphics.setRange(rect=QtCore.QRectF(-10, -10, 20, 20))
self.slider = QSlider(QtCore.Qt.Horizontal)
self.slider.setSingleStep(1)
self.slider.setPageStep(10)
self.slider.setRange(0, 10)
self.slider.setTickPosition(QSlider.TicksAbove)
self.slider.valueChanged.connect(self.slider_value_changed)
self.slider.setValue(1)
layout.addWidget(self.graphics)
layout.addWidget(self.slider)
self.setCentralWidget(frame)
def slider_value_changed(self, value):
self.item.update_position(value)
If you are not going to use signals it is advisable to use objects that inherit from QGraphicsItem instead of QGraphicsObject, for example you could use QGraphicsRectItem:
import sys
from PyQt5 import QtCore, QtWidgets
from pyqtgraph import (
mkBrush,
mkPen,
GraphicsObject,
QtGui,
PlotWidget,
)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle('Micromouse maze simulator')
self.resize(600, 600)
frame = QtWidgets.QFrame()
layout = QtWidgets.QVBoxLayout(frame)
self.graphics = PlotWidget()
self.graphics.setAspectLocked()
self.item = QtWidgets.QGraphicsRectItem(0, 0, 1, 1)
self.item.setBrush(mkBrush('r'))
self.item.setPen(mkPen(None))
self.graphics.addItem(self.item)
self.graphics.setRange(rect=QtCore.QRectF(-10, -10, 20, 20))
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.slider.setSingleStep(1)
self.slider.setPageStep(10)
self.slider.setRange(0, 10)
self.slider.setTickPosition(QtWidgets.QSlider.TicksAbove)
self.slider.valueChanged.connect(self.slider_value_changed)
self.slider.setValue(1)
layout.addWidget(self.graphics)
layout.addWidget(self.slider)
self.setCentralWidget(frame)
def slider_value_changed(self, value):
self.item.setPos(value, 0)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
update:
If you want to redraw you should call update():
import sys
from PyQt5 import QtCore, QtWidgets
from pyqtgraph import (
mkBrush,
mkPen,
GraphicsObject,
QtGui,
PlotWidget,
)
class SquareItem(GraphicsObject):
colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k', 'w', 'FF0', 'AA0', '0AA']
def __init__(self):
super().__init__()
self.mColor = SquareItem.colors[0]
def paint(self, p, *args):
p.setBrush(mkBrush(self.mColor))
p.setPen(mkPen(None))
p.drawRect(self.boundingRect())
def boundingRect(self):
return QtCore.QRectF(0, 0, 1, 1)
def update_draw(self, x):
self.mColor = SquareItem.colors[x]
self.update()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle('Micromouse maze simulator')
self.resize(600, 600)
frame = QtWidgets.QFrame()
layout = QtWidgets.QVBoxLayout(frame)
self.graphics = PlotWidget()
self.graphics.setAspectLocked()
self.item = SquareItem()
self.graphics.addItem(self.item)
self.graphics.setRange(rect=QtCore.QRectF(-10, -10, 20, 20))
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.slider.setSingleStep(1)
self.slider.setPageStep(10)
self.slider.setRange(0, 10)
self.slider.setTickPosition(QtWidgets.QSlider.TicksAbove)
self.slider.valueChanged.connect(self.item.update_draw)
self.slider.setValue(1)
layout.addWidget(self.graphics)
layout.addWidget(self.slider)
self.setCentralWidget(frame)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
I'm trying to paint some ticks in my custom progressbar but I'm not clear on why the line isn't showing up at all?
import sys
import os
sys.path.append('Z:\\pipeline\\site-packages')
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from PySide import QtGui, QtCore
class QProgressBarPro(QtGui.QProgressBar):
progressClicked = QtCore.Signal()
progressChanging = QtCore.Signal()
progressChanged = QtCore.Signal()
def __init__(self, parent=None):
super(QProgressBarPro, self).__init__(parent)
self.default_value = 50.0
self.lmb_pressed = False
self.setFormat('%p')
self.setRange(0.0, 100.0)
self.stepEnabled = True
self.step = 5
self.setToolTip('<strong>Press+Hold+Ctrl</strong> for percise values<br><strong>Right-Click</strong> to reset default value')
def step_round(self, x, base=5):
return int(base * round(float(x)/base))
def set_value_from_cursor(self, xpos):
width = self.frameGeometry().width()
percent = float(xpos) / width
val = self.maximum() * percent
if self.stepEnabled:
modifiers = QtGui.QApplication.keyboardModifiers()
if modifiers != QtCore.Qt.ControlModifier:
val = self.step_round(val, self.step)
self.setValue(val)
def mousePressEvent(self, event):
self.progressClicked.emit()
mouse_button = event.button()
if mouse_button == QtCore.Qt.RightButton:
self.setValue(self.default_value)
else:
xpos = event.pos().x()
self.set_value_from_cursor(xpos)
self.lmb_pressed = True
self.progressChanging.emit()
def mouseReleaseEvent(self, event):
self.lmb_pressed = False
self.progressChanged.emit()
def mouseMoveEvent(self, event):
if self.lmb_pressed:
xpos = event.pos().x()
self.set_value_from_cursor(xpos)
self.progressChanging.emit()
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.drawLine(10, 0, 10, 10)
QtGui.QProgressBar.paintEvent(self, event)
# DEMO
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.ui_progress = QProgressBarPro()
self.ui_progress.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.ui_progress.setValue(10)
gdl = QtGui.QVBoxLayout()
gdl.addWidget(self.ui_progress)
self.setLayout(gdl)
self.resize(300, 300)
self.setWindowTitle('Tooltips')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You need to change your paintEvent function.
I wrote a first approach that provides same result as in your image:
def paintEvent(self, event):
QtGui.QProgressBar.paintEvent(self, event)
painter = QtGui.QPainter(self)
brush = QtGui.QBrush(QtCore.Qt.SolidPattern)
# Set gray color
brush.setColor(QtGui.QColor(204,204,204))
painter.setPen(QtGui.QPen(brush, 2, QtCore.Qt.SolidLine,QtCore.Qt.RoundCap))
#print(str(self.width())+","+str(self.height()))
progressbarwidth = self.width()
progressbarheight = self.height()
## Drawing one vertical line each 1/5
painter.drawLine(progressbarwidth*1/5, 0, progressbarwidth*1/5, progressbarheight)
painter.drawLine(progressbarwidth*2/5, 0, progressbarwidth*2/5, progressbarheight)
painter.drawLine(progressbarwidth*3/5, 0, progressbarwidth*3/5, progressbarheight)
painter.drawLine(progressbarwidth*4/5, 0, progressbarwidth*4/5, progressbarheight)
The achieved outcome is shown here.
Hi I want to add the QProgressBar behind the QLIneEdit, just like it is in Safari Browser or IE, So here is my starting point how can I hook the ProgressBar and MyLineEdit together so that when user is done entering the path the progress bar should show the progress while the path is opened !!!
from PyQt4 import QtGui, QtCore
import sys
class ProgressBar(QtGui.QProgressBar):
""" docstring for ProgressBar
"""
def __init__(self, parent=None):
super(ProgressBar, self).__init__(parent)
self.timer = QtCore.QBasicTimer()
self.step = 0
self.doAction()
def timerEvent(self, e):
if self.step >= 100:
self.timer.stop()
return
self.step = self.step + 15
self.setValue(self.step)
def doAction(self):
if self.timer.isActive():
self.timer.stop()
else:
self.timer.start(100, self)
class MyLineEdit(QtGui.QLineEdit):
""" docstring for MyLineEdit
"""
def __init__(self, parent=None):
super(MyLineEdit, self).__init__(parent)
# I want to hook this bar at the backgroind of MyLineEdit
pbar = ProgressBar()
class Example(QtGui.QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.pbar = ProgressBar(self)
self.editbx = MyLineEdit(self.pbar)
newPalette = QtGui.QPalette()
newPalette.setColor(self.editbx.backgroundRole(), QtCore.Qt.transparent)
self.editbx.setPalette(newPalette)
self.editbx.setText("Defaukt text set")
self.editbx.setStyleSheet("QLineEdit { border:none;}")
self.pbar.setStyleSheet("QProgressBar {border:none;}")
self.initUI()
def initUI(self):
# self.pbar.setGeometry(30, 40, 200, 25)
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle('QtGui.QProgressBar')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
win = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I also looking forward to add a QCombobox in place of text entered so it can list the other existing folders, not the way QCompleter uses though becuase it doesnt has look of QCombobox, and I do not want to allow user to enter anything that doesnt exists.
Any help would be greatly appreciated.
I've attached an example of a QLineEdit with a progress bar behind it. It was heavily influenced by this post: http://www.qtcentre.org/threads/54758-Progress-bar-form-QLineEdit-issue
Basically you have to manage painting yourself. Unfortunately it didn't seem to work when I tried to do the same thing with a QComboBox. I would suggest posting a new question specifically about painting a progress bar on a QComboBox once you get up to it!
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyLineEdit(QLineEdit):
def __init__(self, parent=None):
QLineEdit.__init__(self, parent)
self.timer = QBasicTimer()
self.step = 0
self.doAction()
def timerEvent(self, e):
if self.step >= 100:
self.timer.stop()
return
self.step = self.step + 10
self.repaint()
def doAction(self):
if self.timer.isActive():
self.timer.stop()
else:
self.timer.start(1000, self)
def generateGradient(self, color):
gradient = QLinearGradient(0, 0, 0, self.height());
m_defaultBaseColor = self.palette().color(QPalette.Base)
gradient.setColorAt(0, m_defaultBaseColor)
gradient.setColorAt(0.15, color.lighter(120))
gradient.setColorAt(0.5, color)
gradient.setColorAt(0.85, color.lighter(120))
gradient.setColorAt(1, m_defaultBaseColor)
return gradient
def paintEvent(self, event):
p = QPainter(self)
panel = QStyleOptionFrameV2()
self.initStyleOption(panel)
self.style().drawPrimitive(QStyle.PE_PanelLineEdit, panel, p, self)
# an alternative to painting the QLineEdit is to do it only when the widget has focus and the progress bar is finished
#if self.hasFocus() or self.step >= 100: QLineEdit.paintEvent(self, event)
# however I've chosen to paint it always
QLineEdit.paintEvent(self, event)
painter = QPainter(self)
lenap = QStyleOptionFrameV2()
self.initStyleOption(lenap)
backgroundRect = self.style().subElementRect(QStyle.SE_LineEditContents, lenap, self)
# some alternative if statements you might like to use instead...
#
# if not self.hasFocus() and self.step < 100:
# if self.step < 100:
if True:
loadingColor = QColor(116,192,250)
painter.setBrush(self.generateGradient(loadingColor))
painter.setPen(Qt.transparent)
mid = int(backgroundRect.width()/100.0*self.step)
progressRect = QRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height())
painter.drawRect(progressRect)
painter.setPen(Qt.SolidLine)
painter.drawText(backgroundRect, Qt.AlignLeft|Qt.AlignVCenter, " " + self.text())
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self._control = QWidget()
self.setCentralWidget(self._control)
l = QVBoxLayout(self._control)
e = MyLineEdit()
l.addWidget(e)
b = QPushButton('a')
l.addWidget(b)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
import sys, csv
from PySide import QtGui, QtCore
from mainStrato import *
X_START = 10
Y_START = 15
MAX_WIDTH = 1350
MAX_LENGH = 1650
ZOOM = 2.5
WIDTH_PEZZO = 150
LENGH_PEZZO = 600
CENTER_OFFSET_X = 15
CENTER_OFFSET_Y = 0
class Strato(QtGui.QMainWindow, Ui_MainWindow):
#Apre il file CSV e copia le singole righe in una lista
def __init__(self, parent=None):
super(Strato, self).__init__(parent)
self.setupUi(self)
def paintEvent(centralwidget, e):
qp = QtGui.QPainter()
qp.begin(centralwidget)
print "paint event"
qp.end()
self.drawRectangles(qp)
def drawRectangles(self, qp):
color = QtGui.QColor(0, 0, 0)
color.setNamedColor('#d4d4d4')
qp.setPen(color)
qp.setBrush(QtGui.QColor(200, 0, 0))
coordCarro = QtCore.QRectF(X_START, Y_START, MAX_WIDTH/ZOOM, MAX_LENGH/ZOOM)
qp.drawRect(coordCarro)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Strato()
window.show()
sys.exit(app.exec_())
mainstrato is a file generated from pyside-uic.
I got an error Object not defined on calling self.drawRectangles or any other function in Strato called inside paint event?
If I copy the drawRectangles code in paint event it works!
Suggestion? What's wrong?
You are missing self in the paintEvent definition - and I assume that centralwidget is part of your UI class, so that should be accessible through self.centralwidget (since you are inheriting from your UI class). Besides self, paintEvent has only one parameter, the event object. Also, you must not call qp.end() before you have drawn your rectangles. Finally, you need to properly indent your code - but that could also be a copy&paste issue when posting the question. Try
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self.centralwidget)
print "paint event"
self.drawRectangles(qp)
qp.end()
And, finally, you should not paint on other widgets from within one Widget's paintEvent. Instead, subclass QWidget and overide its paint event. The following sscce works (all non-relevant code removed):
#!/usr/bin/python
import sys
from PySide import QtGui, QtCore
X_START = 10
Y_START = 15
MAX_WIDTH = 1350
MAX_LENGH = 1650
ZOOM = 2.5
WIDTH_PEZZO = 150
LENGH_PEZZO = 600
CENTER_OFFSET_X = 15
CENTER_OFFSET_Y = 0
class PaintWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(PaintWidget, self).__init__(parent)
def paintEvent(self, e):
qp = QtGui.QPainter(self)
print("paint event")
self.drawRectangles(qp)
def drawRectangles(self, qp):
color = QtGui.QColor(0, 0, 0)
color.setNamedColor('#d4d4d4')
qp.setPen(color)
qp.setBrush(QtGui.QColor(200, 0, 0))
coordCarro = QtCore.QRectF(X_START, Y_START, MAX_WIDTH/ZOOM, MAX_LENGH/ZOOM)
qp.drawRect(coordCarro)
class Strato(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Strato, self).__init__(parent)
self.centralwidget = PaintWidget(self)
self.setCentralWidget(self.centralwidget)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Strato()
window.show()
sys.exit(app.exec_())