相关疑难解决方法(0)

Tkinter了解mainloop

直到现在,我曾经用以下结束我的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)

python tkinter

49
推荐指数
2
解决办法
12万
查看次数

Tkinter:在主循环中调用事件

你如何event从一个单独的对象调用tkinter ?

我正在寻找像wxWidgets这样的东西wx.CallAfter.例如,如果我创建一个对象,并将其传递给我的Tk根实例,然后尝试从我的对象调用该根窗口的方法,我的应用程序将锁定.

我能想到的最好的after方法是使用方法并从我的单独对象中检查状态,但这似乎很浪费.

python user-interface communication tkinter

16
推荐指数
2
解决办法
2万
查看次数

Python time.sleep

我试图在等待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 time sleep tkinter elapsedtime

9
推荐指数
1
解决办法
3万
查看次数

如何在python tkinter中的for循环中从列表创建多个复选框

我有一个可变长度列表,并希望为列表中的每个条目创建一个复选框(使用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个复选框,但它们全部勾选或未勾选,并且enabledict中的值不会更改.怎么解决?(我认为这l不起作用,但如何使这个变量?)

python checkbox for-loop tkinter

8
推荐指数
1
解决办法
2万
查看次数

如何在Python中每3小时更新一次URL

我是一个试图学习编程的老人.我试过寻找这个问题的答案,但大多数回复都是我的头脑.所以这里,我编写了代码来从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)

python tkinter

6
推荐指数
1
解决办法
140
查看次数

从按钮命令 Tkinter 调用异步函数

我想从 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等)。

有人知道如何解决这个问题吗?我也不想创建线程。谢谢

python asynchronous tkinter

6
推荐指数
1
解决办法
3901
查看次数

在单独的线程中运行Tkinter表单

我编写了一个可以传递图像的简短模块,只需创建一个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窗口关闭.

python multithreading tkinter

5
推荐指数
2
解决办法
2万
查看次数

使用 Ctrl-C 退出 tkinter 应用程序并捕获 SIGINT

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(没有任何反应)
  • 关上窗户
  • 打印“Exiting...”,并且收到有关循环已退出的错误。

这是怎么回事?如何让终端中的 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)

python multithreading signals tkinter

5
推荐指数
2
解决办法
8311
查看次数

在tkinter窗口中禁用退出(或[X])

我之所以发布此消息,是因为我自己一直在努力寻找有关此问题的明确答案。。。

为了尝试为我的程序创建进度条,我发现使用tkinter很难做到。为了完成创建进度条而没有遇到可怕的“ mainloop”,我选择使用threads从进度条中制作一个类。经过大量的试验,发现一个错误,由于使用多线程(tkinter喜欢在主线程中),因此无法自定义很多内容。这是我尝试过的两个选项,其次是最适合我的需求的第三个选项:

选项1:使用回调函数

给出以下代码:

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 exit python-3.x progress-bar

5
推荐指数
2
解决办法
9635
查看次数

关闭 tkinter 应用程序时,Python 线程调用不会完成

我正在 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 multithreading tkinter python-3.x

5
推荐指数
1
解决办法
550
查看次数

如何轻松避免Tkinter冻结?

我开发了一个简单的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)

它只会执行一次刷新,我无法理解为什么.

非常感谢你的帮助.

python user-interface tkinter

3
推荐指数
1
解决办法
8665
查看次数

在Tkinter应用程序旁边运行一个循环

我是一名高中编程学生,我有一个小问题.我的任务是在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)

python loops tkinter python-2.7

2
推荐指数
1
解决办法
4726
查看次数

如何使while(True):在python中同时运行两个循环

基本上我需要同时运行两个 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 multithreading tkinter urllib2 python-3.x

1
推荐指数
1
解决办法
8591
查看次数