Search code examples
pythonpyqtpygamepyqt4qlabel

Trouble with updating text in QLabel


So I'm making a music player and I want a section where can see my songs, Page by page. The page switching works but the text doesn't update. I've tried googleing but i coudn't find a fitting/working anwser. For the people that want it, this is what my idle says:

1
0
2
3
n1
n2
1
1
2
3

Anyway here is my code:

import sys
import os
import pygame
from PyQt4 import QtGui, QtCore
from time import sleep

class Window(QtGui.QMainWindow):

    def __init__(self):
        super(Window, self).__init__()
        self.setGeometry(50, 50, 500, 300)
        self.setWindowTitle("Music Player Alpha")
        AutoPlay = True
        Song = os.listdir('/home/pi/Desktop/Muziek/' )
        Song = sorted(Song)
        self.Song = Song
        self.CurrentSong = 0
        self.PageNum = 0
        pygame.mixer.init()
        pygame.mixer.music.load('/home/pi/Desktop/Muziek/' + Song[0])
        pygame.mixer.music.play()
        self.home()

    def home(self):
        print("1")
        print(self.PageNum)
        btnQuit = QtGui.QPushButton("Quit", self)
        btnQuit.clicked.connect(self.close)
        btnQuit.move(400,270)
        btnPlay = QtGui.QPushButton("Play", self)
        btnPlay.clicked.connect(self.play)
        btnPlay.move(100, 270)
        btnPause = QtGui.QPushButton("Pause", self)
        btnPause.clicked.connect(self.pause)
        btnPause.move(200, 270)
        btnNext = QtGui.QPushButton("Next", self)
        btnNext.clicked.connect(self.next)
        btnNext.move(300, 270)
        btnPrevious = QtGui.QPushButton("Previous", self)
        btnPrevious.clicked.connect(self.previous)
        btnPrevious.move(0, 270)
        btnPrevPage = QtGui.QPushButton("Prev Page", self)
        btnPrevPage.clicked.connect(self.PrevPage)
        btnPrevPage.move(0,160)
        btnNextPage = QtGui.QPushButton("Next Page", self)
        btnNextPage.clicked.connect(self.NextPage)
        btnNextPage.move(100, 160)
        try:
            txtNum1 = QtGui.QLabel(self.Song[0 + 10*self.PageNum], self)
            txtNum1.resize(500, 30)
            txtNum2 = QtGui.QLabel(self.Song[1 + 10*self.PageNum], self)
            txtNum2.move(0, 15)
            txtNum2.resize(500, 30)
            txtNum3 = QtGui.QLabel(self.Song[2 + 10*self.PageNum], self)
            txtNum3.move(0, 30)
            txtNum3.resize(500, 30)
            txtNum4 = QtGui.QLabel(self.Song[3 + 10*self.PageNum], self)
            txtNum4.move(0, 45)
            txtNum4.resize(500, 30)
            txtNum5 = QtGui.QLabel(self.Song[4 + 10*self.PageNum], self)
            txtNum5.move(0, 60)
            txtNum5.resize(500, 30)
            txtNum6 = QtGui.QLabel(self.Song[5 + 10*self.PageNum], self)
            txtNum6.move(0, 75)
            txtNum6.resize(500, 30)
            txtNum7 = QtGui.QLabel(self.Song[6 + 10*self.PageNum], self)
            txtNum7.move(0, 90)
            txtNum7.resize(500, 30)
            txtNum8 = QtGui.QLabel(self.Song[7 + 10*self.PageNum], self)
            txtNum8.move(0, 105)
            txtNum8.resize(500, 30)
            txtNum9 = QtGui.QLabel(self.Song[8 + 10*self.PageNum], self)
            txtNum9.move(0, 120)
            txtNum9.resize(500, 30)
            txtNum10 = QtGui.QLabel(self.Song[9 + 10*self.PageNum], self)
            txtNum10.move(0, 135)
            txtNum10.resize(500, 30)
            print("2")
        except IndexError:
            print("2.5")
        self.show()
        print("3")

    def close(self):
        sys.exit()

    def play(self):
        pygame.mixer.music.unpause()

    def pause(self):
        pygame.mixer.music.pause()

    def next(self, event):
        self.CurrentSong = self.CurrentSong + 1
        if self.CurrentSong > len(self.Song) + 1:
            self.CurrentSong = 0
        pygame.mixer.music.load('/home/pi/Desktop/Muziek/' + self.Song[self.CurrentSong])
        pygame.mixer.music.play()
        return self.CurrentSong;

    def previous(self, event):
        self.CurrentSong = self.CurrentSong - 1
        if self.CurrentSong < 0:
            self.CurrentSong = len(self.Song) -1
        pygame.mixer.music.load('/home/pi/Desktop/Muziek/' + self.Song[self.CurrentSong])
        pygame.mixer.music.play()

    def PrevPage(self, event):
        print("p1")
        self.PageNum = self.PageNum - 1
        if self.PageNum < 0 :
            print("p<0")
            self.PageNum = 0
        print("p2")
        self.home()
        return self.PageNum;

    def NextPage(self, event):
        print("n1")
        self.PageNum = self.PageNum + 1
        if self.PageNum > len(self.Song) / 10:
            print("n>0")
        self.PageNum = self.PageNum - 1
        print("n2")
        self.home()
        return self.PageNum;

app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())

Solution

  • The problem is that every time you call the home() function you are creating new labels, what you have to do is just update the text, for this we create a list of labels. Avoid using try and except since the program may have errors, it is better to verify that the index of the list is in the range.

    When closing the window it is better to release the sound resource with pygame.mixer.quit() before closing the window, for this it is better to overwrite closeEvent().

    import sys
    import os
    import pygame
    from PyQt4 import QtGui, QtCore
    from time import sleep
    
    
    class Window(QtGui.QMainWindow):
        song_per_page = 10
        directory = '/home/pi/Desktop/Muziek/'
    
        def __init__(self):
            super(Window, self).__init__()
            self.setGeometry(50, 50, 500, 300)
            self.setWindowTitle("Music Player Alpha")
            AutoPlay = True
            Song = os.listdir(self.directory)
            Song = sorted(Song)
            self.Song = Song
            self.CurrentSong = 0
            self.PageNum = 0
            pygame.mixer.init()
            self.txtNums = []
            self.home()
            self.song()
    
        def home(self):
            btnQuit = QtGui.QPushButton("Quit", self)
            btnQuit.clicked.connect(self.close)
            btnQuit.move(400, 270)
            btnPlay = QtGui.QPushButton("Play", self)
            btnPlay.clicked.connect(self.play)
            btnPlay.move(100, 270)
            btnPause = QtGui.QPushButton("Pause", self)
            btnPause.clicked.connect(self.pause)
            btnPause.move(200, 270)
            btnNext = QtGui.QPushButton("Next", self)
            btnNext.clicked.connect(self.next)
            btnNext.move(300, 270)
            btnPrevious = QtGui.QPushButton("Previous", self)
            btnPrevious.clicked.connect(self.previous)
            btnPrevious.move(0, 270)
            btnPrevPage = QtGui.QPushButton("Prev Page", self)
            btnPrevPage.clicked.connect(self.PrevPage)
            btnPrevPage.move(0, 160)
            btnNextPage = QtGui.QPushButton("Next Page", self)
            btnNextPage.clicked.connect(self.NextPage)
            btnNextPage.move(100, 160)
    
            for i in range(self.song_per_page):
                txtNum = QtGui.QLabel(self)
                txtNum.resize(500, 30)
                txtNum.move(0, 15 * i)
                self.txtNums.append(txtNum)
            self.updateLabels()
            self.show()
    
        def updateLabels(self):
            print(self.CurrentSong, self.PageNum)
            for i in range(len(self.txtNums)):
                index = i + self.song_per_page * self.PageNum
                self.txtNums[i].clear()
                if index < len(self.Song):
                    self.txtNums[i].setText(self.Song[i + self.song_per_page * self.PageNum])
    
        def closeEvent(self, event):
            pygame.mixer.quit()
            QtGui.QMainWindow.closeEvent(self, event)
    
        def play(self):
            pygame.mixer.music.unpause()
    
        def pause(self):
            pygame.mixer.music.pause()
    
        def song(self):
            try:
                pygame.mixer.music.load(self.directory + self.Song[self.CurrentSong])
                pygame.mixer.music.play()
            except pygame.error:
                print("Module format not recognized")
    
            self.updateLabels()
    
        def next(self, event):
            self.CurrentSong = (self.CurrentSong + 1) % len(self.Song)
            self.song()
    
        def previous(self, event):
            self.CurrentSong = (self.CurrentSong - 1) % len(self.Song)
            self.song()
    
        def PrevPage(self, event):
            self.PageNum = self.PageNum - 1
            if self.PageNum < 0:
                self.PageNum = 0
            self.updateLabels()
    
        def NextPage(self, event):
            if self.song_per_page * (self.PageNum + 1) - 1 < len(self.Song):
                self.PageNum = self.PageNum + 1
            self.updateLabels()
    
    
    app = QtGui.QApplication(sys.argv)
    GUI = Window()
    sys.exit(app.exec_())