直到现在,我曾经用以下结束我的Tkiter程序:tk.mainloop()
或者什么都不会出现!见例子:
from Tkinter import *
import random
import time
tk = Tk()
tk.title = "Game"
tk.resizable(0,0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
class Ball:
def __init__(self, canvas, color):
self.canvas = canvas
self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
self.canvas.move(self.id, 245, 100)
def draw(self):
pass
ball = Ball(canvas, "red")
tk.mainloop()
Run Code Online (Sandbox Code Playgroud)
然而,当尝试下这个程序的下一步(让球随时间移动)时,本书正在阅读,说要做到以下几点.将绘图功能更改为:
def draw(self):
self.canvas.move(self.id, 0, -1)
Run Code Online (Sandbox Code Playgroud)
并将以下代码添加到我的程序:
while 1:
ball.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
Run Code Online (Sandbox Code Playgroud)
但我注意到添加这段代码,使用tk.mainloop()
无用,因为即使没有它,一切都会出现!
在这一刻,我应该提到我的书从未谈到tk.mainloop()
(也许是因为它使用Python 3)但我学会了它在网上搜索,因为我的程序不能通过复制书的代码工作!
所以我尝试做以下不起作用!
while 1:
ball.draw()
tk.mainloop() …
Run Code Online (Sandbox Code Playgroud) 你如何event
从一个单独的对象调用tkinter ?
我正在寻找像wxWidgets这样的东西wx.CallAfter
.例如,如果我创建一个对象,并将其传递给我的Tk
根实例,然后尝试从我的对象调用该根窗口的方法,我的应用程序将锁定.
我能想到的最好的after
方法是使用方法并从我的单独对象中检查状态,但这似乎很浪费.
我试图在等待5秒后删除文本框内的文本,但是程序不会运行并且会在其他所有内容上休眠.还有一种方法让我只是让我的文本框睡眠,所以我可以在文本被冻结时运行其他代码吗?
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.insert(END, 'This is a test')
sleep(5)
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
empty_textbox()
root.mainloop()
Run Code Online (Sandbox Code Playgroud) 我有一个可变长度列表,并希望为列表中的每个条目创建一个复选框(使用python TKinter)(每个条目对应一个应该使用复选框打开或关闭的机器 - >更改字典中的值) .
print enable
{'ID1050': 0, 'ID1106': 0, 'ID1104': 0, 'ID1102': 0}
Run Code Online (Sandbox Code Playgroud)
(例如,可以是任何长度)
现在相关代码:
for machine in enable:
l = Checkbutton(self.root, text=machine, variable=enable[machine])
l.pack()
self.root.mainloop()
Run Code Online (Sandbox Code Playgroud)
此代码生成4个复选框,但它们全部勾选或未勾选,并且enable
dict中的值不会更改.怎么解决?(我认为这l
不起作用,但如何使这个变量?)
我是一个试图学习编程的老人.我试过寻找这个问题的答案,但大多数回复都是我的头脑.所以这里,我编写了代码来从Web获取数据,将其转换为json,并以所需的格式打印结果.我现在正在使用Tkinter来显示这些数据.我已成功显示数据并更新标签,但我无法获取更新的URL(为标签提供输入).那么如何在预定的时间间隔内(每3小时一次)更新或运行request.get而不使用可以阻止其余程序的循环?
这是我到目前为止所做的(要运行此程序,您需要从openweather.com输入您的api)....
import requests
import time
from tkinter import *
# Input Values
api = 'Enter API Key from Openweather.com'
lat = '33.608'
lon = '-111.863'
unit = 'imperial' # unit must be 'imperial' or 'metric'
fcast_time = [0, 4, 8, 12, 16, 20, 24, 28] # each element is a 3 hour period (i.e. 4 would be 12 hours out), max is 40
main_window = Tk()
url2 = 'http://api.openweathermap.org/data/2.5/forecast?'+'lat='+str(lat)+'&lon='+str(lon)+'&APPID='+str(api)+'&units='+str(unit)
def fconvertTime(tperiod):
period = fcast_data['list'][fcast_time[tperiod]]['dt']
ftime = time.strftime("%a %p", time.localtime(period)) …
Run Code Online (Sandbox Code Playgroud) 我想从 Tkinter 按钮命令调用异步函数,或者想让该函数异步运行,以便 tkinter 窗口响应。
我已经command = open_async
在 Button 中尝试过,其open_async
声明如下async def open_async():
,但它给了我一个错误“RuntimeWarning:coroutine 'open_async'从未等待 self.tk.mainloop(n)”。
如果我只是使用def async():
,代码仍然会同步运行,因此 UI 将没有响应。(async()
内部也包含一些其他异步操作,使用asyncio
等)。
有人知道如何解决这个问题吗?我也不想创建线程。谢谢
我编写了一个可以传递图像的简短模块,只需创建一个Tkinter窗口并显示它.我遇到的问题是,即使我实例化并调用在单独的线程中显示图像的方法,主程序也不会继续,直到Tkinter窗口关闭.
这是我的模块:
import Image, ImageTk
import Tkinter
class Viewer(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
def show(self,img):
self.to_display = ImageTk.PhotoImage(img)
self.label_image = Tkinter.Label(self,image=self.to_display)
self.label_image.grid(column = 0, row = 0, sticky = "NSEW")
self.mainloop()
Run Code Online (Sandbox Code Playgroud)
它似乎工作正常,除非我从我的测试程序中调用它,如下所示,它似乎不允许我的测试程序继续,即使在另一个线程中启动.
import Image
from viewer import Viewer
import threading
def showimage(im):
view = Viewer(None)
view.show(im)
if __name__ == "__main__":
im = Image.open("gaben.jpg")
t = threading.Thread(showimage(im))
t.start()
print "Program keeps going..."
Run Code Online (Sandbox Code Playgroud)
我想也许我的问题是我应该在模块本身内创建一个新线程,但我只想尝试保持简单,因为我是Python的新手.
无论如何,提前感谢任何帮助.
编辑:为了清楚起见,我只是想制作一个在Tkinter窗口中显示图像的模块,以便我可以在任何时候想要显示图像时使用该模块.我遇到的问题是,只要程序使用此模块,它就无法恢复,直到Tkinter窗口关闭.
Ctrl-C/SIGTERM/SIGINT 似乎被 tkinter 忽略。通常可以通过回调再次捕获它。这似乎不起作用,所以我想我应该在另一个线程中运行 tkinter ,因为它的mainloop() 是一个无限循环和 block。实际上我也想这样做以在单独的线程中从标准输入读取。即使在此之后,Ctrl-C 仍然不会被处理,直到我关闭窗口。这是我的 MWE:
#! /usr/bin/env python
import Tkinter as tk
import threading
import signal
import sys
class MyTkApp(threading.Thread):
def run(self):
self.root = tk.Tk()
self.root.mainloop()
app = MyTkApp()
app.start()
def signal_handler(signal, frame):
sys.stderr.write("Exiting...\n")
# think only one of these is needed, not sure
app.root.destroy()
app.root.quit()
signal.signal(signal.SIGINT, signal_handler)
Run Code Online (Sandbox Code Playgroud)
结果:
这是怎么回事?如何让终端中的 Ctrl-C 关闭应用程序?
更新:按照建议添加 poll,在主线程中工作,但在另一个线程中启动时没有帮助......
class MyTkApp(threading.Thread):
def poll(self):
sys.stderr.write("poll\n")
self.root.after(50, self.poll) …
Run Code Online (Sandbox Code Playgroud) 我之所以发布此消息,是因为我自己一直在努力寻找有关此问题的明确答案。。。
为了尝试为我的程序创建进度条,我发现使用tkinter很难做到。为了完成创建进度条而没有遇到可怕的“ mainloop”,我选择使用threads从进度条中制作一个类。经过大量的试验,发现一个错误,由于使用多线程(tkinter喜欢在主线程中),因此无法自定义很多内容。这是我尝试过的两个选项,其次是最适合我的需求的第三个选项:
给出以下代码:
import tkinter as tk
import tkinter.ttk as ttk
import threading
class ProgressbarApp(threading.Thread):
def __init__(self, max_value: int):
self.max_value = max_value
self.root = None
self.pb = None
threading.Thread.__init__(self)
self.lock = threading.Lock() # (1)
self.lock.acquire() # (2)
self.start()
# (1) Makes sure progressbar is fully loaded before executing anything
with self.lock:
return
def close(self):
self.root.quit()
def run(self):
self.root = tk.Tk()
self.root.protocol("WM_DELETE_WINDOW", self.__callback)
self.pb = ttk.Progressbar(self.root, orient='horizontal', length=400, mode='determinate')
self.pb['value'] = 0
self.pb['maximum'] = self.max_value
self.pb.pack()
self.lock.release() …
Run Code Online (Sandbox Code Playgroud) 我正在 python 中使用 tkinter 制作一个计时器。该小部件只有一个按钮。该按钮兼作显示剩余时间的元素。计时器有一个线程,可以简单地更新按钮上显示的时间。
该线程仅使用一个 while 循环,该循环应在设置事件时停止。当窗口关闭时,我使用协议调用设置此事件的函数,然后尝试加入线程。这在大多数情况下都有效。但是,如果我在进行某个调用时关闭程序,则会失败并且线程在窗口关闭后继续运行。
我知道有关关闭 tkinter 窗口时关闭线程的其他 类似线程。但这些答案已经过时了,如果可能的话,我想避免使用 thread.stop() 。
我尝试尽可能减少这一点,同时仍然表明我对该计划的意图。
import tkinter as tk
from tkinter import TclError, ttk
from datetime import timedelta
import time
import threading
from threading import Event
def strfdelta(tdelta):
# Includes microseconds
hours, rem = divmod(tdelta.seconds, 3600)
minutes, seconds = divmod(rem, 60)
return str(hours).rjust(2, '0') + ":" + str(minutes).rjust(2, '0') + \
":" + str(seconds).rjust(2, '0') + ":" + str(tdelta.microseconds).rjust(6, '0')[0:2]
class App(tk.Tk): …
Run Code Online (Sandbox Code Playgroud) 我开发了一个简单的Python应用程序,然后我决定使用Tkinter添加一个简单的GUI.
问题是,虽然主要功能正在做它的东西,窗口冻结.
我知道这是一个常见问题,我已经读过我应该使用多线程(非常复杂,因为函数也更新了GUI)或者将我的代码分成不同的函数,每个函数都工作了一段时间.无论如何,我不想为这样一个愚蠢的应用程序更改我的代码.
我的问题是:是否有可能没有简单的方法来每秒更新我的Tkinter窗口?我只想申请KISS规则!
我会在下面给你一个伪代码示例,但我没试过但是没有用:
class Gui:
[...]#costructor and other stuff
def refresh(self):
self.root.update()
self.root.after(1000,self.refresh)
def start(self):
self.refresh()
doingALotOfStuff()
#outside
GUI = Gui(Tk())
GUI.mainloop()
Run Code Online (Sandbox Code Playgroud)
它只会执行一次刷新,我无法理解为什么.
非常感谢你的帮助.
我是一名高中编程学生,我有一个小问题.我的任务是在Tkinter写一个简单的游戏,冰柱从天花板上掉下来,你必须用鼠标来避免它.很简单.但是,我遇到了一个问题.每当我在Tkinter应用程序中运行循环时,它都不会打开.我尝试使用for循环,使用time.sleep()每隔0.5秒暂停一次,循环结束后窗口就会打开.我需要做一些特殊的事情才能使循环在Tkinter中运行吗?
from Tkinter import *
import time
import random
class App:
def __init__(self, parent):
self.frame = Frame(root, bg= '#1987DF', width=800, height=800)
self.frame.bind("<Motion>", self.motionevent)
self.frame.pack()
#self.run()
def randhex(self):
b = "#"
for i in range(1, 7):
a = random.randint(0, 15)
if a == 10:
a = "A"
elif a == 11:
a = "B"
elif a == 12:
a = "C"
elif a == 13:
a = "D"
elif a == 14:
a = "E"
elif a == 15:
a = …
Run Code Online (Sandbox Code Playgroud) 基本上我需要同时运行两个 while 循环。原因是我需要一个循环来更新 GUI,另一个循环来检查程序是否连接到互联网。所以也许这需要多线程,或者也许我只需要一个网页就可以解决我的问题。这是我的源代码:
# -*- coding: utf-8 -*-
import sys
import urllib2
from Tkinter import *
import time
import socket
def TheMainProgram():
airid = 'http://www.aviationweather.gov/metar/data?ids={airid}&format=raw&hours=0&taf=off&layout=off&date=0'.format(airid=e1.get())
website = urllib2.urlopen(airid)
website_html = website.read()
data_start = website_html.find("<!-- Data starts here -->")
br1 = data_start + 25
br2 = website_html.find("<br />")
metar_slice = website_html[br1:br2]
print("Here is the undecoded METAR data:\n"+metar_slice)
root2 = Tk()
root2.title("#Conection_Made#")
metar_dat_label = Label(root2, text="Here is the undecoded METAR data:")
metar_dat_label_ln_2 = Label(root2, text=metar_slice)
metar_dat_label.grid(row=0)
metar_dat_label_ln_2.grid(row=1)
def _quit():
sys.exit()
def …
Run Code Online (Sandbox Code Playgroud) python ×13
tkinter ×13
python-3.x ×3
asynchronous ×1
checkbox ×1
elapsedtime ×1
exit ×1
for-loop ×1
loops ×1
progress-bar ×1
python-2.7 ×1
signals ×1
sleep ×1
time ×1
urllib2 ×1