pythonpython-3.xpyqt5qpushbuttonborder-image

Pyqt5 List QtPushbutton add border-image


I'm using Python 3 ( Pycharm ) with Pyqt5 (Windows 10)

I need to use a list of QPushbutton. I managed to change the color of button, it's ok. Nevertheless, I couldn't change the image of border-image (same QT), into my function to add button (Add_Buttons_KA_IU) The structure of my repertory :

My_Project :

|-> Vision_Room.py

|-> Ressource -> LightOff.png 

import sys
from PyQt5.QtWidgets import QMainWindow,QWidget,QLabel,QLineEdit,QPushButton,QApplication,QVBoxLayout
from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindows(QMainWindow):
    buttons_KA, keydata_KA = {}, {}
    Positions_Button_KA = [(330, 70, 10, 20),(270, 110, 10, 20),(300, 110, 10, 20),(360, 110, 10, 20),(330, 150, 10, 20),
                           (180, 190, 10, 20),(240, 190, 10, 20),(300, 190, 10, 20),(360, 190, 10, 20),(210, 230, 10, 20),
                           (270, 230, 10, 20),(330, 230, 10, 20),(180, 270, 10, 20),(240, 270, 10, 20),(270, 270, 10, 20),
                           (300, 270, 10, 20),(360, 270, 10, 20),(210, 310, 10, 20),(330, 310, 10, 20),(180, 350, 10, 20),
                           (240, 350, 10, 20),(300, 350, 10, 20),(360, 350, 10, 20),(210, 390, 10, 20),(270, 390, 10, 20),
                           (330, 390, 10, 20),(180, 430, 10, 20),(240, 430, 10, 20),(300, 430, 10, 20),(360, 430, 10, 20)]

    def __init__(self):
        super(Ui_MainWindows,self).__init__()
        #self.layout = QVBoxLayout()
        self.resize(1280,960)
        self.centralWidget = QWidget(self)
        self.setCentralWidget(self.centralWidget)
        self.setWindowTitle("Vision Room")
        #self.setStyleSheet("background-color: rgb(0, 0, 0);")
        self.Add_Buttons_KA_IU()

    def Add_Buttons_KA_IU(self):
        Name_Button = "Button_KA"
        for i in range(0, 30):

            Full_Name_Button = Name_Button + str(i)
            print(Full_Name_Button)

            b = self.buttons_KA[i] = QtWidgets.QPushButton(self.centralWidget)

            b.setGeometry(QtCore.QRect(self.Positions_Button_KA[i][0],self.Positions_Button_KA[i][1],self.Positions_Button_KA[i][2],
                                       self.Positions_Button_KA[i][3]))


            #str_Style_Sheet = "#" + Full_Name_Button + "\n" "{\n""background-color: rgb(0, 0, 255);\n" "}"
            str_Style_Sheet = "#" + Full_Name_Button + "\n" "{\n""border-image: url(:/Ressource/LightOff.png);\n" "}"
            print(str_Style_Sheet)
            b.setObjectName(Full_Name_Button)

            b.setStyleSheet(str_Style_Sheet)

def main():
    app = QApplication(sys.argv)
    MainWindow = Ui_MainWindows()
    MainWindow.show()

    rc = app.exec_()
    sys.exit(rc)


if __name__ == "__main__":
    main()

Solution

  • First of all if you are going to add QSS to each button it is not necessary to use objectName, on the other hand the problem is caused because you do not understand what the ":" means, the ":" indicates that you are using a qresource (.qrc) that is a file that allows to store files universally in Qt, and that is a virtual path, you should not use those ":" because you are not using it. On the other hand it is always better to have the fullpath of the files to avoid problems, but it must also be easy to manage, so the solution is to obtain the path of the .py and concatenate it with the relative path of the resource with respect to the .py, so you can move your project and even then it will work.

    import os
    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    dir_path = os.path.dirname(os.path.realpath(__file__))
    
    positions_button_KA = [(330, 70, 10, 20),(270, 110, 10, 20),(300, 110, 10, 20),(360, 110, 10, 20),(330, 150, 10, 20),
                           (180, 190, 10, 20),(240, 190, 10, 20),(300, 190, 10, 20),(360, 190, 10, 20),(210, 230, 10, 20),
                           (270, 230, 10, 20),(330, 230, 10, 20),(180, 270, 10, 20),(240, 270, 10, 20),(270, 270, 10, 20),
                           (300, 270, 10, 20),(360, 270, 10, 20),(210, 310, 10, 20),(330, 310, 10, 20),(180, 350, 10, 20),
                           (240, 350, 10, 20),(300, 350, 10, 20),(360, 350, 10, 20),(210, 390, 10, 20),(270, 390, 10, 20),
                           (330, 390, 10, 20),(180, 430, 10, 20),(240, 430, 10, 20),(300, 430, 10, 20),(360, 430, 10, 20)]
    
    
    class Ui_MainWindows(QtWidgets.QMainWindow):
        def __init__(self):
            super(Ui_MainWindows,self).__init__()
            self.central_widget = QtWidgets.QWidget()
            self.setCentralWidget(self.central_widget)
            self.setWindowTitle("Vision Room")
    
            self.buttons_KA = {}
    
            self.add_buttons_KA_IU()
            self.resize(1280, 960)
    
    
        def add_buttons_KA_IU(self):
            name_group = "button_KA"
            for i, geom in enumerate(positions_button_KA):
                b = QtWidgets.QPushButton(self.central_widget)
                b.setGeometry(*geom)
                path_image = os.path.join(dir_path, "Ressource/LightOff.png").replace("\\", "/")
                qss = 'border-image: url({})'.format(path_image)
                b.setStyleSheet(qss)
    
                self.buttons_KA[i] = b
    
    def main():
        app = QtWidgets.QApplication(sys.argv)
        MainWindow = Ui_MainWindows()
        MainWindow.show()
    
        rc = app.exec_()
        sys.exit(rc)
    
    
    if __name__ == "__main__":
        main()
    

    Linux:

    enter image description here

    Windows:

    enter image description here