问题描述
我现在遇到了死胡同 - 首先,当您单击一个动态按钮时,会进行函数调用,并且它确实返回所单击按钮的名称。
然而,它应该调用的fEndDay
函数似乎没有运行。
编辑:这一天正在运行。 刚刚重新启动了 Liclipse,它开始工作了。 没有解释。 但是,按钮等待问题仍然存在。
我现在也有点卡住了。 本质上我想要:
-
而当日 < 总天数....
- 运行每日事件,更新屏幕对象。
- 通过单击按钮进行选择。
- 增加当前日期。
但是,日循环会停止显示屏幕(即处理循环)。 我想如果有代码将对象显示向上推并处于无限循环中,该循环被按钮单击破坏,那就可以了。 其他想法? 下面的当前代码。
#!/usr/bin/python
# Reminder to self - lots to add. Include a function to reset the text content
# and populate with day number, score summary etc as a template. We can then
# add to it.
#################### IMPORT MODULES WE NEED ############################
import time # For sleep delays
from random import randint # for random numbers
from _ast import While # while loops
import tkinter as Tkinter # this one handles windows and buttons etc
from tkinter import * # skip the tkinter prefix (constants etc)
# import tkmessagebox # Python 2 alternative!
from tkinter import messagebox as tkMessageBox # Python 3
import sys # for quit when added ie sys.exit()
from functools import partial # So we can create lists of buttons & commands
import time # threading support - check events while waiting
import concurrent.futures # threading - think i'll be needing all this
################## CREATE A NEW CLASS (CONTAINER) ############################
class CrazyCoder (Tkinter.Tk):
# When the class is created, the function fInitialise is run, below.
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.fInitialize() # State here any functions to run on creation
################################ FUNCTION ################################
# Set up variables etc...
def fInitialize(self):
########################### VARIABLES ###############################
# Overkill here probably but will revisit later! Listed / initialised
# here to simplify searching later on!
# Could pass most of theses but will keep it simple and update globally
# to start with
self.vDayNumber = 1 # What the current day is
self.vFinalDay = 10 # The last day of our game
self.vPlayerName = '' # To hold the players name
self.vGameName = '' # To hold the game name
self.vChoice = '' # To hold the user choices clicked
self.vRandom = 0 # To hold random numbers!
self.vGameplay = 0 # SCORES: Current gameplay score
self.vGraphics = 0 # SCORES: Current graphics score
self.vSound = 0 # SCORES: current sound score
self.vBugs = 0 # SCORES: current bug score'
self.vBackColor = 'grey' # The background colour of our app
self.vDynamic_Buttons = [] # To hold button objects each "screen"
self.vEntryBox = [] # To hold text entry box objects
self.vTextEntry = '' # Stores user text entry value temporarily
self.vAvailableButtons = [] # To hold a list of AVAILABLE buttons/event
########################## APP SETUP ################################
self.title('Crazy Coder') # set window title
self.geometry("500x500") # set screen size
self.configure(background=self.vBackColor) # set background colour
# Add a "Title box"
self.vTitle = Tkinter.Label(self,text='Crazy Coder')
self.vTitle.configure(background=self.vBackColor)
self.vTitle.pack(side=TOP,padx=10,pady=10)
# Add a picture box (gif supported)
self.vImage = PhotoImage(file="PUG.gif")
self.vPicture=Label(self,image=self.vImage)
self.vPicture.image=self.vImage
self.vPicture.pack()
# Add the main text box
self.vMessageText = '''
This is where your day number goes
Scores go here too
Event details go here too'''
self.vMessage = Tkinter.Label(self,text=self.vMessageText)
self.vMessage.configure(background=self.vBackColor)
self.vMessage.pack(side=TOP,padx=10,pady=10)
# While loop does not work - there is no concept of
# "display current buttons / screen and wait for click event"
#while self.vDayNumber <= self.vFinalDay:
self.vChoice = '' # Clear it ready to take a user choice each day
print('DEBUG: On Main screen, starting now')
self.vRandom = randint(1,100)
if self.vDayNumber == 1:
self.fWelcomeScreen() # Set up the welcome screen
elif self.vRandom >= 0:
self.fEvent1() # Kick off event 1
############################# FUNCTION #################################
# Sets the message on the main text box to whatever you put in brackets
def fSetText(self,TextMessage):
global vMessageText
self.vMessageText = TextMessage
self.vMessage['text'] = self.vMessageText # This updates the text box
############################# FUNCTION #################################
# Sets the image on the main picture box to whatever you put in brackets
def fSetImage(self,ImageName):
global vImage
self.vImage = PhotoImage(file=ImageName) # Example "PUG2.gif"
self.vPicture['image']=self.vImage # This updates the image box
############################# FUNCTION #################################
# Add a new Entry box to our screen. Supports multiple uses
def fAddEntryBox(self):
self.vNewBox = Entry(width=20)
self.vEntryBox.append(self.vNewBox)
self.vNewBox.pack(side=TOP,padx=10,pady=10)
self.vNewBox.focus()
############################# FUNCTION #################################
# Remove the Entry Boxes
def fDeleteEntryBoxes(self):
for each_box in self.vEntryBox:
each_box.destroy()
############################# FUNCTION #################################
# Read from the requested box number, cutting off the Enter at the end
def fReadEntryBox(self,BoxNumber): #BoxNumber 0 is the first box, 1 next
global vTextEntry
vTextEntry=self.vEntryBox[BoxNumber].get()
############################# FUNCTION #################################
# Handles the the day passing by
def fEndDay(self):
global vPlayerName, vDayNumber
self.vDayNumber = self.vDayNumber + 1
print("This print isn't running either!")
############################# FUNCTION #################################
# A simple step to take a choice from the user - used for button code below
def fMakeChoice(self,value):
global vChoice, vDayNumber
self.fEndDay()
self.vChoice = value
print('Just Clicked:',self.vChoice, "and it's day ", self.vDayNumber)
print('But fEndDay should have just run and increased it to 2!')
############################# FUNCTION #################################
# Add buttons to the screen, based on vAvailableButtons
def fAddButtons(self):
global vAvailableButtons # Shouldn't need this here but...
for each_button in self.vAvailableButtons:
# Important: the Lambda section takes the CURRENT value of the variable
# and stores is in the command string. Without it, all the buttons
# when clicked would do the same as the last button created! daft eh.
vNewButton = Tkinter.Button(self, text=each_button, command=lambda v=each_button: self.fMakeChoice(v))
self.vDynamic_Buttons.append(vNewButton)
vNewButton.pack(side= BOTTOM, padx = 10, pady = 10)
############################# FUNCTION #################################
# Clear the buttons out ie before drawing new ones
def fDeleteButtons(self):
for each_button in self.vDynamic_Buttons:
each_button.destroy()
############################# FUNCTION #################################
# Pop up message box
def fMessage(self,Message):
self.tkMessageBox.showinfo("News", Message)
#*********************************************************************#
#********************* EVENTS SECTION ***************************#
#*********************************************************************#
# We'll define a function here for each "daily event"
# The section will be responsible for:
# 1) Updating the screen image (if necessary)
# 2) Updating the text box content
# 3) Adding entry boxes and buttons as required
# 4) Ending the day (there will be one decision per day for now)
############################# EVENT #################################
# The welcome screen
def fWelcomeScreen(self):
global vAvailableButtons
self.vTextMessage = '''
Yawn. You wake up.
Whats your name?
'''
self.fSetText(self.vTextMessage)
time.sleep(1) # delays for 1 second
self.fAddEntryBox() # Add an entry box for a name
self.vAvailableButtons = ['Ok']
self.fAddButtons() # vChoice set on click, and day ended
############################# EVENT #################################
# A random event
def fEvent1(self):
global vAvailableButtons
self.vTextMessage = '''
This is an event. What will you do?
'''
self.fSetText(self.vTextMessage)
time.sleep(1) # delays for 1 second
self.vAvailableButtons = ['Ok']
self.fAddButtons() # vChoice set on click, and day ended
# Start the program
if __name__ == "__main__":
app = CrazyCoder(None)
app.mainloop()
1楼
您希望每天运行一次函数这一事实与希望动画每秒运行 30 帧没有什么不同。 您实际上想要一个运行 1 fpd(每天一帧)的“动画”。
实现这一点的方法是创建一个每天运行一次的函数。
def do_once_a_day():
...
接下来,创建一个每天调用一次该函数的函数:
def call_daily(self):
self.do_once_a_day()
if self.vDayNumber <= self.vFinalDay:
root.after(1000*60*60*24, self.call_daily)
这将导致每 24 小时调用一次do_once_a_day
。
然后,您可以在该函数中做任何您想做的事情。