Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 [PyQt] how to dynamically add label to pyqt window
#1
I need to be able to dynamically add an object like a label to my window. How do I do that? Here is the code that I have.

import random
import sys

from PIL import Image
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget
from Image2 import Ui_Form


class MyMainWindow(QWidget, Ui_Form):

    human_list = []

    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        self.addHuman(random.randint(1, 10000), random.randint(1, 500), random.randint(1, 200))

    def mouseDoubleClickEvent(self, event):
        self.addHuman(random.randint(1, 10000), random.randint(1, 500), random.randint(1, 200))

    def addHuman(self, humanId, x, y):
        human = HumanLabel(humanId, x, y, self)
        human.addHumanLabel()
        self.human_list.append(human)
        QApplication.processEvents()



class HumanLabel():

    def __init__(self, humanId, x, y, Form):
        self.humanId = humanId
        self.x = x
        self.y = y
        self.form = Form

    def addHumanLabel(self):
        self.label = QtWidgets.QLabel(self.form)
        self.label.setGeometry(QtCore.QRect(self.x, self.y, 500, 375))
        img = Image.open('./321.jpg')
        img.resize((20, 20), Image.ANTIALIAS)
        self.label.setPixmap(QPixmap('./456.jpg'))
        self.label.setObjectName(str(self.humanId))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MyMainWindow()
    win.show()
    sys.exit(app.exec_())
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(500, 375)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(0, 0, 500, 375))
        self.label.setPixmap(QPixmap('./123.jpg'))
        self.label.setObjectName("background")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
The problem is when I double click the mouse that the new human label is being created but it will not show on the window. How do I get the label to show on the window?
Quote
#2
I think your biggest issue was that you were not showing the Label which means while you were creating it you could not see it. Still there might have been a few other issues with how you were going about it so I have tweaked what you had and made it more Classy [which is to say I expounded on the class ;)]. Now other than not showing images because I did not have them this code does work and using the coordinates as text. Note I capped your random coordinates so that the text remained on the form you will have to do something similar when you use the images (basically subtract the image size from your maximum values to get your maximum coordinates).

from random import randint
from sys import exit as sysExit
 
#from PIL import Image

from PyQt5.QtGui import QPixmap

from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWidgets import QLabel

# Okay I was not sure what this was or why but it did not
# seem to me to be part of adding a human to the form and
# since I could not use it anyway I removed it to here
#    img = Image.open('./321.jpg')
#    img.resize((20, 20), Image.ANTIALIAS)


class HumanLabel(QLabel):
    def __init__(self, parent):
        QLabel.__init__ (self, parent)

        self.HumanLocale = parent

    @property
    def HumanLocale(self):
      # On what Form is the Human located
        return self.__parent

    @HumanLocale.setter
    def HumanLocale(self, value):
        self.__parent = value

    @property
    def xCor(self):
      # Human's current X-Coordinate
        return self.__xCoordinate

    @xCor.setter
    def xCor(self, value):
        self.__xCoordinate = value

    @property
    def yCor(self):
      # Human's current Y-Coordinate
        return self.__yCoordinate

    @yCor.setter
    def yCor(self, value):
        self.__yCoordinate = value

    @property
    def HumanImage(self):
      # Human's current Image
        return self.__HumanImage

    @HumanImage.setter
    def HumanImage(self, value):
        self.__HumanImage.setPixmap(QPixmap(value))

    def placeHuman(self):
        self.move(self.xCor, self.yCor)
      # I do not have access to your Image so did this instead
        value = str(self.xCor) + '-' + str(self.yCor)
        self.setText(value)
#        self.Humans[humanId].HumanImage = './456.jpg'
        self.show()

    def addHumanRandomly(self):
      # Note because you do not currently check to see if
      # the current humanId is not already in your list
      # you may end up just moving them instead of creating
      # them as such I would suggest such a check here and
      # creating another method called moveHuman
        self.xCor = randint(1, 450)
        self.yCor = randint(1, 350)
        self.placeHuman()
        
class MyMainWindow(QWidget):
    def __init__(self):
        super(MyMainWindow, self).__init__()

        self.Humans = {}
 
        self.setupUi()

        humanId = randint(1, 10000)
        self.Humans[humanId] = HumanLabel(self)
        self.Humans[humanId].addHumanRandomly()

    def setupUi(self):
        self.setWindowTitle('Form')
        self.resize(500, 375)

        humanId = 1
        self.Humans[humanId] = HumanLabel(self)
        self.Humans[humanId].xCor = 0
        self.Humans[humanId].yCor = 0
#        self.Humans[humanId].HumanImage = './123.jpg'
        self.Humans[humanId].placeHuman()
 
    def mouseDoubleClickEvent(self, event):
        humanId = randint(1, 10000)
      # Create the object within the Dictionary
        self.Humans[humanId] = HumanLabel(self)
      # Then using that object stored in our Dictionary
      # we set its coordinates and show it
        self.Humans[humanId].addHumanRandomly()
 
if __name__ == '__main__':
    MainThred = QApplication([])

    MainGui = MyMainWindow()
    MainGui.show()

    sysExit(MainThred.exec_())
As you can see I used a dictionary to house your dynamic creation of labels it is the only way I know that you can do that but there might be other methods. Now if you wanted to track your Human Ids for any reason I would create a separate list for those or just reference the .keys() value of the dictionary. Of course if you have any questions about why I did any of the things I did just ask.
silly American kah-nig-hit
Quote
#3
(Aug-26-2019, 03:25 PM)Denni Wrote: I think your biggest issue was that you were not showing the Label which means while you were creating it you could not see it. Still there might have been a few other issues with how you were going about it so I have tweaked what you had and made it more Classy [which is to say I expounded on the class ;)]. Now other than not showing images because I did not have them this code does work and using the coordinates as text. Note I capped your random coordinates so that the text remained on the form you will have to do something similar when you use the images (basically subtract the image size from your maximum values to get your maximum coordinates).

from random import randint
from sys import exit as sysExit
 
#from PIL import Image

from PyQt5.QtGui import QPixmap

from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWidgets import QLabel

# Okay I was not sure what this was or why but it did not
# seem to me to be part of adding a human to the form and
# since I could not use it anyway I removed it to here
#    img = Image.open('./321.jpg')
#    img.resize((20, 20), Image.ANTIALIAS)


class HumanLabel(QLabel):
    def __init__(self, parent):
        QLabel.__init__ (self, parent)

        self.HumanLocale = parent

    @property
    def HumanLocale(self):
      # On what Form is the Human located
        return self.__parent

    @HumanLocale.setter
    def HumanLocale(self, value):
        self.__parent = value

    @property
    def xCor(self):
      # Human's current X-Coordinate
        return self.__xCoordinate

    @xCor.setter
    def xCor(self, value):
        self.__xCoordinate = value

    @property
    def yCor(self):
      # Human's current Y-Coordinate
        return self.__yCoordinate

    @yCor.setter
    def yCor(self, value):
        self.__yCoordinate = value

    @property
    def HumanImage(self):
      # Human's current Image
        return self.__HumanImage

    @HumanImage.setter
    def HumanImage(self, value):
        self.__HumanImage.setPixmap(QPixmap(value))

    def placeHuman(self):
        self.move(self.xCor, self.yCor)
      # I do not have access to your Image so did this instead
        value = str(self.xCor) + '-' + str(self.yCor)
        self.setText(value)
#        self.Humans[humanId].HumanImage = './456.jpg'
        self.show()

    def addHumanRandomly(self):
      # Note because you do not currently check to see if
      # the current humanId is not already in your list
      # you may end up just moving them instead of creating
      # them as such I would suggest such a check here and
      # creating another method called moveHuman
        self.xCor = randint(1, 450)
        self.yCor = randint(1, 350)
        self.placeHuman()
        
class MyMainWindow(QWidget):
    def __init__(self):
        super(MyMainWindow, self).__init__()

        self.Humans = {}
 
        self.setupUi()

        humanId = randint(1, 10000)
        self.Humans[humanId] = HumanLabel(self)
        self.Humans[humanId].addHumanRandomly()

    def setupUi(self):
        self.setWindowTitle('Form')
        self.resize(500, 375)

        humanId = 1
        self.Humans[humanId] = HumanLabel(self)
        self.Humans[humanId].xCor = 0
        self.Humans[humanId].yCor = 0
#        self.Humans[humanId].HumanImage = './123.jpg'
        self.Humans[humanId].placeHuman()
 
    def mouseDoubleClickEvent(self, event):
        humanId = randint(1, 10000)
      # Create the object within the Dictionary
        self.Humans[humanId] = HumanLabel(self)
      # Then using that object stored in our Dictionary
      # we set its coordinates and show it
        self.Humans[humanId].addHumanRandomly()
 
if __name__ == '__main__':
    MainThred = QApplication([])

    MainGui = MyMainWindow()
    MainGui.show()

    sysExit(MainThred.exec_())
As you can see I used a dictionary to house your dynamic creation of labels it is the only way I know that you can do that but there might be other methods. Now if you wanted to track your Human Ids for any reason I would create a separate list for those or just reference the .keys() value of the dictionary. Of course if you have any questions about why I did any of the things I did just ask.

Big Grin Thanks,I solved my proble, I found I should add 'label.show()' every time I create a label. And thanks for Ur suggestions
Quote
#4
Oh my if you are doing .show() with every label you are definitely doing something wrong as the .show() should only be applied to the container Widget not all the Widgets in the container.
silly American kah-nig-hit
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  A dynamically updating screen for PyQt GUI from URL bescf 0 373 Mar-25-2019, 06:58 AM
Last Post: bescf
  pyqt main window refresh poblems duende 0 1,431 Apr-13-2018, 05:05 PM
Last Post: duende
  [PyQt] how to dynamically add objects to pyqt window LavaCreeperKing 1 6,481 Apr-26-2017, 09:15 PM
Last Post: joe_anonimist
  update a variable in parent window after closing its toplevel window gray 5 2,680 Mar-20-2017, 10:35 PM
Last Post: Larz60+

Forum Jump:


Users browsing this thread: 1 Guest(s)