How to switch screens dynamically with splash effect in pyqt5 - python

I'm making a python application for switch screens in touchscreen display. I need to make switch screens dynamically with splash effect (not window effect), but I don't know how switch screens.
I have two screen class. The screen class have one button to switch the screens.
How do I switch screens?
Code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class PicButton(QtWidgets.QPushButton):
def __init__(self, pixmap, pixmap_pressed, width, height, id_button, parent=None):
super(PicButton, self).__init__(parent)
self.pixmap = pixmap
self.pixmap_pressed = pixmap_pressed
self.id_buton = id_button
self.width = width
self.height = height
def paintEvent(self, event):
if self.isDown():
pix = self.pixmap_pressed
print("Pressed button: ", self.id_buton)
else:
pix = self.pixmap
painter = QtGui.QPainter(self)
painter.drawPixmap(event.rect(), pix)
def sizeHint(self):
return QtCore.QSize(self.width, self.height)
class ScreenNext(QtWidgets.QWidget):
def __init__(self):
super().__init__(flags=QtCore.Qt.SplashScreen)
self.setGeometry(800, 450, 800, 450)
pixmap = QtGui.QPixmap("background.png")
brush = QtGui.QBrush(pixmap)
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Window, brush)
self.setPalette(palette)
self.next_button = PicButton(QtGui.QPixmap("next_screen_up.png"),
QtGui.QPixmap("next_screen_down.png"), 111, 61, "next")
hlayout = QtWidgets.QHBoxLayout(self)
hlayout.addStretch()
hlayout.addWidget(self.next_button)
hlayout.addStretch()
self.next_button.clicked.connect(self.switch_screen)
self.show()
def switch_screen(self):
print("ScreenNext")
class ScreenReturn(QtWidgets.QWidget):
def __init__(self):
super().__init__(flags=QtCore.Qt.SplashScreen)
self.setGeometry(800, 450, 800, 450)
pixmap = QtGui.QPixmap("background.png")
brush = QtGui.QBrush(pixmap)
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Window, brush)
self.setPalette(palette)
self.return_button = PicButton(QtGui.QPixmap("return_screen_up.png"),
QtGui.QPixmap("return_screen_down.png"), 111, 61, "return")
hlayout = QtWidgets.QHBoxLayout(self)
hlayout.addStretch()
hlayout.addWidget(self.return_button)
hlayout.addStretch()
self.return_button.clicked.connect(self.switch_screen)
self.show()
def switch_screen(self):
print("ScreenReturn")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
screen = ScreenReturn()
sys.exit(app.exec_())
Get images in link: http://www.filedropper.com/images_1
Get gif demonstration in link: http://www.filedropper.com/display

According to the .gif that you share, you want the widget to occupy the entire screen, so you must use showFullScreen, on the other hand it is better to create a class that handles the transition, in this case ScreenManager will take care of making the transition when the signal associated is emitted.
import sys
from functools import partial
from PyQt5 import QtCore, QtGui, QtWidgets
class PicButton(QtWidgets.QPushButton):
def __init__(self, pixmap, pixmap_pressed, width, height, id_button, parent=None):
super(PicButton, self).__init__(parent)
self.pixmap = pixmap
self.pixmap_pressed = pixmap_pressed
self.id_buton = id_button
self.setFixedSize(width, height)
def paintEvent(self, event):
if self.isDown():
pix = self.pixmap_pressed
print("Pressed button: ", self.id_buton)
else:
pix = self.pixmap
painter = QtGui.QPainter(self)
painter.drawPixmap(event.rect(), pix)
class ScreenNext(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setGeometry(800, 450, 800, 450)
pixmap = QtGui.QPixmap("background.png")
brush = QtGui.QBrush(pixmap)
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Window, brush)
self.setPalette(palette)
self.next_button = PicButton(QtGui.QPixmap("next_screen_up.png"),
QtGui.QPixmap("next_screen_down.png"), 111, 61, "next")
hlayout = QtWidgets.QHBoxLayout(self)
hlayout.addStretch()
hlayout.addWidget(self.next_button)
hlayout.addStretch()
class ScreenReturn(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setGeometry(800, 450, 800, 450)
pixmap = QtGui.QPixmap("background.png")
brush = QtGui.QBrush(pixmap)
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Window, brush)
self.setPalette(palette)
self.return_button = PicButton(QtGui.QPixmap("return_screen_up.png"),
QtGui.QPixmap("return_screen_down.png"), 111, 61, "return")
hlayout = QtWidgets.QHBoxLayout(self)
hlayout.addStretch()
hlayout.addWidget(self.return_button)
hlayout.addStretch()
class ScreenManager(QtCore.QObject):
def __init__(self, parent=None):
super(ScreenManager, self).__init__(parent)
self._current_window = None
def add_transition(self, signal, screen):
conn = signal.connect(partial(self.open_window, screen))
def open_window(self, window, *args):
if self._current_window is not None:
self._current_window.hide()
window.showFullScreen()
self._current_window = window
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
screen1 = ScreenReturn()
screen2 = ScreenNext()
manager = ScreenManager()
manager.add_transition(screen1.return_button.clicked, screen2)
manager.add_transition(screen2.next_button.clicked, screen1)
screen1.showFullScreen()
sys.exit(app.exec_())

Related

Qt - Python - Write to label from main class

Below is part of my code. I would like to set the label (marked by an arrow) to the value returned by the function executed in the main class. my code returns AttributeError: type object 'MainTab' has no attribute 'label'
class App(QMainWindow):
def __init__(self):
super().__init__()
self.setMinimumSize(800, 500)
self.tab_widget = TabWidget(self)
self.setCentralWidget(self.tab_widget)
self.show()
class TabWidget(QWidget):
def __init__(self, parent):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout(self)
self.tabs = QTabWidget()
self.tabs.addTab(MainTab(), "Main")
self.tabs.resize(500, 200)
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
class MainTab(QDialog):
def __init__(self, parent=None):
super().__init__()
self.originalPalette = QApplication.palette()
self.mainLayout = QHBoxLayout()
self.buttonLayout = QVBoxLayout()
buttonMsg = QPushButton("test button")
self.buttonLayout.addWidget(buttonMsg)
self.mainLayout.addLayout(self.buttonLayout)
self.label = QLabel(self) # <--------------------------------------------
# pixmap = QPixmap('test.jpg')
# self.label.setPixmap(pixmap)
self.label.setStyleSheet("border: 1px solid black;")
self.label.setAlignment(Qt.AlignCenter)
self.mainLayout.addWidget(self.label)
self.setLayout(self.mainLayout)
def main():
check_requirements(exclude=('tensorboard', 'thop'))
im0 = yoloRun.run()
height, width, channel = im0.shape
bytesPerLine = 3 * width
qImg = QImage(im0.data, width, height, bytesPerLine, QImage.Format_RGB888)
pixmap = QPixmap(qImg)
MainTab.label.setPixmap(pixmap) # <--------- FROM HERE I WOULD LIKE TO PUT PIXMAP AS BACKGROUND
if __name__ == '__main__':
t1 = threading.Thread(target=main)
t1.start()
app = QApplication([])
app.setStyle('Fusion')
app.setApplicationName('KiTest')
ex = App()
app.exec()
How am I supposed to do this?

points are drawn on main window not on the label in the GUI

i'm loading an image on a label supposed after that
a mouse click event that draws dots on the label but dots are drawn on the main window ( behind the label )
GUI Image
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super(ApplicationWindow, self).__init__()
uic.loadUi('MainWindow.ui', self)
self.setFixedSize(self.size())
self.show()
self.points = QtGui.QPolygon()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def mousePressEvent(self, e):
self.points << e.pos()
self.update()
def paintEvent(self, ev):
qp = QtGui.QPainter(self)
qp.setRenderHint(QtGui.QPainter.Antialiasing)
pen = QtGui.QPen(QtCore.Qt.red, 5)
brush = QtGui.QBrush(QtCore.Qt.red)
qp.setPen(pen)
qp.setBrush(brush)
for i in range(self.points.count()):
# qp.drawEllipse(self.points.point(i), 5, 5)
# or
qp.drawPoints(self.points)
def main():
app = QtWidgets.QApplication(sys.argv)
application = ApplicationWindow()
application.show()
sys.exit(app.exec_())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = ApplicationWindow()
sys.exit(app.exec_())
main()
You are calling QPainter(self) so the paint device is the MainWindow. Instead call QPainter on the QPixmap. Here is an example.
class Template(QWidget):
def __init__(self):
super().__init__()
self.lbl = QLabel()
self.pix = QPixmap('photo.jpeg')
grid = QGridLayout(self)
grid.addWidget(self.lbl, 0, 0)
self.points = QPolygon()
def mousePressEvent(self, event):
self.points << QPoint(event.x() - self.lbl.x(), event.y() - self.lbl.y())
def paintEvent(self, event):
qp = QPainter(self.pix)
qp.setRenderHint(QPainter.Antialiasing)
pen = QPen(Qt.red, 5)
brush = QBrush(Qt.red)
qp.setPen(pen)
qp.setBrush(brush)
qp.drawPoints(self.points)
self.lbl.setPixmap(self.pix)
However a better way is to use QImage in a custom widget that will act as a canvas.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Canvas(QWidget):
def __init__(self, photo, *args, **kwargs):
super().__init__(*args, **kwargs)
self.image = QImage(photo)
self.setFixedSize(self.image.width(), self.image.height())
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
qp = QPainter(self.image)
qp.setRenderHint(QPainter.Antialiasing)
qp.setPen(QPen(Qt.red, 5))
qp.setBrush(Qt.red)
qp.drawPoint(event.pos())
self.update()
def paintEvent(self, event):
qp = QPainter(self)
rect = event.rect()
qp.drawImage(rect, self.image, rect)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
w = QWidget()
self.setCentralWidget(w)
grid = QGridLayout(w)
grid.addWidget(Canvas('photo.jpeg'))
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = MainWindow()
gui.show()
sys.exit(app.exec_())
Output:

How can i make 2-layers in QGraphicsView?

In the program below, load the background image and paint it on it.
But, I got a problem.
In this program, when i use 'eraser' tool, the background image is erased too!
Actually, I just want to erase what i painted, except background image.
And then, I'd like to save only the painted ones(layer) as an image.
In this case, What should i do?
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('Eraser')
left.addWidget(gb)
hbox = QHBoxLayout()
gb.setLayout(hbox)
self.checkbox = QCheckBox('Eraser')
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):
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()
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 *jpeg)')
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_())
You can create another transparent item where you draw and that is on the QGraphicsPixmapItem. For painting it is only necessary to draw on a transparent QPixmap that is in the transparent item, and for the deletion we use the composition mode QPainter::CompositionMode_Clear as I indicate in this answer.
Considering the above the solution is:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class LayerItem(QtWidgets.QGraphicsRectItem):
DrawState, EraseState = range(2)
def __init__(self, parent=None):
super().__init__(parent)
self.current_state = LayerItem.DrawState
self.setPen(QtGui.QPen(QtCore.Qt.NoPen))
self.m_line_eraser = QtCore.QLineF()
self.m_line_draw = QtCore.QLineF()
self.m_pixmap = QtGui.QPixmap()
def reset(self):
r = self.parentItem().pixmap().rect()
self.setRect(QtCore.QRectF(r))
self.m_pixmap = QtGui.QPixmap(r.size())
self.m_pixmap.fill(QtCore.Qt.transparent)
def paint(self, painter, option, widget=None):
super().paint(painter, option, widget)
painter.save()
painter.drawPixmap(QtCore.QPoint(), self.m_pixmap)
painter.restore()
def mousePressEvent(self, event):
if self.current_state == LayerItem.EraseState:
self._clear(event.pos().toPoint())
elif self.current_state == LayerItem.DrawState:
self.m_line_draw.setP1(event.pos())
self.m_line_draw.setP2(event.pos())
super().mousePressEvent(event)
event.accept()
def mouseMoveEvent(self, event):
if self.current_state == LayerItem.EraseState:
self._clear(event.pos().toPoint())
elif self.current_state == LayerItem.DrawState:
self.m_line_draw.setP2(event.pos())
self._draw_line(
self.m_line_draw, QtGui.QPen(self.pen_color, self.pen_thickness)
)
self.m_line_draw.setP1(event.pos())
super().mouseMoveEvent(event)
def _draw_line(self, line, pen):
painter = QtGui.QPainter(self.m_pixmap)
painter.setPen(pen)
painter.drawLine(line)
painter.end()
self.update()
def _clear(self, pos):
painter = QtGui.QPainter(self.m_pixmap)
r = QtCore.QRect(QtCore.QPoint(), 10 * QtCore.QSize())
r.moveCenter(pos)
painter.setCompositionMode(QtGui.QPainter.CompositionMode_Clear)
painter.eraseRect(r)
painter.end()
self.update()
#property
def pen_thickness(self):
return self._pen_thickness
#pen_thickness.setter
def pen_thickness(self, thickness):
self._pen_thickness = thickness
#property
def pen_color(self):
return self._pen_color
#pen_color.setter
def pen_color(self, color):
self._pen_color = color
#property
def current_state(self):
return self._current_state
#current_state.setter
def current_state(self, state):
self._current_state = state
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setRenderHint(QtGui.QPainter.HighQualityAntialiasing)
self.setAlignment(QtCore.Qt.AlignCenter)
self.background_item = QtWidgets.QGraphicsPixmapItem()
self.foreground_item = LayerItem(self.background_item)
self.scene().addItem(self.background_item)
def set_image(self, image):
self.scene().setSceneRect(
QtCore.QRectF(QtCore.QPointF(), QtCore.QSizeF(image.size()))
)
self.background_item.setPixmap(image)
self.foreground_item.reset()
self.fitInView(self.background_item, QtCore.Qt.KeepAspectRatio)
self.centerOn(self.background_item)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
menu = self.menuBar().addMenu(self.tr("File"))
open_action = menu.addAction(self.tr("Open image..."))
open_action.triggered.connect(self.open_image)
pen_group = QtWidgets.QGroupBox(self.tr("Pen settings"))
eraser_group = QtWidgets.QGroupBox(self.tr("Eraser"))
self.pen_button = QtWidgets.QPushButton(clicked=self.showColorDlg)
color = QtGui.QColor(0, 0, 0)
self.pen_button.setStyleSheet(
"background-color: {}".format(color.name())
)
self.pen_slider = QtWidgets.QSlider(
QtCore.Qt.Horizontal,
minimum=3,
maximum=21,
value=5,
focusPolicy=QtCore.Qt.StrongFocus,
tickPosition=QtWidgets.QSlider.TicksBothSides,
tickInterval=1,
singleStep=1,
valueChanged=self.onThicknessChanged,
)
self.eraser_checkbox = QtWidgets.QCheckBox(
self.tr("Eraser"), stateChanged=self.onStateChanged
)
self.view = GraphicsView()
self.view.foreground_item.pen_thickness = self.pen_slider.value()
self.view.foreground_item.pen_color = color
# layouts
pen_lay = QtWidgets.QFormLayout(pen_group)
pen_lay.addRow(self.tr("Pen color"), self.pen_button)
pen_lay.addRow(self.tr("Pen thickness"), self.pen_slider)
eraser_lay = QtWidgets.QVBoxLayout(eraser_group)
eraser_lay.addWidget(self.eraser_checkbox)
vlay = QtWidgets.QVBoxLayout()
vlay.addWidget(pen_group)
vlay.addWidget(eraser_group)
vlay.addStretch()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QHBoxLayout(central_widget)
lay.addLayout(vlay, stretch=0)
lay.addWidget(self.view, stretch=1)
self.resize(640, 480)
#QtCore.pyqtSlot(int)
def onStateChanged(self, state):
self.view.foreground_item.current_state = (
LayerItem.EraseState
if state == QtCore.Qt.Checked
else LayerItem.DrawState
)
#QtCore.pyqtSlot(int)
def onThicknessChanged(self, value):
self.view.foreground_item.pen_thickness = value
#QtCore.pyqtSlot()
def showColorDlg(self):
color = QtWidgets.QColorDialog.getColor(
self.view.foreground_item.pen_color, self
)
self.view.foreground_item.pen_color = color
self.pen_button.setStyleSheet(
"background-color: {}".format(color.name())
)
def open_image(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
"Open File",
QtCore.QDir.currentPath(),
filter="Images (*.png *.xpm *.jpg *jpeg)",
)
if filename:
pixmap = QtGui.QPixmap(filename)
if pixmap.isNull():
QtWidgets.QMessageBox.information(
self, "Image Viewer", "Cannot load %s." % filename
)
return
self.view.set_image(pixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Problems aligning buttons in widget in pyqt5

I've been trying to create a widget with image background and two buttons (cancel and ok) with image and push down/up effect, using pyqt5 GUI of python language, but I have two problem:
1 – I can't align the buttons in widget center
2 – The buttons events occur twice
Code:
import sys
from PyQt5 import QtGui
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class PicButton(QAbstractButton):
def __init__(self, pixmap, pixmap_pressed, id_button, parent=None):
super(PicButton, self).__init__(parent)
self.pixmap = pixmap
self.pixmap_pressed = pixmap_pressed
self.id_buton = id_button
self.pressed.connect(self.update)
self.released.connect(self.update)
def paintEvent(self, event):
if self.isDown():
pix = self.pixmap_pressed
print("botao pressionado: ", self.id_buton)
else:
pix = self.pixmap
painter = QPainter(self)
painter.drawPixmap(event.rect(), pix)
def enterEvent(self, event):
self.update()
def leaveEvent(self, event):
self.update()
def sizeHint(self):
return QSize(131, 82)
app = QApplication(sys.argv)
window = QWidget()
window.setGeometry(800, 450, 800, 450)
pixmap = QPixmap("background.png")
brush = QBrush(pixmap)
palette = QPalette()
palette.setBrush(QPalette.Background, brush)
window.setPalette(palette)
button1 = PicButton(QtGui.QPixmap("cancel_up.png"), QtGui.QPixmap("cancel_down.png"), "cancel")
button2 = PicButton(QtGui.QPixmap("ok_up.png"), QtGui.QPixmap("ok_down.png"), "ok")
layout = QHBoxLayout()
layout.addStretch(1)
layout.addWidget(button1)
layout.addWidget(button2)
layout.setAlignment(Qt.AlignCenter)
window.setLayout(layout)
window.show()
sys.exit(app.exec_())
Get images in link: https://www.filedropper.com/imagens
Can somebody please tell me what I'm doing wrong?
I can't align the buttons in widget center: If you have applied addStretch() before button1 so that it is symmetrical you must set another addStretch() after button2
The buttons events occur twice: QAbstractButton already calls the update method when you press the button so it is not necessary to connect pressed or released signals to the update() method or call it in the enterEvent() and leaveEvent() methods.
Considering the above the solution is:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class PicButton(QtWidgets.QAbstractButton):
def __init__(self, pixmap, pixmap_pressed, id_button, parent=None):
super(PicButton, self).__init__(parent)
self.pixmap = pixmap
self.pixmap_pressed = pixmap_pressed
self.id_buton = id_button
def paintEvent(self, event):
if self.isDown():
pix = self.pixmap_pressed
print("botao pressionado: ", self.id_buton)
else:
pix = self.pixmap
painter = QtGui.QPainter(self)
painter.drawPixmap(event.rect(), pix)
def sizeHint(self):
return QtCore.QSize(131, 82)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window =QtWidgets. QWidget()
window.setGeometry(800, 450, 800, 450)
pixmap = QtGui.QPixmap("background.png")
brush = QtGui.QBrush(pixmap)
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Background, brush)
window.setPalette(palette)
button1 = PicButton(QtGui.QPixmap("cancel_up.png"), QtGui.QPixmap("cancel_down.png"), "cancel")
button2 = PicButton(QtGui.QPixmap("ok_up.png"), QtGui.QPixmap("ok_down.png"), "ok")
layout = QtWidgets.QHBoxLayout(window)
layout.addStretch()
layout.addWidget(button1)
layout.addWidget(button2)
layout.addStretch()
window.show()
sys.exit(app.exec_())

pyqt expand grid in scroll area

I have a grid area in a scroll area within a dialog
class IndicSelectWindow(QDialog):
def __init__(self, path, parent=None):
super(IndicSelectWindow, self).__init__(parent)
self.resize(500, 400)
self.scroll_area = QScrollArea(self)
self.scroll_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.grid_layout = QGridLayout(self.scroll_area)
self.exec_()
How can I make the grid cover the full area of the scroll_area. it does not have a method setSizePolicy. How can I make this work?
You must add the QGridLayout to the QWidget that is added to the QScrollArea
import sys
from PyQt5 import QtWidgets
class IndicSelectWindow(QtWidgets.QDialog):
def __init__(self, parent=None):
super(IndicSelectWindow, self).__init__(parent=parent)
self.resize(500, 400)
self.layout = QtWidgets.QHBoxLayout(self)
self.scrollArea = QtWidgets.QScrollArea(self)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.gridLayout = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.layout.addWidget(self.scrollArea)
for i in range(100):
for j in range(100):
self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = IndicSelectWindow()
w.show()
sys.exit(app.exec_())

Categories