如果您想了解在Tkinter中执行功能期间冻结程序的相关知识,那么本文是一篇不可错过的文章,我们将对tkinter中bind进行全面详尽的解释,并且为您提供关于Mac无法在Tkinter中注册键释放、
如果您想了解在Tkinter中执行功能期间冻结程序的相关知识,那么本文是一篇不可错过的文章,我们将对tkinter中bind进行全面详尽的解释,并且为您提供关于Mac无法在Tkinter中注册键释放、Python Tkinter更新功能冻结了主要功能、Python&Tkinter->关于调用长时间运行的函数来冻结程序、Tkinter程序运行功能,但结束后弹出窗口的有价值的信息。
本文目录一览:- 在Tkinter中执行功能期间冻结程序(tkinter中bind)
- Mac无法在Tkinter中注册键释放
- Python Tkinter更新功能冻结了主要功能
- Python&Tkinter->关于调用长时间运行的函数来冻结程序
- Tkinter程序运行功能,但结束后弹出窗口
在Tkinter中执行功能期间冻结程序(tkinter中bind)
我为我的一个脚本创建了一个小GUI。一切都很好。
当我单击一个按钮时,它会启动一个很大的功能,该功能正在解析某些网站中的许多数据。
但是,一旦我单击了Button,程序就会冻结,直到该功能完全运行为止。一切正常,但是为什么我的GUI在执行功能时冻结了。我想打印一个进度条,但这是不可能的。
这是程序的一部分:
self.Button1 = Button(self.MENU, text="IELTS", command=self.My_Command) self.Button1.grid(row=0, column=0,sticky=W+E)def My_Command(self): ## HERE WE LAUNCH THE FUNCTION Module_1.main() # My Big Function from another file self.Button1.config(text="DONE")
在执行Module_1.main()时,我无法执行任何操作//打印任何内容… GUI完全冻结。
Module_1.main()函数是一个线程解析器(解析来自两个网站的某些数据),通常需要2分钟才能运行。如果某人有想法可以在执行此功能所需的2分钟内与程序进行交互,则将非常有帮助。
答案1
小编典典Tkinter是单线程的。屏幕更新在整个事件循环中每次旅行时发生。每当您使用长时间运行的命令时,都在阻止事件循环完成迭代,从而阻止了事件的处理,从而阻止了重绘。
唯一的解决方案是:a)对长时间运行的命令使用线程,b)对长时间运行的命令使用进程,或者c)将命令分解为小块,每个小块可以在几毫秒内运行,因此您可以运行一个事件循环的后续迭代中的块。您还有另一种解决方案,该解决方案是update_idletasks
定期调用窗口小部件的方法,但这是解决方法,而不是修复方法。
请记住,Tkinter不是线程安全的,因此使用线程需要格外小心。您只能从主线程调用窗口小部件上的方法,这意味着其他线程必须通过线程安全队列与主线程进行通信。
Mac无法在Tkinter中注册键释放
如何解决Mac无法在Tkinter中注册键释放?
运行以下代码在Windows计算机上可以完美运行。但是,当我在MacBook上运行它时,按键释放事件List<Book> books = ...
Map<String,List<Long>> booksByOwner = books.stream()
.flatMap(book -> Arrays.stream(book.getowner().split("/"))
.map(owner -> new AbstractMap.SimpleEntry<>(owner,book.getBookId())))
.collect(Collectors.groupingBy(
AbstractMap.SimpleEntry::getKey,Collectors.mapping(AbstractMap.SimpleEntry::getValue,Collectors.toList())));
将在按下w时返回,未释放。
问题:tkinter或其他标准库中是否有修订/替代方法? 我想避免因为pygame或键盘而下载新的库,因为我不允许在学校计算机上这样做。
* 窗口(win 10)具有python 3.5.2,Mac(Catalina 10.15.6)具有python 3.8.5
canvas.bind_all(''<keyrelease-w>'',func)
编辑:根据评论,这可能是Tkinter库中的错误。 但是问题仍未解决。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
Python Tkinter更新功能冻结了主要功能
如何解决Python Tkinter更新功能冻结了主要功能?
我有一个带有python API的Windows应用程序(支持python 3)。您可以提供具有主要功能的类。在程序启动时,将创建此类的实例,并定期调用main函数。我可以配置频率,但是没有别的。 (我无法更改API的工作方式)
现在,我想将tkinter用于某些可视化效果,图表等。这是我当前的类结构的示例:
import tkinter as tk
class Script:
def __init__(self):
self.root = tk.Tk()
self.count = 0
def main(self):
# do some stuff
print(str(self.count))
self.count += 1
# update gui
self.root.update()
# This is to simulate the software behavior.
import time
scriptInstance = Script()
for i in range(0,20 * 10):
scriptInstance.main()
time.sleep(0.1)
我遇到的主要问题是,只要您与Tkinter交互,root.update()方法就会冻结main函数。您可以在上面的示例中看到,只要您移动窗口,该数字就不会递增。有办法防止这种情况吗?
我试图通过另一个线程调用root.update(),该线程不起作用,因为Tkinter不允许这样做。
谢谢您的帮助。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
Python&Tkinter->关于调用长时间运行的函数来冻结程序
这是GUI编程中的新功能,我正在尝试为我的python解析器之一创建GUI。
我知道 :
-
Tkinter是单线程的。屏幕更新在整个事件循环中每次旅行时发生。每当您使用长时间运行的命令时,都在阻止事件循环完成迭代,从而阻止了事件的处理,从而阻止了重绘。
-
我的程序调用了一个大函数,大约需要5分钟才能完全运行它。因此,我猜唯一的解决方案是针对长期运行的命令使用线程。但是,我长期运行的命令已经在线程中,所以我真的不知道如何继续。
->在GUI中单击BUT1后,程序将冻结,直到功能完全完成。我想 在backgroung中 运行此功能,因此程序不会冻结。
->我不是在寻找完整的解决方案,但是如果有人可以让我走上一个好的轨道,那就太好了!
- Main.py-> GUI
- Module_1.py->我们通过单击按钮BUT1调用的函数
先感谢您 !
这是Main.py-> GUI
#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *
import sys
import tkMessageBox
import tkFileDialog
import Module_1
import csv
from time import strftime,gmtime
DATE = strftime("_%d_%b_%Y")
class App:
def __init__(self,master):
self.frame = Frame(master,borderwidth=5,relief=RIDGE)
self.frame.grid()
class IORedirector(object):
def __init__(self,TEXT_INFO):
self.TEXT_INFO = TEXT_INFO
class StdoutRedirector(IORedirector):
def write(self,str):
self.TEXT_INFO.config(text=self.TEXT_INFO.cget('text') + str)
self.TEXT_HEADER = self.text_intro = Label(self.frame,bg="lightblue",text="THIS IS \n MY SUPER PROGRAM")
self.TEXT_HEADER.grid(row=0,column=0,columnspan=2,sticky=W+E+N+S)
self.MENU = Frame(self.frame,relief=RIDGE,height=12)
self.MENU.grid(row=1,sticky=N)
self.button = Button(self.MENU,text="QUIT",bg="red",command=self.frame.quit)
self.button.grid(row=4,column=0)
self.BUT1 = Button(self.MENU,text="BUT1",command=self.BUT1)
self.BUT1.grid(row=0,sticky=W+E)
self.TEXT_INFO = Label(self.frame,height=12,width=40,text="SOME TEXT",bg="grey",relief=RIDGE)
self.TEXT_INFO.grid(row=1,column=1,sticky = N+W)
sys.stdout = StdoutRedirector(self.TEXT_INFO)
def BUT1(self):
self.BUT1.config(text="RUNNING")
self.TEXT_INFO.config(text="BUT1 LAUNCHED")
Module_1.main("BUT1")
## HERE WE NEED TO RUN THE FUNCTION
## THE PROGRAMM FREEZE HERE UNTIL THE FUNCTION IS ENTIRELY RUN
self.TEXT_INFO.config(text="BUT1 FINISHED")
self.BUT1.config(text="DONE")
root = Tk()
app = App(root)
root.mainloop()
这是Module_1.py->包含big函数
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Queue
import threading
import urllib2
import time
from bs4 import BeautifulSoup as soup
from urllib2 import urlopen
import re
import os
import random
import sys
import logging
import csv
from time import strftime,gmtime
import os
import random
import shutil
import sys
import re
import logging
from threading import RLock
from time import strftime,gmtime
import csv
import urllib
from urllib import urlretrieve
from grab.spider import Spider,Task
logging.basicConfig(level=logging.CRITICAL) # Loggin to DEBUG / INFO
log = logging.getLogger()
DATE = strftime("_%d_%b_%Y")
class SPIDER1(Spider):
initial_urls = ['URL_THAT_I_NEED_TO_PARSE']
def __init__(self):
super(SPIDER1,self).__init__(
thread_number=20,network_try_limit=20,task_try_limit=20
)
self.result = {}
def task_initial(self,grab,task):
for opt in grab.css_list("select[name='Template$TestCentreSearch1$SubRegionList'] option")[1:]:
grab.set_input('Template$TestCentreSearch1$SubRegionList',opt.attrib['value'])
grab.submit(extra_post={
'__EVENTTARGET': 'Template$TestCentreSearch1$SubRegionList'
},make_request=False)
yield Task('parse',grab=grab,country=opt.text_content())
def task_parse(self,task):
log.info('downloaded %s' % task.country)
city_gen = (x.text_content() for x in grab.css_list(".TestCentreSearchLabel+br+span"))
title_gen = (x.text_content() for x in grab.css_list(".TestCentreSearchTitle"))
id_gen = (x.attrib['href'][-36:] for x in grab.css_list(".TestCentreSearchLink"))
for x in zip(city_gen,title_gen,id_gen):
self.result[x[2]] = {
'country': task.country,'city': x[0],'name': x[1],'id': x[2],'price':'','currency':'','fee':''
}
yield Task('info','URL_URL=%s' % x[2],id=x[2])
def task_info(self,task):
for label in grab.css_list(".TestCentreViewLabel"):
if label.text_content().strip()=="Test Fee:":
fees = label.getnext().text_content().strip()
self.result[task.id]['fee'] = fees
price = re.findall('\d[\d\.,]+\d',fees)
if price:
price = re.findall('\d[\d\.,fees)[0]
self.result[task.id]['price'] = price.replace(' ','').replace(',','.')
currency = re.findall('[A-Z]{2,3}[$|€|£]?',fees)
if not currency:
currency = re.findall('[$|€|£]',fees)
if not currency:
currency = fees.replace(price,'').strip().replace(' ','')
if isinstance(currency,list):
currency = currency[0]
self.result[task.id]['currency'] = currency
#log.info(' %(price)s %(currency)s - %(fee)s ' % self.result[task.id])
break
def dump(self,path):
"""
Save result as csv into the path
"""
with open(path,'w') as file:
file.write("ID;Country;State;City;Name;Price;Currency;Original Fee\n")
for test_center in sorted(self.result.values(),key=lambda x: "%(country)s%(city)s%(name)s" % x):
file.write(("%(id)s;%(country)s;;%(country)s;%(name)s;%(price)s;%(currency)s;%(fee)s\n" % test_center).encode('utf8'))
def main(choice):
parser,path,name = None,None,None
def run(name,parser,path):
log.info('Parsing %s...' % name)
parser.run()
parser.dump(path)
log.info('Parsing %s completed,data was dumped into %s' % (name,path))
log.info(parser.render_stats())
if choice == "NONE":
# DO NOTHING
# HERE I'D LIKE TO HAVE ANOTHER CALL TO ANOTHER THREADED FUNCTION
elif choice == "BUT1":
run('Function1',SPIDER1(),'C:\LOL\Output1'+DATE+'.csv')
因此,通过单击BUT1,我们运行Module_1.py文件中包含的main(“ BUT1”)函数,并带有参数BUT1,然后启动->
run(’Function1’,SPIDER1(),’C:\ LOL \ Output1’+ DATE +
‘.csv’),然后程序冻结,直到解析器完成工作为止.. :)
Tkinter程序运行功能,但结束后弹出窗口
如何解决Tkinter程序运行功能,但结束后弹出窗口?
好的,所以我对 tkinter 还很陌生,我无法解决我遇到的这个问题。
当我运行程序时,它运行该函数,并在它结束后弹出带有照片的窗口,但循环不会再次启动程序。
import tkinter as tk
from tkinter import*
from PIL import ImageTk,Image
from tkinter import messageBox
import YuaChanMainFunc
import time
def on_click(event=None):
# `command=` calls function without argument
# `bind` calls function with one argument
print("hey Yua!")
YuaChanMainFunc.statement="hey yua"
class Window(Frame):
def __init__(self,master=None):
super().__init__(master)
self.master = master
self.pack()
master.title("Yua-chan AI")
self.img = ImageTk.PhotoImage(Image.open("YuaChanAI/Yua Chan Artwork/YuaChan2.png"))
MainLB = tk.Label(master,image=self.img)
MainLB.bind(''<Button-1>'',on_click)
MainLB.pack()
b = tk.Button(root,text="Close",command=root.destroy)
b.pack()
#YuaChanMainFunc.YuaChanaimainFunc()
root = tk.Tk()
#instance of the class
app = Window(root)
root.resizable(0,0)
root.geometry("310x500+1600+510")
YuaChanMainFunc.YuaChanaimainFunc()
#Runs the application until we close
root.mainloop()
解决方法
据我所知你想要“YuaChanMainFunc.YuaChanAIMainFunc()” 在 UI 运行前台时在后台运行。为此,您可以在不同的线程中启动“YuaChanMainFunc.YuaChanAIMainFunc()”并在主线程本身中运行 UI。现在你可以让 "YuaChanMainFunc.YuaChanAIMainFunc()" 成为一个无限循环,它不会阻塞 root.mainloop()。还要记住 root.mainloop() 也是一个无限循环。因此,在关闭程序之前,您之后编写的任何内容都不会执行。
import threading
backend_thread = threading.Thread(target=YuaChanMainFunc.YuaChanAIMainFunc,args=())
backend_thread.daemon = True #This will make sure backend thread closes when you close ui
backend_thread.start()
root.mainloop()
今天的关于在Tkinter中执行功能期间冻结程序和tkinter中bind的分享已经结束,谢谢您的关注,如果想了解更多关于Mac无法在Tkinter中注册键释放、Python Tkinter更新功能冻结了主要功能、Python&Tkinter->关于调用长时间运行的函数来冻结程序、Tkinter程序运行功能,但结束后弹出窗口的相关知识,请在本站进行查询。
本文标签: