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_())
Related
I'm setting up a new desktop widget to make my life easier at work and using QPropertyAnimation to make it pretty. Fading the app in and out doesn't seem to want to work and in typical coder fashion, it's brought my progress to a standstill.
I'm implementing QPropertyAnimation in a personalised class to make my life easier, but since it's not intially worked I've taken it back to the class code and it's still being pretty stubborn. So far I've tried.
class widget(QWidget):
def init(self):
self.setSize(QSize(300, 300))
self.setWindowOpacity(1)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
def paintEvent(self, event):
s = self.size()
qp = QPainter()
qp.begin(self)
qp.setRenderHint(QPainter.Antialiasing, True)
qp.setBrush(QColor().fromRgb(2,106,194))
qp.setPen(QColor().fromRgb(2,106,194))
qp.drawRoundRect(QRect(0,0, 300, 300), 16, 8)
qp.end()
def show(self):
self.superShow()
a = QPropertyAnimation(self, "windowOpacity")
a.setDuration(500)
a.setStartValue(1)
a.setEndValue(0)
a.start()
def hide(self):
a = QPropertyAnimation(self, "windowOpacity")
a.setDuration(500)
a.setStartValue(0)
a.setEndValue(1)
a.finished.connect(self.superHide)
a.start()
def superShow(self):
super(widget, self).show()
def superHide(self):
super(widget, self).hide()
No error messages at all it just hides and shows after the animation duration is over. No idea where to look or what to do to get it working. I've only been coding for like 3 months or so.
Your code has many errors, for example:
I don't see where you call init().
Animations are local variables that will be removed when the show and hide methods are finished, which is almost instantaneous.
etc.
Instead of changing the opacity directly I will use QGraphicsOpacityEffect, instead of using the show and close method, I will use the showEvent, hideEvent and closeEvent methods.
import sys
from PySide2.QtCore import QEasingCurve, QEventLoop, QPropertyAnimation, QRect, QSize, Qt
from PySide2.QtGui import QColor, QPainter
from PySide2.QtWidgets import QAction, QApplication, QGraphicsOpacityEffect, QWidget
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(QSize(300, 300))
# self.setWindowOpacity(1)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setContextMenuPolicy(Qt.ActionsContextMenu)
quit_action = QAction(self.tr("E&xit"), self)
quit_action.setShortcut(self.tr("Ctrl+Q"))
quit_action.triggered.connect(self.close)
self.addAction(quit_action)
effect = QGraphicsOpacityEffect(self, opacity=1.0)
self.setGraphicsEffect(effect)
self._animation = QPropertyAnimation(
self,
propertyName=b"opacity",
targetObject=effect,
duration=500,
startValue=0.0,
endValue=1.0,
)
def paintEvent(self, event):
qp = QPainter(self)
qp.setRenderHint(QPainter.Antialiasing, True)
qp.setBrush(QColor().fromRgb(2, 106, 194))
qp.setPen(QColor().fromRgb(2, 106, 194))
qp.drawRoundedRect(QRect(0, 0, 300, 300), 16, 8)
def fade_in(self):
self._animation.setDirection(QPropertyAnimation.Forward)
self._animation.start()
def fade_out(self):
loop = QEventLoop()
self._animation.finished.connect(loop.quit)
self._animation.setDirection(QPropertyAnimation.Backward)
self._animation.start()
loop.exec_()
def showEvent(self, event):
super().showEvent(event)
self.fade_in()
def closeEvent(self, event):
# fade out
self.fade_out()
super().closeEvent(event)
def hideEvent(self, event):
# fade out
self.fade_out()
super().hideEvent(event)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
How can I make a zoom effect with key input on a widget? The widget is inside a scroll area and there are some drawings made with QPainter who change with user input. The zoom would affect the length of the scrolling bar, the closer you are, the smaller the bar becomes. The zoom at minimum level should make the scroll bar as big as the widget area, so all the content in the widget could be visualized.
MRE:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QPen, QColor
import sys
class Diedrico(QWidget):
def __init__(self, parent):
super().__init__(parent)
def paintEvent(self, event):
qp = QPainter(self)
qp.setPen(QPen(QColor(Qt.black), 5))
qp.drawRect(500, 500, 1000, 1000)
class UiVentana(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(UiVentana, self).__init__(parent)
self.resize(520, 520)
self.widget_central = QtWidgets.QWidget(self)
scrol = QtWidgets.QScrollArea(self.widget_central)
scrol.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scrol.setGeometry(QtCore.QRect(10, 10, 500, 500))
scrol.setWidgetResizable(False)
contenido = QtWidgets.QWidget()
contenido.setGeometry(QtCore.QRect(0, 0, 2000, 2000))
scrol.setWidget(contenido)
self.Diedrico = Diedrico(contenido)
self.Diedrico.setGeometry(QtCore.QRect(0, 0, 2000, 2000))
self.setCentralWidget(self.widget_central)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ui = UiVentana()
ui.show()
sys.exit(app.exec_())
Why do you want to reinvent the wheel? Instead of wanting to implement the logic of the scaling feature, use the classes that already do it. In this case, a good option is to use QGraphicsView with QGraphicsScene:
Note: The shortcut standard Zoom In and Zoom Out are associated with Ctrl + + and Ctrl + -, respectively.
from PyQt5 import QtCore, QtGui, QtWidgets
class Diedrico(QtWidgets.QWidget):
def paintEvent(self, event):
qp = QtGui.QPainter(self)
pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.black), 5)
qp.setPen(pen)
qp.drawRect(500, 500, 1000, 1000)
class UiVentana(QtWidgets.QMainWindow):
factor = 1.5
def __init__(self, parent=None):
super(UiVentana, self).__init__(parent)
self._scene = QtWidgets.QGraphicsScene(self)
self._view = QtWidgets.QGraphicsView(self._scene)
self._diedrico = Diedrico()
self._diedrico.setFixedSize(2000, 2000)
self._scene.addWidget(self._diedrico)
self.setCentralWidget(self._view)
QtWidgets.QShortcut(
QtGui.QKeySequence(QtGui.QKeySequence.ZoomIn),
self._view,
context=QtCore.Qt.WidgetShortcut,
activated=self.zoom_in,
)
QtWidgets.QShortcut(
QtGui.QKeySequence(QtGui.QKeySequence.ZoomOut),
self._view,
context=QtCore.Qt.WidgetShortcut,
activated=self.zoom_out,
)
#QtCore.pyqtSlot()
def zoom_in(self):
scale_tr = QtGui.QTransform()
scale_tr.scale(UiVentana.factor, UiVentana.factor)
tr = self._view.transform() * scale_tr
self._view.setTransform(tr)
#QtCore.pyqtSlot()
def zoom_out(self):
scale_tr = QtGui.QTransform()
scale_tr.scale(UiVentana.factor, UiVentana.factor)
scale_inverted, invertible = scale_tr.inverted()
if invertible:
tr = self._view.transform() * scale_inverted
self._view.setTransform(tr)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ui = UiVentana()
ui.show()
sys.exit(app.exec_())
Update:
If you want to use + and - for ZoomIn and ZoomOut, respectively, then just change the shortcuts to:
QtWidgets.QShortcut(
QtGui.QKeySequence(QtCore.Qt.Key_Plus), # <---
self._view,
context=QtCore.Qt.WidgetShortcut,
activated=self.zoom_in,
)
QtWidgets.QShortcut(
QtGui.QKeySequence(QtCore.Qt.Key_Minus), # <---
self._view,
context=QtCore.Qt.WidgetShortcut,
activated=self.zoom_out,
)
I want to display an image in a QGraphicsView, actually in QGraphicsScene, this is the easy part, bu, when I move the cursor over the image, I want to see the X and Y coordinates lines (the yellow lines), like in this image, can anyone explain me how to do this?
To implement what you want there are 2 tasks:
Obtain the position of the cursor, for this case the flag mouseTracking is enabled so that mouseMoveEvent() is called where the position is obtained.
Paint on the top layer, for this we use the drawForeground() function.
from PyQt5 import QtCore, QtGui, QtWidgets
class GraphicsScene(QtWidgets.QGraphicsScene):
def drawForeground(self, painter, rect):
super(GraphicsScene, self).drawForeground(painter, rect)
if not hasattr(self, "cursor_position"):
return
painter.save()
pen = QtGui.QPen(QtGui.QColor("yellow"))
pen.setWidth(4)
painter.setPen(pen)
linex = QtCore.QLineF(
rect.left(),
self.cursor_position.y(),
rect.right(),
self.cursor_position.y(),
)
liney = QtCore.QLineF(
self.cursor_position.x(),
rect.top(),
self.cursor_position.x(),
rect.bottom(),
)
for line in (linex, liney):
painter.drawLine(line)
painter.restore()
def mouseMoveEvent(self, event):
self.cursor_position = event.scenePos()
self.update()
super(GraphicsScene, self).mouseMoveEvent(event)
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(GraphicsView, self).__init__(parent)
self.setMouseTracking(True)
scene = GraphicsScene(QtCore.QRectF(-200, -200, 400, 400), self)
self.setScene(scene)
if __name__ == "__main__":
import sys
import random
app = QtWidgets.QApplication(sys.argv)
w = GraphicsView()
for _ in range(4):
r = QtCore.QRectF(
*random.sample(range(-200, 200), 2),
*random.sample(range(50, 150), 2)
)
it = w.scene().addRect(r)
it.setBrush(QtGui.QColor(*random.sample(range(255), 3)))
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
I've been recently learning pyqt5 as my first gui framework. So far I have been experimenting with QtStackedLayout. I currently have two window screens, one created inside the UI class and another in another separate class. I have two concerns:
Everything was working until I started experimenting on adding a background image for Window 1. There is no image displayed but the code runs ok.
There is this small fraction of time in the beginning where window one will get displayed first until it gets loaded to the mainwindow, I tried passing self during instantiation of the object to sert as some kind of parent to prevent this but I think I'm not doing it right.
See below code (I have bad import statements, I will sort it out)
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Ui(QWidget):
def setupUi(self, Main, width, height):
self.stack = QStackedLayout()
self.window_1 = WindowOne(width, height)
self.window_2 = QWidget(self)
self.window_2_UI()
self.stack.addWidget(self.window_1)
self.stack.addWidget(self.window_2)
# Only one button
self.btn = QPushButton("Change window", self)
# Create the central widget of your Main Window
self.main_widget = QWidget(self)
layout = QVBoxLayout(self.main_widget)
layout.addLayout(self.stack)
layout.addWidget(self.btn)
self.setCentralWidget(self.main_widget)
self.btn.clicked.connect(self.change_window)
def change_window(self):
if self.stack.currentIndex() == 0:
self.stack.setCurrentIndex(1)
else:
self.stack.setCurrentIndex(0)
def window_2_UI(self):
label = QLabel("In Window 2", self.window_2)
class WindowOne(QWidget):
def __init__(self, width, height):
super().__init__()
self.set_bg(width, height)
self.set_label()
# self.setStyleSheet("background-image: url(:resource/images/blue_bg.jpg)")
def set_label(self):
label = QLabel("In Window 1", self)
def set_bg(self, w, h):
oImage = QImage("resource/images/blue_bg.jpg")
sImage = oImage.scaled(QSize(w, h))
palette = QPalette()
palette.setBrush(10, QBrush(sImage))
self.setPalette(palette)
class Main(QMainWindow, Ui):
def __init__(self):
super().__init__()
self.w_width = 480
self.w_height = 720
self.resize(self.w_width, self.w_height)
self.init_ui()
self.setupUi(self, self.w_width, self.w_height)
def init_ui(self):
self.center()
self.setWindowTitle('Main Window')
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
if __name__ == "__main__":
app = QApplication(sys.argv)
M = Main()
M.show()
sys.exit(app.exec())
By default only the window (which is different to a widget) will use the background color of QPalette, if you want a widget to use the background color of QPalette you must enable the autoFillBackground property.
# ...
self.set_label(width, height)
self.setAutoFillBackground(True)
# ...
Although your code is a little messy, for example you establish that certain methods receive certain parameters but you never use them. Finally I think you want the background of the image to be re-scale using the size of the window so I have override the resizeEvent() method so that scaling takes the size of the window.
Considering all the above, I have improved your code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.m_stacked_layout = QtWidgets.QStackedLayout()
self.widget_1 = WidgetOne()
self.widget_2 = QtWidgets.QWidget()
self.widget_2_UI()
self.m_stacked_layout.addWidget(self.widget_1)
self.m_stacked_layout.addWidget(self.widget_2)
button = QtWidgets.QPushButton(
"Change window", clicked=self.change_window
)
lay = QtWidgets.QVBoxLayout(self)
lay.addLayout(self.m_stacked_layout)
lay.addWidget(button)
#QtCore.pyqtSlot()
def change_window(self):
ix = self.m_stacked_layout.currentIndex()
self.m_stacked_layout.setCurrentIndex(1 if ix == 0 else 0)
def widget_2_UI(self):
label = QtWidgets.QLabel("In Window 2", self.widget_2)
class WidgetOne(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setAutoFillBackground(True)
self.set_label()
self.m_image = QtGui.QImage("resource/images/blue_bg.jpg")
def set_label(self):
label = QtWidgets.QLabel("In Window 1", self)
def resizeEvent(self, event):
palette = self.palette()
sImage = self.m_image.scaled(event.size())
palette.setBrush(10, QtGui.QBrush(sImage))
self.setPalette(palette)
super(WidgetOne, self).resizeEvent(event)
class Main(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
widget = Widget()
self.setCentralWidget(widget)
self.resize(480, 720)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec())
I want to move the QLabel with the mouse movement (not like Drag&drop, 'object' disappears while moving). Clicked - moved - released. I did it to some extent, but I ran into a problem. QLabel shrinks as I move it or even disappears (like shrinks to 0 width). How to fix it or what more correct approach to do it?
(self.label_pos is needed to keep the mouse position relative inside self.label)
Or its just monitor's refresh rate issue? But in photoshop's gradient editor, that little color stop isn't shrikns. It's choppy because of refresh rate, but always the same size.
This is what I want to see, recorded using a screen capture program. The same thing I see in Photoshop
This is what I see, recorded on my phone. The quality is poor, but the difference is clearly visible anyway.
This Photoshop is also captured on my phone, here the “object” remains the same size, as in the example made using screen capture
Here is code from eyllanesc's answer, 'object' still shrinks :(
self.label = QLabel(self)
self.label.move(100, 100)
self.label.mousePressEvent = self.mouse_on
self.label.mouseReleaseEvent = self.mouse_off
def mouse_on(self, event):
self.bool = True
self.label_pos = event.pos()
def mouse_off(self, event):
self.bool = False
def mouseMoveEvent(self, event):
if self.bool:
self.label.move(event.x()-self.label_pos.x(), event.y()-self.label_pos.y())
Instead of using a QLabel I recommend using QGraphicsRectItem with a QGraphicsView since it is specialized in this type of tasks:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
self.setBackgroundBrush(brush)
rect_item = self.scene().addRect(
QtCore.QRectF(QtCore.QPointF(), QtCore.QSizeF(40, 80))
)
rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
rect_item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.setFixedSize(640, 480)
w.show()
sys.exit(app.exec_())
If you want to just scroll horizontally then overwrite the itemChange method of QGraphicsItem:
from PyQt5 import QtCore, QtGui, QtWidgets
class HorizontalItem(QtWidgets.QGraphicsRectItem):
def __init__(self, rect, parent=None):
super(HorizontalItem, self).__init__(rect, parent)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
def itemChange(self, change, value):
if (
change == QtWidgets.QGraphicsItem.ItemPositionChange
and self.scene()
):
return QtCore.QPointF(value.x(), self.pos().y())
return super(HorizontalItem, self).itemChange(change, value)
class Widget(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
self.setBackgroundBrush(brush)
rect_item = HorizontalItem(
QtCore.QRectF(QtCore.QPointF(), QtCore.QSizeF(40, 80))
)
rect_item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
self.scene().addItem(rect_item)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.setFixedSize(640, 480)
w.show()
sys.exit(app.exec_())
In the following code there is an example similar to what you want:
from PyQt5 import QtCore, QtGui, QtWidgets
class HorizontalItem(QtWidgets.QGraphicsRectItem):
def __init__(self, rect, parent=None):
super(HorizontalItem, self).__init__(rect, parent)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
def itemChange(self, change, value):
if (
change == QtWidgets.QGraphicsItem.ItemPositionChange
and self.scene()
):
return QtCore.QPointF(value.x(), self.pos().y())
return super(HorizontalItem, self).itemChange(change, value)
class Widget(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
self.setBackgroundBrush(brush)
self.setFixedSize(640, 480)
size = self.mapToScene(self.viewport().rect()).boundingRect().size()
r = QtCore.QRectF(QtCore.QPointF(), size)
self.setSceneRect(r)
rect = QtCore.QRectF(
QtCore.QPointF(), QtCore.QSizeF(0.8 * r.width(), 80)
)
rect.moveCenter(r.center())
rect_item = self.scene().addRect(rect)
rect_item.setBrush(QtGui.QBrush(QtGui.QColor("salmon")))
item = HorizontalItem(
QtCore.QRectF(
rect.bottomLeft() + QtCore.QPointF(0, 20), QtCore.QSizeF(20, 40)
)
)
item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
self.scene().addItem(item)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())