PYQT Background image not showing correctly - python

I created a file using QT Designer, and I uploaded a background image. This file works well and the image appears in the background.
However, when the file is import to the main file, the image does not appear in the background correctly.
and project link
https://github.com/ahmedlam3y/GarageSystem

Because it is not the main window, but it is Ù‹Widget so the picture was not visible in the background and one of the Widgets has been set to the mainWindow so it work correctly
and The code for solution:
import sys
from PyQt5.QtCore import QSize
from PyQt5 import QtCore, QtGui, QtWidgets as Q
from PyQt5.QtGui import QImage, QPalette, QBrush
from PyQt5.QtWidgets import *
import image_rc
from SignIN import Ui_Form as SignInForm
from WelFrame import Ui_Form as WelFrameForm
from SignUp import Ui_Form as SignUpForm
from Accounting import Ui_Form as AccountForm
class SignIn(Q.QWidget, SignInForm): # Widget
def __init__(self, parent=None):
super(SignIn, self).__init__(parent)
Q.QWidget.__init__(self, parent)
self.setupUi(self)
oImage = QImage("GTR.png")
sImage = oImage.scaled(QSize(600, 360)) # resize Image to widgets size
palette = QPalette()
palette.setBrush(10, QBrush(sImage)) # 10 = WindowRole
self.setPalette(palette)
class WelFrame(Q.QMainWindow, WelFrameForm): # MainWindow
def __init__(self, parent=None):
Q.QWidget.__init__(self, parent)
self.setupUi(self)
class SignUp(Q.QWidget, SignUpForm): # Widget
def __init__(self, parent=None):
Q.QWidget.__init__(self, parent)
self.setupUi(self)
oImage = QImage("GTR.png")
sImage = oImage.scaled(QSize(600, 360)) # resize Image to widgets size
palette = QPalette()
palette.setBrush(10, QBrush(sImage)) # 10 = WindowRole
self.setPalette(palette)
class Accout(Q.QWidget, AccountForm): # Widget
def __init__(self, parent=None):
Q.QWidget.__init__(self, parent)
self.setupUi(self)
oImage = QImage("GTR.png")
sImage = oImage.scaled(QSize(600, 360)) # resize Image to widgets size
palette = QPalette()
palette.setBrush(10, QBrush(sImage)) # 10 = WindowRole
self.setPalette(palette)
def foo(w1, w2):
w1.show()
w2.hide()
if __name__ == '__main__':
app = Q.QApplication(sys.argv)
wel = WelFrame()
signIn = SignIn()
signUp = SignUp()
accout = AccountForm()
wel.pushButton_2.clicked.connect(lambda: foo(signIn, wel))
wel.pushButton.clicked.connect(lambda: foo(signUp, wel))
signIn.pushButton_2.clicked.connect(lambda: foo(wel, signIn))
signUp.pushButton_2.clicked.connect(lambda: foo(wel, signUp))
wel.show()
sys.exit(app.exec_())

Related

QPainter not drawing with mouse events

I have created a static GUI with a side panel and a custom widget handling the paintEvent.Both of which inherit the QFrame Object.
I begin with loading the image to the PainterFrame which works and then when I try to draw on top of this image it doesn't work despite the mousePressEvent getting triggered.
This is how it looks.
When I hit the choose File button and choose an image it successfully draws the Pixmap on the screen but when I try to draw nothing happens
This is the code for the custom widget PainterFrame and the RegisterFrame which handles the whole GUI.
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtGui as qtg
from PyQt5 import QtCore as qtc
from PyQt5.QtCore import Qt
from PIL import Image
from PIL.ImageQt import ImageQt
import io,sys
class PainterFrame(qtw.QFrame):
def __init__(self, parent=None):
super().__init__(parent)
self.image = None
# Create the properties for the custom object to fit to the parent widget
sizePolicy = qtw.QSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
self.lastPoint = qtc.QPoint()
self.setSizePolicy(sizePolicy)
self.setFrameShape(qtw.QFrame.StyledPanel)
self.setFrameShadow(qtw.QFrame.Plain)
self.show()
def paintEvent(self,event):
if self.image:
painter = qtg.QPainter(self)
self.pixmap = self.imageCovnerter(self.image).scaled(self.size(),qtc.Qt.IgnoreAspectRatio,qtc.Qt.SmoothTransformation)
painter.drawPixmap(self.rect(),self.pixmap)
self.update()
def mousePressEvent(self, event):
painter = qtg.QPainter(self.pixmap)
painter.setPen(qtg.QPen(Qt.red, 5, Qt.SolidLine))
painter.drawPoint(event.x(), event.y())
self.update()
def imageCovnerter(self,imageString):
image = Image.open(io.BytesIO(imageString)).convert("RGBA")
pix = qtg.QPixmap.fromImage(ImageQt(image))
return pix
def setUserImage(self, image):
self.image = image
And the code for the RegisterFrame
from StackedWidgetGUIS.RegisterGUI import Ui_Frame
from Frames.PainterFrame import PainterFrame
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtGui as qtg
from PyQt5 import QtCore as qtc
from PyQt5.QtCore import Qt
import re,os
class RegisterFrame(qtw.QFrame, Ui_Frame):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.painter_frame = PainterFrame()
self.horizontalLayout.addWidget(self.painter_frame)
self.horizontalLayout.setStretch(0, 1)
self.horizontalLayout.setStretch(1, 3)
self.back_button.clicked.connect(self.clearFields)
self.invalid_mail_label = qtw.QLabel("Invalid mail")
self.invalid_mail_label.setStyleSheet("font-family: \'Roboto\';\n"
"font-style: normal;\n"
"font-weight: 200;\n"
"font-size: 14px;\n"
"color: #E61518;")
self.entries_layout.addWidget(self.invalid_mail_label)
self.invalid_mail_label.setVisible(False)
self.email_edit.textChanged.connect(self.checkEmail)
self.choose_file_button.clicked.connect(self.launchDialog)
def clearFields(self):
self.first_name_edit.clear()
self.last_name_edit.clear()
self.email_edit.clear()
self.painter_frame.image = None
def checkEmail(self):
mail_regex = r'\b[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
if (re.fullmatch(mail_regex, self.email_edit.text())):
self.invalid_mail_label.setVisible(False)
else:
self.invalid_mail_label.setVisible(True)
def launchDialog(self):
file_filter = "Image File (*.png *.jpg)"
self.fileDialog = qtw.QFileDialog.getOpenFileName(parent =self,
caption="Select an image file",
directory= os.getcwd(),
filter=file_filter)
self.painter_frame.setUserImage(self.imageOpener(self.fileDialog[0]))
self.painter_frame.update()
def imageOpener(self, filePath):
with open(filePath, "rb") as f:
img = f.read()
return img

Background picture in QMainwindow PyQt5

I'm trying to get a background image to my mainwindow but i can't get it to work properly.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QLabel
from PyQt5.QtGui import QIcon
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSvg import *
from PyQt5.QtWidgets import *
from abc import abstractmethod
class App(QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.title = 'Title'
self.left = 500
self.top = 500
self.width = 440
self.height = 280
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# ...
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
#view = TableScene(ex)
ex.show()
sys.exit(app.exec_())
I've tried different kinds of methods but none of them works as it should.
I found the following code as a solution from another topic but it just gives me a black background and the rest of the widgets get laggy.
oImage = QImage("table.png")
sImage = oImage.scaled(QSize(440, 280))
palette = QPalette()
palette.setBrush(QPalette.Window, QBrush(sImage))
self.setPalette(palette)
I don't know if the whole window gets laggy or what really happens but the picture below is a screenshot of a part of the window using the code above, and as you can see it gets all black and the slider shows all the previous position it has been on, sort of laggy anyways.
I've also tried the setStyleSheet but I don't know if it's my syntax that's wrong or if it's a faulty way of doing it. Does anyone know a way of doing it correctly?
EDIT
This is my current window:
This is the picture I'm trying to implement as a background to my current window, the picture called "table.png" :
This is a visualization of what I'm trying to do, and this is made in paint since I don't know how to do it correctly:
And this is what I get if i use the code from the other topic:
One of the possible reasons why a black background appears is that QImage is null. And a QImage is null because the image is invalid or because the image path is incorrect. In this case I think it is the second case since the OP uses a relative path that is prone to errors. The solution is to build the absolute path using the script information such as its location:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class App(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.initUI()
def initUI(self):
self.setWindowTitle("Title")
self.setGeometry(500, 500, 440, 280)
oImage = QtGui.QImage(os.path.join(CURRENT_DIR, "table.png"))
sImage = oImage.scaled(QtCore.QSize(440, 280))
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush(sImage))
self.setPalette(palette)
pushbutton = QtWidgets.QPushButton("test", self)
pushbutton.move(100, 100)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
Note: The image provided by the OP has extension .jpg but the one indicated by code is .png, maybe "imgur" has changed the extension.
Note: If the window is resized manually, the following behavior will be observed:
So for this there are 2 possible solutions depending on the developer's criteria:
Set a fixed size: self.setFixedSize(440, 280)
Adapt the image to the size of the window:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class App(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.initUI()
def initUI(self):
self.setWindowTitle("Title")
self.setGeometry(500, 500, 440, 280)
pushbutton = QtWidgets.QPushButton("test", self)
pushbutton.move(100, 100)
self.oImage = QtGui.QImage(os.path.join(CURRENT_DIR, "table.png"))
# or QPixmap
# self.oPixmap = QtGui.QPixmap(os.path.join(CURRENT_DIR, "table.png"))
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.drawImage(self.rect(), self.oImage)
# or QPixmap
# painter.drawPixmap(self.rect(), self.oPixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
or
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class App(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.initUI()
def initUI(self):
self.setWindowTitle("Title")
self.setGeometry(500, 500, 440, 280)
pushbutton = QtWidgets.QPushButton("test", self)
pushbutton.move(100, 100)
self.setStyleSheet(
"""
QMainWindow{
border-image: url(%s) 0 0 0 0 stretch stretch
}
"""
% os.path.join(CURRENT_DIR, "table.png")
)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())

PyQt5: How to place a QPixmap on top of another QPixmap?

I would like to place a QPixmap on another QPixmap. Both have the same size, so I would just like to make an overlay. The overlay image has a transparent elipse in the middle. I figure they should be QPixmap format, however I dont know how to place them on top of each other and keep them in place when resizing the window. This is my code displaying how my background images are placed. I have attached a image explaining what i want.
import sys
from PyQt5 import QtGui ,QtWidgets, uic
from PyQt5.QtCore import Qt
class Ergolab(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(Ergolab, self).__init__(*args, **kwargs)
# Load the UI Page
self.ui = uic.loadUi("mainwindow.ui",self)
self.pixmap1 = QtGui.QPixmap('C:/Users/Frede/Desktop/img1.jpg')
self.shoflexLLabel.setPixmap(self.pixmap1.scaled(self.shoflexLLabel.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
self.shoflexLLabel.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.shoflexLLabel.setMinimumSize(150, 150)
self.shoflexLLabel.resize(800, 600)
self.pixmap2 = QtGui.QPixmap('C:/Users/Frede/Desktop/img2.jpg')
self.shoflexRLabel.setPixmap(self.pixmap2.scaled(self.shoflexRLabel.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
self.shoflexRLabel.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.shoflexRLabel.setMinimumSize(150, 150)
self.shoflexRLabel.resize(800, 600)
def resizeEvent(self, event):
scaledSize = self.shoflexLLabel.size()
if not self.shoflexLLabel.pixmap() or scaledSize != self.shoflexLLabel.pixmap().size():
self.updateLabel()
def updateLabel(self):
self.shoflexLLabel.setPixmap(self.pixmap1.scaled(
self.shoflexLLabel.size(), Qt.KeepAspectRatio,
Qt.SmoothTransformation))
self.shoflexRLabel.setPixmap(self.pixmap2.scaled(
self.shoflexRLabel.size(), Qt.KeepAspectRatio,
Qt.SmoothTransformation))
def main():
app = QtWidgets.QApplication(sys.argv)
main = Ergolab()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
This is the result I would like:
You must use QPainter by setting the circle as a clip path:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
label = QtWidgets.QLabel()
self.setCentralWidget(label)
base_pixmap = QtGui.QPixmap("background.png")
overlay_pixmap = QtGui.QPixmap("overlay.png")
radius = 300
r = QtCore.QRectF()
r.setSize(radius * QtCore.QSizeF(1, 1))
r.moveCenter(base_pixmap.rect().center())
path = QtGui.QPainterPath()
path.addEllipse(r)
painter = QtGui.QPainter(base_pixmap)
painter.setRenderHints(
QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform
)
painter.setClipPath(path, QtCore.Qt.IntersectClip)
painter.drawPixmap(QtCore.QPoint(), overlay_pixmap)
painter.end()
label.setPixmap(base_pixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Draw QFrame around QPushButton PyQt5

I am unable to get a QFrame to completely surround a QPushButton Like a Border. It only frames the top and left side of the button. I was wondering what I'm doing wrong with the frame.
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class main(QWidget):
def __init__(self):
super().__init__()
layout1 = QVBoxLayout()
btn1 = QPushButton("Test")
frame = QFrame(btn1)
frame.setGeometry(btn1.geometry())
frame.setFrameShape(QFrame.Box)
frame.setFrameShadow(QFrame.Plain)
frame.setLineWidth(4)
layout1.addWidget(btn1)
self.setLayout(layout1)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = main()
window.show()
sys.exit(app.exec_())
The problem is caused because the QFrame does not change the size, instead QPushButton does. In my solution I have resized every time the size is changed in the QPushButton
class FrameButton(QPushButton):
def __init__(self, *args, **kwargs):
QPushButton.__init__(self, *args, **kwargs)
self.frame = QFrame(self)
self.frame.setFrameShape(QFrame.Box)
self.frame.setFrameShadow(QFrame.Plain)
self.frame.setLineWidth(4)
def resizeEvent(self, event):
self.frame.resize(self.size())
QWidget.resizeEvent(self, event)
class main(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout(self)
layout.addWidget(FrameButton("Test"))

pyQT4 py3 Can't display image in QFrame background

I am trying since a little while to simply display an image in background of a QFrame and simply can't. I can see loads of example on the net but none of them seems to work with my code, and I can't understand why :
import sys, random
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QPalette, QBrush, QPixmap
class MainWin(QtGui.QMainWindow):
def __init__(self):
super(MainWin, self).__init__()
self.initUI()
def initUI(self):
#central widget
self.theboard = Board(self)
self.setCentralWidget(self.theboard)
self.resize(360, 760)
self.setWindowTitle('Name')
self.show()
class Board(QtGui.QFrame):
def __init__(self, parent):
super(Board, self).__init__(parent)
self.initBoard()
def initBoard(self):
print("ddd")
frame = Board
palette = QPalette(self)
palette.setBrush(QPalette.Background,QBrush(QPixmap("ImageTest.jpg")))
frame.setPalette(palette)
def main():
app = QtGui.QApplication([])
mw = MainWin()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
will return:
TypeError: QWidget.setPalette(QPalette): first argument of unbound method must have type 'QWidget'
If I don't pass my QFrame in a variable and do as such :
palette = QPalette(self)
palette.setBrush(QPalette.Background,QBrush(QPixmap("ImageTest.jpg")))
self.setPalette(palette)
No more errors but my background is still blank. Same thing if I just try to fill a color instead of the image.
Unless it's a top-level widget, you need to set the autoFillBackground property to get this to work:
def initBoard(self):
self.setAutoFillBackground(True)
palette = QPalette(self)
palette.setBrush(QPalette.Background, QBrush(QPixmap("ImageTest.jpg")))
self.setPalette(palette)
Alternatively, and more simply, use a style-sheet to set the background image:
def initBoard(self):
self.setStyleSheet('background-image: url("ImageTest.jpg")')

Categories

Resources