我弟弟刚刚进入程序,并为他的科学博览会项目,他做的鸟在天空中一群的模拟。他得到了他的大部分代码编写的,它工作得很好,但鸟儿需要移动的每一刻的。

Tkinter的,但是,猪为自己的事件循环的时间,所以他的代码将无法运行。这样做root.mainloop()运行,运行,并保持运行,并且它运行的唯一事情是事件处理程序。

有没有已经同时运行主循环一行代码的方式(不包括多线程,它的混乱,这应该是保持简单),如果有,是什么呢?

现在,他想出了一个丑陋的黑客攻击,绑他的move()功能<b1-motion>,所以只要他持有的按钮并晃鼠标,它的工作原理。但是,我们有了一个更好的办法。

有帮助吗?

解决方案

使用after方法Tk对象上:

from tkinter import *

root = Tk()

def task():
    print("hello")
    root.after(2000, task)  # reschedule event in 2 seconds

root.after(2000, task)
root.mainloop()

以下是适用于after方法的声明和文件:

def after(self, ms, func=None, *args):
    """Call function once after given time.

    MS specifies the time in milliseconds. FUNC gives the
    function which shall be called. Additional parameters
    are given as parameters to the function call.  Return
    identifier to cancel scheduling with after_cancel."""

其他提示

张贴由比约结果的溶液在一个“RuntimeError:从不同的公寓的Tcl调用”消息我的计算机上(RedHat的企业5家,蟒蛇2.6.1)。比约恩可能不会得到这个消息,因为根据一个地方,我检查时,与Tkinter的误操作线程是不可预测的,依赖于平台的。

这个问题似乎是app.start()计数为Tk的一个参考,由于应用包含Tk的元件。我由一个内含app.start()一个self.start()更换__init__固定这一点。我还使使所有的Tk的引用或者是内部的函数调用mainloop() 或在里面的由调用的函数调用mainloop()功能(这是显然的关键避免 “不同的公寓” 错误)。

最后,我添加了一个协议处理程序与一个回调,由于没有这个程序退出一个错误时,Tk的窗口被用户关闭。

修改后的代码如下所示:

# Run tkinter code in another thread

import tkinter as tk
import threading

class App(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.start()

    def callback(self):
        self.root.quit()

    def run(self):
        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.callback)

        label = tk.Label(self.root, text="Hello World")
        label.pack()

        self.root.mainloop()


app = App()
print('Now we can continue running code while mainloop runs!')

for i in range(100000):
    print(i)

当自己写循环,如模拟(我认为),你需要调用update功能它执行mainloop做什么:你的改动更新窗口,但你在你的循环做

def task():
   # do something
   root.update()

while 1:
   task()  

另一种选择是让Tkinter的执行上一个单独的线程。这样做的一种方法是这样的:

import Tkinter
import threading

class MyTkApp(threading.Thread):
    def __init__(self):
        self.root=Tkinter.Tk()
        self.s = Tkinter.StringVar()
        self.s.set('Foo')
        l = Tkinter.Label(self.root,textvariable=self.s)
        l.pack()
        threading.Thread.__init__(self)

    def run(self):
        self.root.mainloop()


app = MyTkApp()
app.start()

# Now the app should be running and the value shown on the label
# can be changed by changing the member variable s.
# Like this:
# app.s.set('Bar')

不过要小心,多线程编程很难,它是很容易拍摄你自己的脚。例如,你有当你改变上述这样就不会与Tkinter的的事件循环中断样品类的成员变量要小心。

这是将是一个什么GPS读取器和数据演示第一工作版本。 Tkinter的是路太少的错误消息非常脆弱的东西。它不把东西了,不知道为什么很多的时间。从良好的所见即所得的表单开发人员很难到来。无论如何,这将运行一个小程序每秒10次,并提出了一个表格上的信息。花了一段时间来做到这一点。当我试图0定时器的值,形式一直没上。我现在头很痛!每秒10次或更多次对我不够好。我希望它可以帮助别人。麦克莫罗

import tkinter as tk
import time

def GetDateTime():
  # Get current date and time in ISO8601
  # https://en.wikipedia.org/wiki/ISO_8601 
  # https://xkcd.com/1179/
  return (time.strftime("%Y%m%d", time.gmtime()),
          time.strftime("%H%M%S", time.gmtime()),
          time.strftime("%Y%m%d", time.localtime()),
          time.strftime("%H%M%S", time.localtime()))

class Application(tk.Frame):

  def __init__(self, master):

    fontsize = 12
    textwidth = 9

    tk.Frame.__init__(self, master)
    self.pack()

    tk.Label(self, font=('Helvetica', fontsize), bg = '#be004e', fg = 'white', width = textwidth,
             text='Local Time').grid(row=0, column=0)
    self.LocalDate = tk.StringVar()
    self.LocalDate.set('waiting...')
    tk.Label(self, font=('Helvetica', fontsize), bg = '#be004e', fg = 'white', width = textwidth,
             textvariable=self.LocalDate).grid(row=0, column=1)

    tk.Label(self, font=('Helvetica', fontsize), bg = '#be004e', fg = 'white', width = textwidth,
             text='Local Date').grid(row=1, column=0)
    self.LocalTime = tk.StringVar()
    self.LocalTime.set('waiting...')
    tk.Label(self, font=('Helvetica', fontsize), bg = '#be004e', fg = 'white', width = textwidth,
             textvariable=self.LocalTime).grid(row=1, column=1)

    tk.Label(self, font=('Helvetica', fontsize), bg = '#40CCC0', fg = 'white', width = textwidth,
             text='GMT Time').grid(row=2, column=0)
    self.nowGdate = tk.StringVar()
    self.nowGdate.set('waiting...')
    tk.Label(self, font=('Helvetica', fontsize), bg = '#40CCC0', fg = 'white', width = textwidth,
             textvariable=self.nowGdate).grid(row=2, column=1)

    tk.Label(self, font=('Helvetica', fontsize), bg = '#40CCC0', fg = 'white', width = textwidth,
             text='GMT Date').grid(row=3, column=0)
    self.nowGtime = tk.StringVar()
    self.nowGtime.set('waiting...')
    tk.Label(self, font=('Helvetica', fontsize), bg = '#40CCC0', fg = 'white', width = textwidth,
             textvariable=self.nowGtime).grid(row=3, column=1)

    tk.Button(self, text='Exit', width = 10, bg = '#FF8080', command=root.destroy).grid(row=4, columnspan=2)

    self.gettime()
  pass

  def gettime(self):
    gdt, gtm, ldt, ltm = GetDateTime()
    gdt = gdt[0:4] + '/' + gdt[4:6] + '/' + gdt[6:8]
    gtm = gtm[0:2] + ':' + gtm[2:4] + ':' + gtm[4:6] + ' Z'  
    ldt = ldt[0:4] + '/' + ldt[4:6] + '/' + ldt[6:8]
    ltm = ltm[0:2] + ':' + ltm[2:4] + ':' + ltm[4:6]  
    self.nowGtime.set(gdt)
    self.nowGdate.set(gtm)
    self.LocalTime.set(ldt)
    self.LocalDate.set(ltm)

    self.after(100, self.gettime)
   #print (ltm)  # Prove it is running this and the external code, too.
  pass

root = tk.Tk()
root.wm_title('Temp Converter')
app = Application(master=root)

w = 200 # width for the Tk root
h = 125 # height for the Tk root

# get display screen width and height
ws = root.winfo_screenwidth()  # width of the screen
hs = root.winfo_screenheight() # height of the screen

# calculate x and y coordinates for positioning the Tk root window

#centered
#x = (ws/2) - (w/2)
#y = (hs/2) - (h/2)

#right bottom corner (misfires in Win10 putting it too low. OK in Ubuntu)
x = ws - w
y = hs - h - 35  # -35 fixes it, more or less, for Win10

#set the dimensions of the screen and where it is placed
root.geometry('%dx%d+%d+%d' % (w, h, x, y))

root.mainloop()
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top