私は6秒間画像を表示してラジオボタンを使って別のページにジャンプし、画像について自分の気持ちを評価できるようにしようとしています。次の画像を表示する。しかし、15秒をカウントダウンするには、time.sleep()関数を使用しました。これは、ラジオボタンを押してもプログラムを非常に遅くします(しかし、クリックすると、ボタンはまだ押されます)。カウントダウンがプログラムに影響を与えないようにする方法があるのかどうかは疑問だが、時間切れになると次のページにジャンプする。ここに私のコードは次のとおりです。それは実行したイベントに応答できるからmainloop()
を保つため、tkinter
プログラムでtime.sleep()
を使用してtime.sleep blocks tkinter.Buttonを押す
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.geometry('1800x970+15+5')
self.title('Emotion Test')
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
container = tk.Frame(self)
container.pack(side="top", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, Show_image, Rate_e, EndPage):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
frame.execute()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text=instructions, width=1500, height=700, font=TITLE_FONT)
label.pack(side="top")
label.place(x=100, y=40, width=1500, height=700)
button1 = tk.Button(self, text="Start", height = 5, width = 10,
command=lambda: controller.show_frame("Show_image"))
button1.pack(side="bottom")
def execute(self):
current = -1
class EndPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text=instructions, width=1500, height=700,
font=TITLE_FONT)
label.pack(side="top")
label.place(x=100, y=40, width=1500, height=700)
def execute(self):
current = -1
class Show_image(tk.Frame):
def __init__(self, parent, controller):
global seconds
tk.Frame.__init__(self, parent)
self.controller = controller
global lbPic
global timer1
lbPic = tk.Label(self, text='Image System', width=1200, height=900)
lbPic.place(x=20, y=50, width=1200, height=900)
lbPic.pack(side="top", fill="both", expand=True)
timer1 = tk.Label(self, text='timer', width=50, height=10)
timer1.place(x=1325, y=2, width=50, height=10)
timer1.pack(side="bottom", fill="both", expand=True)
def execute(self):
if (self.changePic(1)):
for k in range(seconds, 0, -1):
timer1["text"] = "Time left : " + str(k) + " s"
self.update()
time.sleep(1)
self.controller.show_frame("Rate_e")
else:
self.controller.show_frame("EndPage")
def changePic(self, flag):
global current
new = current + flag
if new<0:
#tkMessageBox.showerror('', 'last picture')
return 0
elif new>=len(pics):
#tkMessageBox.showerror('', 'last picture')
return 0
else:
#get the next picture
pic = pics[new]
im = Image.open(pic)
w, h = im.size
if w>1200:
h = int(h*1200/w)
w = 1200
if h>800:
w = int(w*800/h)
h = 800
im = im.resize((w,h))
im1 = ImageTk.PhotoImage(im)
lbPic['image'] = im1
lbPic.image = im1
current = new
return 1
class Rate_e(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
global wait
self.controller = controller
global lbrate1
global lbrate2
global lbrate3
global timer2
lbrate1 = tk.Label(self, text='Pleasure', width=1400, height=260)
lbrate1.place(x=50, y=10, width=1400, height=260)
lbrate1.pack(side="top", fill="both", expand=True)
lbrate2 = tk.Label(self, text='Excited', width=1400, height=260)
lbrate2.place(x=50, y=230, width=1400, height=260)
lbrate2.pack(side="top", fill="both", expand=True)
lbrate3 = tk.Label(self, text='Controlled', width=1400, height=260)
lbrate3.place(x=50, y=650, width=1400, height=260)
lbrate3.pack(side="top", fill="both", expand=True)
timer2 = tk.Label(self, text='timer', width=50, height=10)
timer2.place(x=800, y=850, width=50, height=10)
timer2.pack(side="bottom", fill="both", expand=True)
MODES = [
("1", 1),
("2", 2),
("3", 3),
("4", 4),
("5", 5),
("6", 6),
("7", 7),
("8", 8),
("9", 9)
]
global v1
v1 = tk.StringVar()
v1.set("score1") # initialize
xaxis = 0
for text, mode in MODES:
b1 = tk.Radiobutton(self, text=text,
variable=v1, value=mode)
b1.config(indicatoron=False,width=10,height=2)
b1.place(x=140 + xaxis*127, y=240 , width=100, height=30)
#b.pack(side="left")
xaxis = xaxis + 1
global v2
v2 = tk.StringVar()
v2.set("score2") # initialize
xaxis = 0
for text, mode in MODES:
b2 = tk.Radiobutton(self, text=text,
variable=v2, value=mode)
b2.config(indicatoron=False,width=10,height=2)
b2.place(x=140 + xaxis*128, y=510 , width=100, height=30)
#b.pack(side="left")
xaxis = xaxis + 1
global v3
v3 = tk.StringVar()
v3.set("score3") # initialize
xaxis = 0
for text, mode in MODES:
b3 = tk.Radiobutton(self, text=text,
variable=v3, value=mode)
b3.config(indicatoron=False,width=10,height=2)
b3.place(x=140 + xaxis*125, y=800 , width=100, height=30)
#b.pack(side="left")
xaxis = xaxis + 1
def execute(self):
for k in range(wait, 0, -1):
timer2["text"] = "Time left : " + str(k) + " s"
self.update()
time.sleep(1)
Pleasure = v1.get()
Excited = v2.get()
Control = v3.get()
print(Pleasure)
print(Excited)
print(Control)
self.controller.show_frame("Show_image")
if __name__ == "__main__":
suffix = ('.jpg', '.bmp', '.png')
pics = [image_path + p for p in os.listdir(image_path) if p.endswith(suffix)]
seconds = 2
wait = 6
current = -1
app = SampleApp()
app.mainloop()
tkinterでtime.sleepを使用しないでください。プログラムが応答しなくなるだけです。 – abccd
マルチスレッドを使用する必要がありますか?どんな詳細も配慮されています。 –