Use QItemDelegate to draw icon - python

I want to draw a second icon in a single column, on the right side of the standard painting event of that column. You can see below I draw a red icon on the far right side of the items in column 3. How would I go about doing this using a QItemDelegate? I would prefer the default paint even still happens in order to pain the decoration role and display role text.
import os, sys, pprint
from Qt import QtGui, QtWidgets, QtCore
class Window(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.resize(500, 400)
self.uiItems = QtWidgets.QTreeView()
self.uiItems.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.uiItems.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.uiItems.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.uiItems.setModel(QtGui.QStandardItemModel())
self.uiItems.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.uiItems)
self.setLayout(self.layout)
for i in range(3):
parent1 = QtGui.QStandardItem('Parente Item ' + str(i))
parent2 = QtGui.QStandardItem()
parent3 = QtGui.QStandardItem()
self.uiItems.model().appendRow([parent1, parent2, parent3])
for x in range(3):
col1 = QtGui.QStandardItem('Child Item' + str(x))
col2 = QtGui.QStandardItem('Item' + str(x))
col3 = QtGui.QStandardItem('Item' + str(x))
col3.setData(self.createDotPixmap(), role=QtCore.Qt.DecorationRole)
parent1.appendRow([col1,col2,col3])
self.uiItems.expandAll()
def createRectPixmap(self, col=QtGui.QColor(240,50,50)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(150,20,20), 1.25))
painter.drawRect(pxSize)
painter.end()
return px
def createDotPixmap(self, col=QtGui.QColor(128,128,128)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(15,15,15), 1.25))
painter.drawEllipse(pxSize)
painter.end()
return px
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Window()
ex.show()
app.exec_()

The solution is:
import os, sys, pprint
from Qt import QtGui, QtWidgets, QtCore
DecorationRole2 = QtCore.Qt.UserRole + 1000
class IconDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter, option, index):
super(self.__class__, self).paint(painter, option, index)
value = index.data(DecorationRole2)
if value:
margin = 10
mode = QtGui.QIcon.Normal
if not (option.state & QtWidgets.QStyle.State_Enabled):
mode = QtGui.QIcon.Disabled
elif option.state & QtWidgets.QStyle.State_Selected:
mode = QtGui.QIcon.Selected
if isinstance(value, QtGui.QPixmap):
icon = QtGui.QIcon(value)
option.decorationSize = value.size() / value.devicePixelRatio()
elif isinstance(value, QtGui.QColor):
pixmap = QtGui.QPixmap(option.decorationSize)
pixmap.fill(value)
icon = QtGui.QIcon(pixmap)
elif isinstance(value, QtGui.Image):
icon = QtGui.QIcon(QtGui.QPixmap.fromImage(value))
option.decorationSize = value.size() / value.devicePixelRatio()
elif isinstance(value, QtGui.QIcon):
state = QtGui.QIcon.On if option.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
actualSize = option.icon.actualSize(option.decorationSize, mode, state)
option.decorationSize = QtCore.QSize(min(option.decorationSize.width(), actualSize.width()), min(option.decorationSize.height(), actualSize.height()))
r = QtCore.QRect(QtCore.QPoint(), option.decorationSize)
r.moveCenter(option.rect.center())
r.setRight(option.rect.right() - margin)
state = QtGui.QIcon.On if option.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
icon.paint(painter, r, QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter, mode, state)
class Window(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.resize(500, 400)
self.uiItems = QtWidgets.QTreeView()
self.uiItems.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.uiItems.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.uiItems.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.uiItems.setModel(QtGui.QStandardItemModel())
self.uiItems.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
delegate = IconDelegate(self.uiItems)
self.uiItems.setItemDelegateForColumn(2, delegate)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.uiItems)
self.setLayout(self.layout)
for i in range(3):
parent1 = QtGui.QStandardItem('Parente Item ' + str(i))
parent2 = QtGui.QStandardItem()
parent3 = QtGui.QStandardItem()
self.uiItems.model().appendRow([parent1, parent2, parent3])
for x in range(3):
col1 = QtGui.QStandardItem('Child Item' + str(x))
col2 = QtGui.QStandardItem('Item' + str(x))
col3 = QtGui.QStandardItem('Item' + str(x))
col3.setData(self.createDotPixmap(), role=QtCore.Qt.DecorationRole)
col3.setData(self.createRectPixmap(), role=DecorationRole2)
parent1.appendRow([col1,col2,col3])
self.uiItems.expandAll()
def createRectPixmap(self, col=QtGui.QColor(240,50,50)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(150,20,20), 1.25))
painter.drawRect(pxSize)
painter.end()
return px
def createDotPixmap(self, col=QtGui.QColor(128,128,128)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(15,15,15), 1.25))
painter.drawEllipse(pxSize)
painter.end()
return px
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Window()
ex.show()
app.exec_()

Related

PyQt/PySide QGraphicsScene, Hover event on Ellipse Item not working

I'm currently learning how to use Qt's Qgraphics and i cant get the hoverEnterEvent to work on an QGraphicsEllipseItem object. I am setting setAcceptHoverEvents to True and implemented the hoverEnterEvent function, yet the function isn't getting called.
here's my code:
import sys
from PySide6.QtWidgets import (
QApplication,
QMainWindow,
QGraphicsView,
QGraphicsScene,
QGraphicsEllipseItem,
)
from PySide6.QtGui import QPainterPath, QTransform, QPen, QBrush, QColor, QPainter
from PySide6.QtCore import Qt
PORT_PEN_COLOR = "#000000"
PORT_BRUSH_COLOR = "#ebebeb"
EDGE_PEN_COLOR = "#474747"
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(0, 0, 800, 600)
self.setCentralWidget(GraphicsView())
self.show()
class GraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.setMouseTracking(True)
self.setScene(GraphicsScene())
self.setRenderHint(QPainter.RenderHint.Antialiasing)
class GraphicsScene(QGraphicsScene):
def __init__(self, parent=None):
super().__init__(parent)
self.setSceneRect(-10000, -10000, 20000, 20000)
self._port_pen = QPen(QColor(PORT_PEN_COLOR))
self._port_brush = QBrush(QColor(PORT_BRUSH_COLOR))
self._edge_pen = QPen(QColor(EDGE_PEN_COLOR))
self._edge_pen.setWidth(4)
def mousePressEvent(self, event):
clicked_item = self.itemAt(event.scenePos(), QTransform())
if event.buttons() == Qt.MouseButton.LeftButton:
if clicked_item is not None:
# edge item
pos = clicked_item.scenePos()
pos.setX(pos.x() + 6)
pos.setY(pos.y() + 6)
self.edge = self.addPath(QPainterPath())
self.edge.setPen(self._edge_pen)
self.start_pos = pos
self.end_pos = self.start_pos
self.update_path()
else:
x = event.scenePos().x()
y = event.scenePos().y()
# port item
start_port = Ellipse()
start_port.setPos(x - 6, y - 6)
start_port.setPen(self._port_pen)
start_port.setBrush(self._port_brush)
start_port.setZValue(10000.0)
self.addItem(start_port)
# edge item
self.edge = self.addPath(QPainterPath())
self.edge.setPen(self._edge_pen)
self.start_pos = event.scenePos()
self.end_pos = self.start_pos
self.update_path()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.MouseButton.LeftButton:
print(f"moving, x : {event.scenePos().x()}, y : {event.scenePos().y()}")
self.end_pos = event.scenePos()
try:
self.update_path()
except AttributeError:
pass
def mouseReleaseEvent(self, event) -> None:
released_item = self.itemAt(event.scenePos(), QTransform())
if event.button() == Qt.MouseButton.LeftButton:
if released_item is not None and released_item.type() != 2:
self.end_pos = released_item.scenePos()
self.end_pos.setX(self.end_pos.x() + 6)
self.end_pos.setY(self.end_pos.y() + 6)
if not self.start_pos.isNull() and not self.end_pos.isNull():
path = QPainterPath()
path.moveTo(self.start_pos.x() - 1, self.start_pos.y() - 1)
path.lineTo(self.end_pos)
self.edge.setPath(path)
else:
x = event.scenePos().x() + 1
y = event.scenePos().y() + 1
end_port = QGraphicsEllipseItem(0, 0, 10, 10)
end_port.setPos(x - 6, y - 6)
end_port.setPen(self._port_pen)
end_port.setBrush(self._port_brush)
end_port.setZValue(10000.0)
self.addItem(end_port)
def update_path(self):
if not self.start_pos.isNull() and not self.end_pos.isNull():
path = QPainterPath()
path.moveTo(self.start_pos.x() - 1, self.start_pos.y() - 1)
path.lineTo(self.end_pos)
self.edge.setPath(path)
class Ellipse(QGraphicsEllipseItem):
def __init__(self):
super().__init__()
self.setRect(0, 0, 10, 10)
self.setAcceptHoverEvents(True)
def hoverEnterEvent(self, event) -> None:
print("hovered")
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MainWindow()
sys.exit(app.exec())
What am i doing wrong here, how do i get the hover event to work please ?
Thank you

Get correct parent in a slot triggered by Button inside a QHeaderView class

Just for a sport of it I am playing around with a demo code from #ekhumoro (all credits for original Qt4 code goes to him), where he inserted a new line of QLineEdit widgets into QHeaderview of QTableView. I ported the code to Qt5 and started to add different widget to the header. No problems with a QComboBox, QCheckBox, an empty space (QWidget) and a QPushButton.
However, when I created a composed QWidget containting a QHBoxLayout with a QPushButton (it's the one with "=" sign, in column "Three") and a QLineEdit. All the controls are linked to relevant slots and it runs fine, including the QLineEdit from the composed field in column Three, but except the QPushButton from that composed widget. The ChangeIntButtonSymbol(self) slot def should cycle the button's Text between <|=|> values. I always get an error:
AttributeError: 'FilterHeader' object has no attribute 'text'
which indicates, that unlike in other cases, here the context of the parent (retrieved by self.sender()) widget is different, the def received FilterHeader class as a parent instead the btn. I tried also passing an argument using lambda:
self.btn.clicked.connect(lambda: self.changebuttonsymbol.emit(self.btn))
...but the result was exactly the same (with different wording in the error).
Clearly, I'm not getting fully the architecture of this QHeaderView extension and making some basic mistake. Full demo bellow, the problem occures when "=" button is clicked, any solutions or hints appreciated.
import sys
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QHeaderView, QWidget, QLineEdit, QApplication, QTableView, QVBoxLayout,QHBoxLayout, QLineEdit, QComboBox, QPushButton, QCheckBox
from PyQt5.QtCore import pyqtSignal
class FilterHeader(QHeaderView):
filterActivated = QtCore.pyqtSignal()
changebuttonsymbol = QtCore.pyqtSignal()
def __init__(self, parent):
super().__init__(QtCore.Qt.Horizontal, parent)
self._editors = []
self._padding = 4
self.setStretchLastSection(True)
#self.setResizeMode(QHeaderView.Stretch)
self.setDefaultAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.setSortIndicatorShown(False)
self.sectionResized.connect(self.adjustPositions)
parent.horizontalScrollBar().valueChanged.connect(self.adjustPositions)
def setFilterBoxes(self, count):
while self._editors:
editor = self._editors.pop()
editor.deleteLater()
for index in range(count):
if index == 1: # Empty
editor = QWidget()
elif index == 2: # Number filter (>|=|<)
editor = QWidget(self.parent())
edlay = QHBoxLayout()
edlay.setContentsMargins(0, 0, 0, 0)
edlay.setSpacing(0)
self.btn = QPushButton()
self.btn.setText("=")
self.btn.setFixedWidth(20)
#self.btn.clicked.connect(lambda: self.changebuttonsymbol.emit(self.btn))
self.btn.clicked.connect(self.changebuttonsymbol.emit)
#btn.setViewportMargins(0, 0, 0, 0)
linee = QLineEdit(self.parent())
linee.setPlaceholderText('Filter')
linee.returnPressed.connect(self.filterActivated.emit)
#linee.setViewportMargins(0, 0, 0, 0)
edlay.addWidget(self.btn)
edlay.addWidget(linee)
editor.setLayout(edlay)
elif index == 3:
editor = QComboBox(self.parent())
editor.addItems(["", "Combo", "One", "Two", "Three"])
editor.currentIndexChanged.connect(self.filterActivated.emit)
elif index == 4:
editor = QPushButton(self.parent())
editor.clicked.connect(self.filterActivated.emit)
editor.setText("Button")
elif index == 5:
editor = QCheckBox(self.parent())
editor.clicked.connect(self.filterActivated.emit)
editor.setTristate(True)
editor.setCheckState(1)
editor.setText("CheckBox")
else: # string filter
editor = QLineEdit(self.parent())
editor.setPlaceholderText('Filter')
editor.returnPressed.connect(self.filterActivated.emit)
self._editors.append(editor)
self.adjustPositions()
def sizeHint(self):
size = super().sizeHint()
if self._editors:
height = self._editors[0].sizeHint().height()
size.setHeight(size.height() + height + self._padding)
return size
def updateGeometries(self):
if self._editors:
height = self._editors[0].sizeHint().height()
self.setViewportMargins(0, 0, 0, height + self._padding)
else:
self.setViewportMargins(0, 0, 0, 0)
super().updateGeometries()
self.adjustPositions()
def adjustPositions(self):
for index, editor in enumerate(self._editors):
height = editor.sizeHint().height()
CompensateY = 0
CompensateX = 0
if self._editors[index].__class__.__name__ == "QComboBox":
CompensateY = +2
elif self._editors[index].__class__.__name__ == "QWidget":
CompensateY = -1
elif self._editors[index].__class__.__name__ == "QPushButton":
CompensateY = -1
elif self._editors[index].__class__.__name__ == "QCheckBox":
CompensateY = 4
CompensateX = 4
editor.move( self.sectionPosition(index) - self.offset() + 1 + CompensateX, height + (self._padding // 2) + 2 + CompensateY)
editor.resize(self.sectionSize(index), height)
def filterText(self, index):
if 0 <= index < len(self._editors):
if self._editors[index].__class__.__name__ == "QLineEdit":
return self._editors[index].text()
return ''
def setFilterText(self, index, text):
if 0 <= index < len(self._editors):
self._editors[index].setText(text)
def clearFilters(self):
for editor in self._editors:
editor.clear()
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.view = QTableView()
layout = QVBoxLayout(self)
layout.addWidget(self.view)
header = FilterHeader(self.view)
self.view.setHorizontalHeader(header)
model = QtGui.QStandardItemModel(self.view)
model.setHorizontalHeaderLabels('One Two Three Four Five Six Seven'.split())
self.view.setModel(model)
header.setFilterBoxes(model.columnCount())
header.filterActivated.connect(self.handleFilterActivated)
header.changebuttonsymbol.connect(self.ChangeIntButtonSymbol)
def handleFilterActivated(self):
header = self.view.horizontalHeader()
for index in range(header.count()):
if index != 4:
print((index, header.filterText(index)))
else:
print("Button")
def ChangeIntButtonSymbol(self):
print("Int button triggered")
nbtn = self.sender()
print(str(nbtn))
if nbtn.text() == "=":
nbtn.setText(">")
elif nbtn.text() == ">":
nbtn.setText("<")
else:
nbtn.setText("=")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.setGeometry(800, 100, 600, 300)
window.show()
sys.exit(app.exec_())
sender() is a method that indicates to which object the signal belongs, and it is obvious changebuttonsymbol belongs to the header that obviously does not have a text() method. On the other hand, it is better for each class to manage its own objects, so the change of the button text must be implemented in the header.
Finally, if a complex widget is used, it is better to have it in a class.
import sys
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import (
QHeaderView,
QWidget,
QLineEdit,
QApplication,
QTableView,
QVBoxLayout,
QHBoxLayout,
QComboBox,
QPushButton,
QCheckBox,
)
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.btn = QPushButton()
self.btn.setText("=")
self.btn.setFixedWidth(20)
self.linee = QLineEdit()
self.linee.setPlaceholderText("Filter")
lay = QHBoxLayout(self)
lay.setContentsMargins(0, 0, 0, 0)
lay.setSpacing(0)
lay.addWidget(self.btn)
lay.addWidget(self.linee)
class FilterHeader(QHeaderView):
filterActivated = pyqtSignal()
def __init__(self, parent):
super().__init__(Qt.Horizontal, parent)
self._editors = []
self._padding = 4
self.setStretchLastSection(True)
# self.setResizeMode(QHeaderView.Stretch)
self.setDefaultAlignment(Qt.AlignLeft | Qt.AlignVCenter)
self.setSortIndicatorShown(False)
self.sectionResized.connect(self.adjustPositions)
parent.horizontalScrollBar().valueChanged.connect(self.adjustPositions)
def setFilterBoxes(self, count):
while self._editors:
editor = self._editors.pop()
editor.deleteLater()
for index in range(count):
editor = self.create_editor(self.parent(), index)
self._editors.append(editor)
self.adjustPositions()
def create_editor(self, parent, index):
if index == 1: # Empty
editor = QWidget()
elif index == 2: # Number filter (>|=|<)
editor = Widget(parent)
editor.linee.returnPressed.connect(self.filterActivated)
editor.btn.clicked.connect(self.changebuttonsymbol)
elif index == 3:
editor = QComboBox(parent)
editor.addItems(["", "Combo", "One", "Two", "Three"])
editor.currentIndexChanged.connect(self.filterActivated)
elif index == 4:
editor = QPushButton(parent)
editor.clicked.connect(self.filterActivated)
editor.setText("Button")
elif index == 5:
editor = QCheckBox(parent)
editor.clicked.connect(self.filterActivated)
editor.setTristate(True)
editor.setCheckState(Qt.Checked)
editor.setText("CheckBox")
else:
editor = QLineEdit(parent)
editor.setPlaceholderText("Filter")
editor.returnPressed.connect(self.filterActivated)
return editor
def sizeHint(self):
size = super().sizeHint()
if self._editors:
height = self._editors[0].sizeHint().height()
size.setHeight(size.height() + height + self._padding)
return size
def updateGeometries(self):
if self._editors:
height = self._editors[0].sizeHint().height()
self.setViewportMargins(0, 0, 0, height + self._padding)
else:
self.setViewportMargins(0, 0, 0, 0)
super().updateGeometries()
self.adjustPositions()
def adjustPositions(self):
for index, editor in enumerate(self._editors):
if not isinstance(editor, QWidget):
continue
height = editor.sizeHint().height()
compensate_y = 0
compensate_x = 0
if type(editor) is QComboBox:
compensate_y = +2
elif type(editor) in (QWidget, Widget):
compensate_y = -1
elif type(editor) is QPushButton:
compensate_y = -1
elif type(editor) is QCheckBox:
compensate_y = 4
compensate_x = 4
editor.move(
self.sectionPosition(index) - self.offset() + 1 + compensate_x,
height + (self._padding // 2) + 2 + compensate_y,
)
editor.resize(self.sectionSize(index), height)
def filterText(self, index):
for editor in self._editors:
if hasattr(editor, "text") and callable(editor.text):
return editor.text()
return ""
def setFilterText(self, index, text):
for editor in self._editors:
if hasattr(editor, "setText") and callable(editor.setText):
editor.setText(text)
def clearFilters(self):
for editor in self._editors:
editor.clear()
def changebuttonsymbol(self):
nbtn = self.sender()
if nbtn.text() == "=":
nbtn.setText(">")
elif nbtn.text() == ">":
nbtn.setText("<")
else:
nbtn.setText("=")
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.view = QTableView()
layout = QVBoxLayout(self)
layout.addWidget(self.view)
header = FilterHeader(self.view)
self.view.setHorizontalHeader(header)
model = QStandardItemModel(self.view)
model.setHorizontalHeaderLabels("One Two Three Four Five Six Seven".split())
self.view.setModel(model)
header.setFilterBoxes(model.columnCount())
header.filterActivated.connect(self.handleFilterActivated)
def handleFilterActivated(self):
header = self.view.horizontalHeader()
for index in range(header.count()):
if index != 4:
print(index, header.filterText(index))
else:
print("Button")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.setGeometry(800, 100, 600, 300)
window.show()
sys.exit(app.exec_())

How to set QGraphicsView 's background Image? [duplicate]

This question already has answers here:
Painting background on QGraphicsView using drawBackground
(1 answer)
How to enable Pan and Zoom in a QGraphicsView
(3 answers)
How to put an image in QGraphicsView's scrollbar area?
(1 answer)
Closed 3 years ago.
I'm wondering how to set QgraphicsView's background Image.
In this painter program, the background is just white color.
I want to load some image(jpg, png, .. whatever) and set it as painter's background.
and after painting it, I want to just save painting (not include background, just what i painted.)
how can i do this? please help me.
import sys
from PyQt5.QtCore import *
from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,
QPushButton, QVBoxLayout, QWidget, QSlider)
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
class CWidget(QWidget):
def __init__(self):
super().__init__()
# 전체 폼 박스
formbox = QHBoxLayout()
self.setLayout(formbox)
# 좌, 우 레이아웃박스
left = QVBoxLayout()
right = QVBoxLayout()
# 그룹박스2
gb = QGroupBox('펜 설정')
left.addWidget(gb)
grid = QGridLayout()
gb.setLayout(grid)
label = QLabel('펜 색상')
grid.addWidget(label, 1, 0)
self.pencolor = QColor(0, 0, 0)
self.penbtn = QPushButton()
self.penbtn.setStyleSheet('background-color: rgb(0,0,0)')
self.penbtn.clicked.connect(self.showColorDlg)
grid.addWidget(self.penbtn, 1, 1)
label = QLabel('펜 굵기')
grid.addWidget(label, 2, 0)
self.slider = QSlider(Qt.Horizontal)
self.slider.setMinimum(3)
self.slider.setMaximum(21)
self.slider.setValue(5)
self.slider.setFocusPolicy(Qt.StrongFocus)
self.slider.setTickPosition(QSlider.TicksBothSides)
self.slider.setTickInterval(1)
self.slider.setSingleStep(1)
grid.addWidget(self.slider)
# 그룹박스4
gb = QGroupBox('지우개')
left.addWidget(gb)
hbox = QHBoxLayout()
gb.setLayout(hbox)
self.checkbox = QCheckBox('지우개')
self.checkbox.stateChanged.connect(self.checkClicked)
hbox.addWidget(self.checkbox)
left.addStretch(1)
# 우 레이아웃 박스에 그래픽 뷰 추가
self.view = CView(self)
right.addWidget(self.view)
# 전체 폼박스에 좌우 박스 배치
formbox.addLayout(left)
formbox.addLayout(right)
formbox.setStretchFactor(left, 0)
formbox.setStretchFactor(right, 1)
self.setGeometry(100, 100, 800, 500)
def checkClicked(self):
pass
def createExampleGroup(self):
groupBox = QGroupBox("Slider Example")
slider = QSlider(Qt.Horizontal)
slider.setFocusPolicy(Qt.StrongFocus)
slider.setTickPosition(QSlider.TicksBothSides)
slider.setTickInterval(10)
slider.setSingleStep(1)
vbox = QVBoxLayout()
vbox.addWidget(slider)
vbox.addStretch(1)
groupBox.setLayout(vbox)
return groupBox
def showColorDlg(self):
# 색상 대화상자 생성
color = QColorDialog.getColor()
sender = self.sender()
# 색상이 유효한 값이면 참, QFrame에 색 적용
self.pencolor = color
self.penbtn.setStyleSheet('background-color: {}'.format(color.name()))
# QGraphicsView display QGraphicsScene
class CView(QGraphicsView):
def __init__(self, parent):
super().__init__(parent)
self.scene = QGraphicsScene()
self.setScene(self.scene)
self.items = []
self.start = QPointF()
self.end = QPointF()
self.setRenderHint(QPainter.HighQualityAntialiasing)
def moveEvent(self, e):
rect = QRectF(self.rect())
rect.adjust(0, 0, -2, -2)
self.scene.setSceneRect(rect)
def mousePressEvent(self, e):
if e.button() == Qt.LeftButton:
# 시작점 저장
self.start = e.pos()
self.end = e.pos()
def mouseMoveEvent(self, e):
# e.buttons()는 정수형 값을 리턴, e.button()은 move시 Qt.Nobutton 리턴
if e.buttons() & Qt.LeftButton:
self.end = e.pos()
if self.parent().checkbox.isChecked():
pen = QPen(QColor(255, 255, 255), 10)
path = QPainterPath()
path.moveTo(self.start)
path.lineTo(self.end)
self.scene.addPath(path, pen)
self.start = e.pos()
return None
pen = QPen(self.parent().pencolor, self.parent().slider.value())
# Path 이용
path = QPainterPath()
path.moveTo(self.start)
path.lineTo(self.end)
self.scene.addPath(path, pen)
# 시작점을 다시 기존 끝점으로
self.start = e.pos()
def open(self):
fileName, _ = QFileDialog.getOpenFileName(self, "Open File",
QDir.currentPath())
if fileName:
image = QImage(fileName)
if image.isNull():
QMessageBox.information(self, "Image Viewer",
"Cannot load %s." % fileName)
return
self.imageLabel.setPixmap(QPixmap.fromImage(image))
self.scaleFactor = 1.0
self.printAct.setEnabled(True)
self.fitToWindowAct.setEnabled(True)
self.updateActions()
if not self.fitToWindowAct.isChecked():
self.imageLabel.adjustSize()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = CWidget()
w.show()
sys.exit(app.exec_())
You can create an instance of QGraphicsPixmapItem and add it to the scene, here is an example:
import sys
from PyQt5.QtCore import *
from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,
QPushButton, QVBoxLayout, QWidget, QSlider)
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
class CWidget(QWidget):
def __init__(self):
super().__init__()
# 전체 폼 박스
formbox = QHBoxLayout()
self.setLayout(formbox)
# 좌, 우 레이아웃박스
left = QVBoxLayout()
right = QVBoxLayout()
# 그룹박스2
gb = QGroupBox('펜 설정')
left.addWidget(gb)
grid = QGridLayout()
gb.setLayout(grid)
label = QLabel('펜 색상')
grid.addWidget(label, 1, 0)
self.pencolor = QColor(0, 0, 0)
self.penbtn = QPushButton()
self.penbtn.setStyleSheet('background-color: rgb(0,0,0)')
self.penbtn.clicked.connect(self.showColorDlg)
grid.addWidget(self.penbtn, 1, 1)
label = QLabel('펜 굵기')
grid.addWidget(label, 2, 0)
self.slider = QSlider(Qt.Horizontal)
self.slider.setMinimum(3)
self.slider.setMaximum(21)
self.slider.setValue(5)
self.slider.setFocusPolicy(Qt.StrongFocus)
self.slider.setTickPosition(QSlider.TicksBothSides)
self.slider.setTickInterval(1)
self.slider.setSingleStep(1)
grid.addWidget(self.slider)
# 그룹박스4
gb = QGroupBox('지우개')
left.addWidget(gb)
hbox = QHBoxLayout()
gb.setLayout(hbox)
self.checkbox = QCheckBox('지우개')
self.checkbox.stateChanged.connect(self.checkClicked)
hbox.addWidget(self.checkbox)
left.addStretch(1)
# 우 레이아웃 박스에 그래픽 뷰 추가
self.view = CView(self)
right.addWidget(self.view)
# 전체 폼박스에 좌우 박스 배치
formbox.addLayout(left)
formbox.addLayout(right)
formbox.setStretchFactor(left, 0)
formbox.setStretchFactor(right, 1)
self.setGeometry(100, 100, 800, 500)
def checkClicked(self, state):
self.view.stretch(state)
def createExampleGroup(self):
groupBox = QGroupBox("Slider Example")
slider = QSlider(Qt.Horizontal)
slider.setFocusPolicy(Qt.StrongFocus)
slider.setTickPosition(QSlider.TicksBothSides)
slider.setTickInterval(10)
slider.setSingleStep(1)
vbox = QVBoxLayout()
vbox.addWidget(slider)
vbox.addStretch(1)
groupBox.setLayout(vbox)
return groupBox
def showColorDlg(self):
# 색상 대화상자 생성
color = QColorDialog.getColor()
sender = self.sender()
# 색상이 유효한 값이면 참, QFrame에 색 적용
self.pencolor = color
self.penbtn.setStyleSheet('background-color: {}'.format(color.name()))
# QGraphicsView display QGraphicsScene
class CView(QGraphicsView):
def __init__(self, parent):
super().__init__(parent)
self.scene = QGraphicsScene()
self.setScene(self.scene)
self.items = []
self.start = QPointF()
self.end = QPointF()
self.backgroundImage = None
self.graphicsPixmapItem = None
self.setRenderHint(QPainter.HighQualityAntialiasing)
self.open()
def moveEvent(self, e):
rect = QRectF(self.rect())
rect.adjust(0, 0, -2, -2)
self.scene.setSceneRect(rect)
def mousePressEvent(self, e):
if e.button() == Qt.LeftButton:
# 시작점 저장
self.start = e.pos()
self.end = e.pos()
def mouseMoveEvent(self, e):
# e.buttons()는 정수형 값을 리턴, e.button()은 move시 Qt.Nobutton 리턴
if e.buttons() & Qt.LeftButton:
self.end = e.pos()
if self.parent().checkbox.isChecked():
pen = QPen(QColor(255, 255, 255), 10)
path = QPainterPath()
path.moveTo(self.start)
path.lineTo(self.end)
self.scene.addPath(path, pen)
self.start = e.pos()
return None
pen = QPen(self.parent().pencolor, self.parent().slider.value())
# Path 이용
path = QPainterPath()
path.moveTo(self.start)
path.lineTo(self.end)
self.scene.addPath(path, pen)
# 시작점을 다시 기존 끝점으로
self.start = e.pos()
def stretch(self, state):
self._set_image(state == 2)
def open(self):
fileName, _ = QFileDialog.getOpenFileName(self, "Open File", QDir.currentPath(), filter='Images (*.png *.xpm *.jpg)')
if fileName:
image = QImage(fileName)
if image.isNull():
QMessageBox.information(self, "Image Viewer",
"Cannot load %s." % fileName)
return
self.backgroundImage = fileName
self._set_image(False)
def _set_image(self, stretch: bool):
tempImg = QPixmap(self.backgroundImage)
if stretch:
tempImg = tempImg.scaled(self.scene.width(), self.scene.height())
if self.graphicsPixmapItem is not None:
self.scene.removeItem(self.graphicsPixmapItem)
self.graphicsPixmapItem = QGraphicsPixmapItem(tempImg)
self.scene.addItem(self.graphicsPixmapItem)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = CWidget()
w.show()
sys.exit(app.exec_())

How to put a gif in gui using python PyQt5

This program is a trafficlight program but i want to put a gif on the right space of the window that will show a walking man gif when the color is green and a stop gif when in red or yellow so I tried to use QMovie which I get mixed results and still ended up in an error or the gif won't appear at the window can you please help me?
from itertools import cycle
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTimer,Qt,QPoint
from PyQt5.QtWidgets import QApplication,QMainWindow
from PyQt5.QtGui import QPainter,QColor,QMovie
class TrafficLight(QMainWindow):
def __init__(self,parent = None):
super(TrafficLight, self).__init__(parent)
self.setWindowTitle("TrafficLight ")
self.traffic_light_color1 = cycle(\[
QColor('red'),
QColor('gray'),
QColor('gray')
\])
self.traffic_light_color2 = cycle(\[
QColor('gray'),
QColor('yellow'),
QColor('gray')
\])
self.traffic_light_color3 = cycle(\[
QColor('gray'),
QColor('gray'),
QColor('green')
\])
self._current_color1 = next(self.traffic_light_color1)
self._current_color2 = next(self.traffic_light_color2)
self._current_color3 = next(self.traffic_light_color3)
timer = QTimer(self, timeout=self.change_color)
x = 0
if x == 0 :
self.movie1 = QMovie("Walking-man2[enter image description here][1].gif")
self.movie1.frameChanged.connect(self.repaint)
self.movie1.start()
timer.start(30*100)
x = 1
elif x == 1 :
self.movie1 = QMovie("tenor(1).gif")
self.movie1.frameChanged.connect(self.repaint)
self.movie1.start()
timer.start(10*100)
x = 2
elif x == 2:
self.movie1 = QMovie("tenor(1).gif")
self.movie1.frameChanged.connect(self.repaint)
self.movie1.start()
timer.start(40*100)
x = 0
self.resize(700, 510)
#QtCore.pyqtSlot()
def change_color(self):
self._current_color1 = next(self.traffic_light_color1)
self._current_color2 = next(self.traffic_light_color2)
self._current_color3 = next(self.traffic_light_color3)
self.update()
def paintEvent(self, event):
p1 = QPainter(self)
p1.setBrush(self._current_color1)
p1.setPen(Qt.black)
p1.drawEllipse(QPoint(125, 125), 50, 50)
p2 = QPainter(self)
p2.setBrush(self._current_color2)
p2.setPen(Qt.black)
p2.drawEllipse(QPoint(125, 250),50,50)
p3 = QPainter(self)
p3.setBrush(self._current_color3)
p3.setPen(Qt.black)
p3.drawEllipse(QPoint(125, 375),50,50)
currentFrame = self.movie1.currentPixmap()
frameRect = currentFrame.rect()
frameRect.moveCenter(self.rect().center())
if frameRect.intersects(event.rect()):
painter = QPainter(self)
painter.drawPixmap(frameRect.left(), frameRect.top(), currentFrame)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = TrafficLight()
w.show()
sys.exit(app.exec_())
The logic of changing one state to another can be implemented with a Finite State Machine (FSM), and fortunately Qt implements it using The State Machine Framework:
from functools import partial
from PyQt5 import QtCore, QtGui, QtWidgets
class LightWidget(QtWidgets.QWidget):
def __init__(self, color, parent=None):
super(LightWidget, self).__init__(parent)
self._state = False
self._color = color
self.setFixedSize(150, 150)
#QtCore.pyqtSlot()
def turnOn(self):
self._state = True
self.update()
#QtCore.pyqtSlot()
def turnOff(self):
self._state = False
self.update()
def paintEvent(self, event):
color = self._color if self._state else QtGui.QColor('gray')
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(QtCore.Qt.black)
painter.setBrush(color)
painter.drawEllipse(self.rect())
class TrafficLightWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(TrafficLightWidget, self).__init__(parent)
hlay = QtWidgets.QHBoxLayout(self)
container = QtWidgets.QWidget()
container.setStyleSheet('''background-color : black''')
vlay = QtWidgets.QVBoxLayout(container)
self.m_red = LightWidget(QtGui.QColor("red"))
self.m_yellow = LightWidget(QtGui.QColor("yellow"))
self.m_green = LightWidget(QtGui.QColor("green"))
vlay.addWidget(self.m_red)
vlay.addWidget(self.m_yellow)
vlay.addWidget(self.m_green)
hlay.addWidget(container, alignment=QtCore.Qt.AlignCenter)
self.label = QtWidgets.QLabel("Test", alignment=QtCore.Qt.AlignCenter)
hlay.addWidget(self.label, 1)
red_to_yellow = createLightState(self.m_red, 30*1000, partial(self.change_gif, "gif_red.gif"))
yellow_to_green = createLightState(self.m_yellow, 20*1000, partial(self.change_gif, "gif_yellow.gif"))
green_to_yellow = createLightState(self.m_green, 40*1000, partial(self.change_gif, "gif_green.gif"))
yellow_to_red = createLightState(self.m_yellow, 20*1000, partial(self.change_gif, "gif_yellow.gif"))
red_to_yellow.addTransition(red_to_yellow.finished, yellow_to_green)
yellow_to_green.addTransition(yellow_to_green.finished, green_to_yellow)
green_to_yellow.addTransition(green_to_yellow.finished, yellow_to_red)
yellow_to_red.addTransition(yellow_to_red.finished, red_to_yellow)
machine = QtCore.QStateMachine(self)
machine.addState(red_to_yellow)
machine.addState(yellow_to_green)
machine.addState(green_to_yellow)
machine.addState(yellow_to_red)
machine.setInitialState(red_to_yellow)
machine.start()
#QtCore.pyqtSlot()
def change_gif(self, gif):
last_movie = self.label.movie()
movie = QtGui.QMovie(gif)
self.label.setMovie(movie)
movie.start()
if last_movie is not None:
last_movie.deleteLater()
def createLightState(light, duration, callback):
lightState = QtCore.QState()
timer = QtCore.QTimer(
lightState,
interval=duration,
singleShot=True
)
timing = QtCore.QState(lightState)
timing.entered.connect(light.turnOn)
timing.entered.connect(callback)
timing.entered.connect(timer.start)
timing.exited.connect(light.turnOff)
done = QtCore.QFinalState(lightState)
timing.addTransition(timer.timeout, done)
lightState.setInitialState(timing)
return lightState
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = TrafficLightWidget()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
Though the answer ain't as fancy as eyllanesc's... You can make the ellipse depend on a variable color, then change the stored variable color and call update(). The gif can be displayed using a label
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTimer,Qt,QPoint
from PyQt5.QtWidgets import QApplication,QMainWindow
from PyQt5.QtGui import QPainter,QColor,QMovie
class TrafficLight(QtWidgets.QWidget):
def __init__(self,parent = None):
super(TrafficLight, self).__init__(parent)
self.setWindowTitle("TrafficLight ")
layout = QtWidgets.QHBoxLayout()
self.setLayout(layout)
self.lblGif = QtWidgets.QLabel()
layout.addSpacing(300)
layout.addWidget(self.lblGif)
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.changeLight)
self.timer.start(3000)
self.resize(700, 510)
self.x = 0
self.changeLight()
def changeLight(self):
if self.x == 0 :
self.color1 = QColor('red')
self.color2 = QColor('grey')
self.color3 = QColor('grey')
self.loadGif('wait.gif')
self.x = 1
elif self.x == 1 :
self.color1 = QColor('grey')
self.color2 = QColor('yellow')
self.color3 = QColor('grey')
self.loadGif('almost.gif')
self.x = 2
elif self.x == 2:
self.color1 = QColor('grey')
self.color2 = QColor('grey')
self.color3 = QColor('green')
self.loadGif('walk.gif')
self.x = 0
self.update()
def loadGif(self, path):
movie = QtGui.QMovie(path)
self.lblGif.setMovie(movie)
movie.start()
def paintEvent(self, event):
p1 = QPainter(self)
p1.setBrush(self.color1)
p1.setPen(Qt.black)
p1.drawEllipse(QPoint(125, 125), 50, 50)
p1.end()
p2 = QPainter(self)
p2.setBrush(self.color2)
p2.setPen(Qt.black)
p2.drawEllipse(QPoint(125, 250),50,50)
p2.end()
p3 = QPainter(self)
p3.setBrush(self.color3)
p3.setPen(Qt.black)
p3.drawEllipse(QPoint(125, 375),50,50)
p3.end()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = TrafficLight()
w.show()
sys.exit(app.exec_())

AttributeError: 'Settings' object has no attribute 'scene'

I need to add pixmap to my rectangles. When I press the click button then my pixmap will be added to one by one in my rectangles but I got this attribute error. Can any one please guide me how to solve this error? I tried so many ways but I didn't get the proper output.
Thank you in advance.
Given below is my code:
from pyface.qt import QtGui, QtCore
import sys
global X,Y
class ScanView(QtGui.QGraphicsView):
def __init__(self,X=5, Y=5, parent=None):
super(ScanView, self).__init__(parent)
self.row = X
self.cols = Y
self.squareLB = 50
self.width = Y*self.squareLB+2*self.squareLB
self.height = X*self.squareLB+2*self.squareLB
self.List = []
if self.width>708:
self.scene = QtGui.QGraphicsScene(0,0,self.width,self.height)
for i in range(self.row):
for j in range(self.cols):
item = self.scene.addRect(QtCore.QRectF(0,0,self.squareLB,self.squareLB))
item.setPos(self.squareLB+j*self.squareLB, X*self.squareLB-(i*self.squareLB))
self.List.append(item)
else:
self.scene = QtGui.QGraphicsScene(0,0,708,self.height)
self.marginLR = (708.0-Y*self.squareLB)/2.0
for i in range(self.row):
for j in range(self.cols):
item = self.scene.addRect(QtCore.QRectF(0,0,self.squareLB,self.squareLB))
item.setPos(self.marginLR+j*self.squareLB, X*self.squareLB-(i*self.squareLB))
self.List.append(item)
self.setScene(self.scene)
class Settings(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Settings, self).__init__(parent)
spacer = QtGui.QWidget(self)
spacer.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
self.vbox = QtGui.QVBoxLayout()
self.save = QtGui.QPushButton("save")
self.open= QtGui.QPushButton("open")
self.folder= QtGui.QPushButton("Folder")
self.folder.clicked.connect(self.showSettings)
self.vbox.addWidget(self.save)
self.vbox.addWidget(self.open)
self.vbox.addWidget(self.folder)
self.grid = QtGui.QGridLayout()
self.grid.addLayout(self.vbox,0,0)
self.scrollArea = QtGui.QScrollArea()
self.scrollArea.setBackgroundRole(QtGui.QPalette.Light)
self.scrollArea.setWidgetResizable(True)
self.grid.addWidget(self.scrollArea,0,1)
self.setCentralWidget(QtGui.QWidget(self))
self.centralWidget().setLayout(self.grid)
self.setGeometry(200,100,300,300)
self.show()
def showSettings(self):
self.MyView = ScanView(5,5)
self.vbox2 = QtGui.QVBoxLayout()
self.Scanbtn1 = QtGui.QPushButton(("click"))
self.Scanbtn1.clicked.connect(self.on_clicked)
self.vbox2.addWidget(self.Scanbtn1)
self.newwidget = QtGui.QWidget()
self.glayout = QtGui.QGridLayout(self.newwidget)
self.glayout.addWidget(self.MyView,0,0)
self.Sw = QtGui.QWidget()
self.Sw.setLayout(self.vbox2)
# self.Sw.setFixedWidth(width - self.scrollArea.viewport().width())
self.glayout.addWidget(self.Sw,0,1)
self.scrollArea.setWidget(self.newwidget)
def on_clicked(self):
print "hellloooooo"
filename1 = "./img/tick.png"
pixmap = QtGui.QPixmap(filename1)
if not pixmap.isNull():
self.MyView.add_pixmap(pixmap)
# pic = QtGui.QPixmap("./img/tick.png")
# scene.addItem(QtGui.QGraphicsPixmapItem(pic))
# # view = self.gv
# self.MyView.setScene(scene)
# self.MyView.setRenderHint(QtGui.QPainter.Antialiasing)
# self.MyView.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Settings()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You have that error because scene does not exist in the Settings class, self.scene is a member of the ScanView class plus self.scene is different from scene.
Going to the problem, you must add as a child of the rectangles and you must also change the size of the pixmap is necessary. To obtain the first rectangle you must store it in a list and then create an iterator.
import sys
from pyface.qt import QtGui, QtCore
class ScanView(QtGui.QGraphicsView):
def __init__(self,X=5, Y=5, parent=None):
super(ScanView, self).__init__(parent)
self._squares = []
n_rows, n_cols = X, Y
squareLB = 50
width, height = (Y + 2)*squareLB, (X + 2)*squareLB
self._scene = QtGui.QGraphicsScene(0, 0, max(708, width), height)
p = squareLB if width > 708 else (708.0-Y*squareLB)/2.0
for i in range(n_rows):
for j in range(n_cols):
it = self._scene.addRect(0, 0, squareLB, squareLB)
it.setPos(p + j*squareLB, i*squareLB)
self._squares.append(it)
self.setScene(self._scene)
class Settings(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Settings, self).__init__(parent)
self.save = QtGui.QPushButton("save")
self.open = QtGui.QPushButton("open")
self.folder = QtGui.QPushButton("Folder", clicked=self.showSettings)
central_widget = QtGui.QWidget()
self.setCentralWidget(central_widget)
vbox = QtGui.QVBoxLayout()
vbox.addWidget(self.save)
vbox.addWidget(self.open)
vbox.addWidget(self.folder)
self.scrollArea = QtGui.QScrollArea(widgetResizable=True)
self.scrollArea.setBackgroundRole(QtGui.QPalette.Light)
hlay = QtGui.QHBoxLayout(central_widget)
hlay.addLayout(vbox)
hlay.addWidget(self.scrollArea)
self.setGeometry(200, 100, 300, 300)
def showSettings(self):
self.view = ScanView(5, 5)
self.scanbtn = QtGui.QPushButton("click", clicked=self.on_clicked)
self.newwidget = QtGui.QWidget()
hlay = QtGui.QHBoxLayout(self.newwidget)
hlay.addWidget(self.view)
hlay.addWidget(self.scanbtn)
self.scrollArea.setWidget(self.newwidget)
self._iter_squares = iter(self.view._squares)
def on_clicked(self):
filename = "./img/tick.png"
pixmap = QtGui.QPixmap(filename)
if pixmap.isNull():
return
try:
it = next(self._iter_squares)
except StopIteration:
pass
else:
pixmap = pixmap.scaled(it.rect().size().toSize())
pixmap_it = QtGui.QGraphicsPixmapItem(pixmap, it)
def main():
app = QtGui.QApplication(sys.argv)
ex = Settings()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Categories

Resources