从其他Tkinter程序调用时未显示标签

时间:2017-11-23 20:31:49

标签: python tkinter

我正在编写一个带有起始页面的程序,以及从该起始页面调用的两个程序。这两个子程序都是自己工作的。但是,当我将它们放入我的起始页时,秒表计时标签不会显示。如果你想知道,我把它们放进我的程序中:

import program
program.function()

这是我的首页程序:

from Tkinter import *
class start_page:
    def __init__(self,master):
        self.master = master
        self.frame = Frame(self.master)
        self.countdown = Button(master, text = "Timer", command = self.c).pack()
        self.stopwatch_butt = Button(master,text="Stopwatch",command=self.g).pack()
    def g(self):
        import stopwatch
        stopwatch.f()
    def c(self):
        import timer_prog
        timer_prog.timer()
        self.master.after_cancel(timer_prog)
def main():
    root = Tk()
    s = start_page(root)
    root.title("Timer Suite: Brian Ton")
    root.mainloop()
main()

如果我运行此程序,计时器程序工作正常,但秒表不会显示其标签,只显示其按钮。我试图在功能之后清除所有Tk,但这不起作用,我也尝试先运行秒表程序,但无济于事。

这是我的秒表计划:

from Tkinter import *
import datetime

def s():
    start.config(state='disabled')
    stop.config(state="normal")
    reset.config(state='disabled')
    Start()
def Start():
    if reset['state'] == 'disabled' and stop['state'] == 'normal':
        hidden.set(str(int(hidden.get())+1))
        root.update()
        root.after(1000,Start)
        curr = hidden.get()
        g.set(str(datetime.timedelta(seconds=int(curr))))
        print g.get()
    else:
        return None
def Stop():
    start.config(state='disabled')
    stop.config(state='disabled')
    reset.config(state="normal")
def Reset():
    start.config(state="normal")
    stop.config(state="disabled")
    reset.config(state='disabled')
    hidden.set('0')
    g.set(str(datetime.timedelta(seconds=0)))
def f():
    global root,frame,master,hidden,g,timelabel,start,stop,reset
    root = Tk()
    frame = Frame(root)
    master = root
    hidden = StringVar()
    g = StringVar()
    hidden.set('0')
    timelabel = Label(master,textvariable=g)
    g.set(str(datetime.timedelta(seconds=int(0))))
    timelabel.grid(row=1,column=2)
    start = Button(master,text="Start",command = s,state="normal")
    stop = Button(master,text="Stop",command = Stop,state = "disabled")
    reset = Button(master,text="Reset",command = Reset,state = "disabled")
    start.grid(row=2,column=1)
    stop.grid(row=2,column=2)
    reset.grid(row=2,column=3)
    root.update()
    root.mainloop()


这是我的计时器程序:

from Tkinter import *
import datetime

def get_seconds(h,m,s):
    hr_sec = h * 3600
    m_sec = m * 60
    return hr_sec+m_sec+s
def timerstartstop():
    hours = hour_entry.get()
    minutes = minute_entry.get()
    sec = second_entry.get()
    if hours == "":
        hours = 0
        hour_entry.insert(0,"0")
    if minutes == "":
        minutes = 0
        minute_entry.insert(0,"0")
    if sec == "":
        sec = 0
        second_entry.insert(0,"0")
    c = get_seconds(int(hours), int(minutes), int(sec))
    global s
    s = StringVar(master)
    s.set(c)
    if startstop['text'] == 'Stop':
        global curr
        curr = shown
        s.set(-1)
    if startstop['text'] == 'Reset':
        startstop.config(text="Start")
        s.set(c)
        root.update()
        shown.set(str(datetime.timedelta(seconds=int(s.get()))))
        return None
    countdown()
import winsound
def countdown():
    startstop.config(text="Stop")
    global shown
    good = True
    shown = StringVar(master)
    shown.set(str(datetime.timedelta(seconds=int(s.get()))))
    L = Label(master,textvariable=shown).grid(row=1,column=2)
    if int(s.get()) == 0:
        startstop.config(text="Reset")
        while startstop['text'] != "Start":
            root.update()
            winsound.Beep(500,500)
    elif int(s.get()) < 0:
        good = False
        shown.set(curr.get())
        startstop.config(text="Reset")
    else:
        if good:
            s.set(str(int(s.get())-1))
            root.after(1000,countdown)
def ex():
    root.after_cancel(countdown)
    root.destroy()
def timer():
    global root
    global master
    global frame
    root = Tk()
    master = root
    frame = Frame(master)
    global hour_entry
    hour_entry = Entry(master,width=3)
    hour_entry.grid(row=0,column=0)
    colon_l = Label(master,text=':').grid(row=0,column=1)
    global minute_entry
    minute_entry = Entry(master,width=2)
    minute_entry.grid(row=0,column=2)
    colon_l2 = Label(master,text=':').grid(row=0,column=3)
    global second_entry
    second_entry = Entry(master,width=2)
    second_entry.grid(row=0,column=4)
    global startstop
    startstop = Button(master,text="Start",command=timerstartstop)
    e = Button(master,text="Exit",command=ex).grid(row=1,column=3)
    startstop.grid(row=0,column=5)
    root.mainloop()

此外,我尝试从使用控制台的不同开始菜单运行这两个程序,这是有效的。
控制台程序是:

import timer_prog
timer_prog.timer()
raw_input('next')
import stopwatch
stopwatch.f()

附上一些截图,显示秒表程序应该与起始程序调用时的外观相比。


注意:我可以告诉程序从起始页面运行,因为它每秒打印当前时间。另外,我附上了一些截图

Stopwatch Program Run Directly
Stopwatch Program Run From The Start Page

1 个答案:

答案 0 :(得分:1)

Tkinter程序应该只使用一个Tk() - 创建主窗口 - 和一个mainloop() - 来控制所有窗口和窗口小部件。如果您使用两个Tk()和两个mainloop(),那么它就会出现问题 - 例如get()/set()可能无效。

子窗口应使用Toplevel()而不是Tk()

启动程序的函数(即run())可以使用参数windowdef run(window))运行,然后您可以将其作为独立程序执行

root = Tk()
run(root)
root.mainloop()

或导入后

run(Toplevel())

(不含maniloop()

您可以使用if __name__ == "__main__"来识别程序是否以独立方式启动。

实施例

<强> main.py

from Tkinter import *

class StartPage:

    def __init__(self, master):
        self.master = master
        master.title("Timer Suite: Brian Ton")
        Button(master, text="Timer", command=self.run_timer).pack()
        Button(master, text="Stopwatch", command=self.run_stopwatch).pack()

    def run_stopwatch(self):
        import stopwatch
        window = Toplevel()
        stopwatch.run(window)

    def run_timer(self):
        import timer_prog
        window = Toplevel()
        timer_prog.timer(window)
        self.master.after_cancel(timer_prog)

def main():
    root = Tk()
    StartPage(root)
    root.mainloop()

main()

<强> stopwatch.py​​

from Tkinter import *
import datetime

def pre_start():
    start_button.config(state='disabled')
    stop_button.config(state='normal')
    reset_button.config(state='disabled')
    start()

def start():
    global current_time

    # stop_button['state'] can be 'normal' or 'active' so better use ` != 'disabled'`
    if reset_button['state'] == 'disabled' and stop_button['state'] != 'disabled':
        current_time += 1
        time_var.set(str(datetime.timedelta(seconds=current_time)))
        print(time_var.get())
        master.after(1000, start)

def stop():
    start_button.config(state='disabled')
    stop_button.config(state='disabled')
    reset_button.config(state='normal')

def reset():
    global current_time

    start_button.config(state='normal')
    stop_button.config(state='disabled')
    reset_button.config(state='disabled')
    current_time = 0
    time_var.set(str(datetime.timedelta(seconds=0)))

def run(window):
    global master
    global current_time, time_var
    global start_button, stop_button, reset_button

    master = window
    current_time = 0

    time_var = StringVar()
    time_var.set(str(datetime.timedelta(seconds=0)))

    time_label = Label(window, textvariable=time_var)
    time_label.grid(row=1, column=2)

    start_button = Button(master, text='Start', command=pre_start, state='normal')
    stop_button  = Button(master, text='Stop',  command=stop,      state='disabled')
    reset_button = Button(master, text='Reset', command=reset,     state='disabled')
    start_button.grid(row=2, column=1)
    stop_button.grid(row=2, column=2)
    reset_button.grid(row=2, column=3)

if __name__ == '__main__':
    # it runs only in standalone program
    root = Tk()    
    run(root)
    root.mainloop()