Search code examples
pyqtqwidgetqlabelqpixmap

Function call only works in constructor, otherwise function spawns an invisible label


I'm programming snake with pyqt5. Then I try to use self.spawnFruit() in the constructor everything works and i see the fruits in the Window. But when I try to use the same function outside of init() nothing on the window appears.

E.g. I have a Key.Event that will call the function self.spawnFruit if I press F.

It seems that the labels are on Gui but they're invisible.

import sys
from PyQt5.QtCore import Qt
import PyQt5.QtWidgets as qw
from PyQt5 import QtGui as gui
from PyQt5 import QtCore as core
import numpy as np

spielfeldgröße = 16
state = [[0 for y in range(spielfeldgröße)] for x in range(spielfeldgröße)]
size = 30#10 pixel

class GameWindow(qw.QWidget):

    def __init__(self):
        super().__init__()
        self.setGeometry(500,500,500,500)

        self.spawnFruit() #spawns a fruit

    def spawnFruit(self):
        fruitpixmap = gui.QPixmap(size,size)
        fruitpixmap.fill(Qt.red)

        #find available spots to spawn fruits on the map
        available = list()
        for x in range(spielfeldgröße):
            for y in range(spielfeldgröße):
                if self.state[x][y] == 0:
                    available.append((x,y))

        lenght = len(available)
        rand = np.random.randint(0, lenght)

        x,y = available[rand]
        print("fruit at:", x, ":", y)
        #spawn
        label = qw.QLabel(self)
        label.setPixmap(fruitpixmap)
        label.move(x*size, y*size)

    def keyPressEvent(self, event):
        if(key == Qt.Key_F):
            self.spawnFruit() #doesn't spawns a fruit
        else:
            super().keyPressEvent(event)


app = qw.QApplication(sys.argv)
win = GameWindow()
win.show()
app.exec_()

Solution

  • Please try this code.

    Explanation

    There are some points to say, but the main problem is why new labels don't show up?

    In python , with PyQt and PySide. We prepare the widgets in advance , and set them to the main widget and show them all at the last time.

    If you want to add the new visible item to it, you must call clearly setVisible(True) respectively.

    and event.key() == Qt.Key_F: is the idiom of keyEvents.

    It is often confused.

    And please warn IndexError of the state. list starts from 0 ,so you often meet the IndexError.

    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    import sys
    import random
    spielfeldgröße = 16
    
    size = 30#10 pixel
    class GameWindow(QWidget):
    
        def __init__(self):
            super().__init__()
            self.setGeometry(500,500,500,500)
            self.state = [[0 for y in range(spielfeldgröße)] for x in range(spielfeldgröße)]
            self.spawnFruit() #spawns a fruit
    
        def spawnFruit(self):
    
            fruitpixmap = QPixmap(size,size)
            fruitpixmap.fill(Qt.red)
    
            #find available spots to spawn fruits on the map
            available = list()
            for x in range(spielfeldgröße-1):
                for y in range(spielfeldgröße-1):
                    if self.state[x][y] == 0:
                        available.append((x,y))
    
            lenght = len(available)
            rand = random.randint(0, lenght - 1)
    
            x,y = available[rand]
            print("fruit at:", x, ":", y)
            #spawn
            label = QLabel(self)
            label.setPixmap(fruitpixmap)  
            label.move(x*size, y*size)
            label.setVisible(True)
    
        def keyPressEvent(self, event):
            if(event.key() == Qt.Key_F):
                self.spawnFruit() #doesn't spawns a fruit
            else:
                super().keyPressEvent(event)
    
    
    app = QApplication(sys.argv)
    win = GameWindow()
    win.show()
    sys.exit(app.exec_())