Issue
I'm doing a simple text based adventure using PyQt and buttons. For some reason, after clicking a few buttons, there's some awful lag when clicking a button before the screen is refreshed. Why does this happen? Since I have no idea what's causing this problem, I'll copy the whole ~100 line program...
import sys, time
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 600, 400)
self.setWindowTitle("Omar OK Adventures!")
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create("plastique"))
self.home()
def home(self):
btn1 = QtGui.QPushButton("New Game", self)
btn1.clicked.connect(self.change)
btn1.resize(500, 25)
btn1.move(50, 275)
self.btn1 = btn1
btn2 = QtGui.QPushButton("What's this all about?", self)
btn2.clicked.connect(self.wat)
btn2.resize(500, 25)
btn2.move(50, 305)
self.btn2 = btn2
btn3 = QtGui.QPushButton("...", self)
btn3.resize(500, 25)
btn3.move(50, -200)
self.btn3 = btn3
btn4 = QtGui.QPushButton("...", self)
btn4.resize(500, 25)
btn4.move(50, -200)
self.btn4 = btn4
txt = "Welcome to the main menu! (WIP obviously)"
lbl = QtGui.QLabel(txt, self)
lbl.resize(500, 200)
lbl.move(50, 25)
lbl.setAlignment(QtCore.Qt.AlignCenter)
self.lbl = lbl
self.show()
def homefake(self):
self.btn1.setText("Begin teh epic adventures")
self.btn1.clicked.connect(self.change)
self.btn2.setText("What's this all about?")
self.btn2.clicked.connect(self.wat)
self.btn2.move(50,305)
self.btn3.move(50, -200)
self.btn4.move(50, -200)
self.lbl.setText("Welcome to the main menu! (WIP obviously)")
def close_application(self):
choice = QtGui.QMessageBox.question(self, "Gemme outta here!",
"Do you really want to quit?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if choice == QtGui.QMessageBox.Yes:
sys.exit()
else:
pass
def closeEvent(self, event):
event.ignore()
self.close_application()
def C1_1(self):
self.lbl.setText("You tell your parents that you're going to Japan to get some 'stuff'\nThey tell you to be back at dinner\nOk.\nYou buy a plane ticket and board the plane\nYou realize boarding the plane is boring as hell.\nWhat should you do to kill time?")
self.btn1.setText("Take over the plane (Try not to crash it horribly)")
self.btn1.clicked.connect(self.C2_1)
self.btn2.setText("Watch a movie on the not-tablet stuck on a chair infront of you (Really, it's a tablet stuck on a chair.)")
self.btn2.move(50, 305)
self.btn2.clicked.connect(self.C2_2)
self.btn3.move(50, -200)
self.btn4.move(50, -200)
def C2_1(self):
self.btn1.setText("Restart game")
self.btn1.clicked.connect(self.homefake)
self.btn2.move(50, -200)
self.lbl.setText("You pull out your combat shotgun and tell everyone to freeze and go on the floor.\nNeedless to say, people are screaming.\nSome guy tried to tackle you\nYou shot him\nSome air police jackass lands a headshot on you while you were looking away\nYou died.\n\nGood job.")
def C2_2(self):
self.lbl.setText('lol')
def C1_2(self):
self.lbl.setText("ARMED MEN")
def C1_3(self):
self.lbl.setText("TAKIN A HIKE")
def C1_4(self):
self.lbl.setText("HORSE TIME")
def wat(self):
self.lbl.setText("What's this?\nThis is pretty much a 5 minute (or so) test to see the capabilities of text based adventures.\n I'll probably be doing stuff much better later on. Keep an eye out!\nI probably won't replace this even if it's a joke program. Just because.\n\nCreated by popcar2")
self.btn1.setText("Back to main menu")
self.btn2.move(50, -200)
self.btn1.clicked.connect(self.homefake)
def change(self, txt):
self.lbl.setText("You're sitting at home, incredibly bored as usual.\nHowever... You decided to do something new in your okeil life...\nA few ideas pop up in your head, what do you wanna do?")
self.btn1.setText("Go steal whatever's nuclear in one of Japan's nuclear power plants (Diseases might be included)")
self.btn2.move(50, 305)
self.btn2.setText("Hire a group of armed men and take over the school (Be sure to tie kids as hostages)")
self.btn3.move(50, 335)
self.btn3.setText("Take a walk (TAKE A HIKE, MATE)")
self.btn4.move(50, 365)
self.btn4.setText("Steal a horse (The only logical option)")
self.btn1.clicked.connect(self.C1_1)
self.btn2.clicked.connect(self.C1_2)
self.btn3.clicked.connect(self.C1_3)
self.btn4.clicked.connect(self.C1_4)
def run():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()
Solution
When you make a signal connection (btnX.clicked.connect()
) this does not automatically disconnect the previously connected slot. As such, as you progress through your game, each button click is actually executing every method that has been connected to it, which starts getting slower and slower as more and more methods are connected to the clicked signal of each button.
You need to call btnX.clicked.disconnect(previous_slot)
before making the new connection with btnX.clicked.connect(new_slot)
.
This requires you to know which slot was previously connected (as you need to refer to the method name) when you come to connect the next method. I haven't followed through the logic of your program to see how easy that is, but it is what you need to do. Otherwise you will need to take a different approach that doesn't require changing the slot the button is connected to (for example using a stacked widget to switch between different sets of buttons, or similar)
Answered By - three_pineapples
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.