简体   繁体   English

Tkinter的Python线程

[英]Python threading with tkinter

Back to working on a program I started and partially finished back in late Nov/early Dec. 回到开发程序,我从11月下旬/ 12月初开始,并部分完成了工作。

I want to send a value to a program/thread, reset the value and do it again, 11 times. 我想将值发送到程序/线程,重置该值,然后再次执行11次。 The programs/threads will be running simultaneously right alongside the main program/thread. 程序/线程将与主程序/线程同时运行。 I want the 'child threads' to report back to the main program/thread and the main thread will display on a gui where each of the threads is currently processing so I can have a rough idea of how much longer it will be before the entire task is finished. 我希望“子线程”向主程序/线程报告,并且主线程将显示在gui中每个线程当前正在处理的位置,因此我可以粗略地了解到整个子进程之前还有多长时间任务完成。 This was the original concept now I'm looking at combining another program with this, which will be downloading other images from the internet, while this one is searching the internet for certain audio/video files. 这是最初的概念,现在我正在考虑与此结合的另一个程序,该程序将从互联网上下载其他图像,而这个程序正在互联网上搜索某些音频/视频文件。 This part of the program will take longer to execute then the image downloads(45 minutes, roughly versus 4-5 minutes for the image downloads). 该程序的这一部分将花费更长的时间执行,然后执行图像下载(45分钟,而图像下载大约需要4-5分钟)。

Once the image downloads are finished I want to be able to look through the images. 图像下载完成后,我希望能够浏览图像。 Hence the mother thread would have to be 'fully functional' not tied up. 因此,母线程将必须“完全功能化”而不是捆绑在一起。

This idea keeps expanding as I keep learning more of the capabilities I have with Python that I never really had with VB6. 随着我不断学习更多关于Python的能力,而我从未真正拥有VB6的能力,这个想法不断扩展。

I saw in old post a few minutes ago that Tkinter only works with the main thread. 几分钟前,我在旧帖子中看到Tkinter仅适用于主线程。 Hence the reason I was always getting the errors in the code below. 因此,我总是在下面的代码中得到错误的原因。

Is there a way, without locking up the main program/thread that I can have the child threads report back to the main thread and have the main thread update the screen while still letting the main thread function normally(download/display images)? 有没有办法在不锁定主程序/线程的情况下让子线程向主线程报告并让主线程更新屏幕,同时仍然让主线程正常工作(下载/显示图像)?

Here's a look at where I'm currently starting from. 这是我目前的出发地。

import os
import sys
import urllib
from tkinter import *
import threading
import time

class Startup:
    def __init__(self, root):
            self.DrawArea = Canvas(root, height=250, width=200,bg = 'black')
            self.starthere()        

    def dl_0(self):
            self.NxtNum0 = int(self.HiStr0)
            while self.NxtNum0 < int(self.HiStr0)+100:
                    self.DrawArea.create_text(50,12,text = str(self.NxtNum0), fill = 'white', tags = '0')
                    self.NxtNum0 +=1
                    #download routine goes here once the on screen update routine gets straightened out, time.sleep(.1) will be removed
                    time.sleep(.1)
                    #self.DrawArea.delete('0')

    def dl_1(self):
            self.NxtNum1 = int(self.HiStr1)
            while self.NxtNum1 < int(self.HiStr1)+100:
                    self.DrawArea.create_text(50,37,text = str(int(self.NxtNum1)), fill = 'white', tags = '1') 
                    self.NxtNum1 +=1
                    #download routine goes here once the on screen update routine gets straightened out, time.sleep(.1) will be removed
                    time.sleep(.1)
                    #self.DrawArea.delete('1')

    #continue on through all 11 threads

    def starthere(self):
            #find current highest value
            Hival = open("Highest.txt", "r") 
            Histr = Hival.read()
            Hival.close()
            self.HiStr0 = str(int(Histr)+1)
            HiStra = int(int(Histr)/10000)

            #call download #0
            dl0 = threading.Thread(target = self.dl_0, name = 'dl0')
            dl0.start()

            #setup/call download #1
            self.HiStr1 = str(str(HiStra+1)+"0000")
            dl1 = threading.Thread(target = self.dl_1, name = 'dl1')
            dl1.start()

            #continue on down through all 11 threads

if (__name__ == "__main__"):
    os.chdir ('/media/')
    root = Tk()
    root.geometry("200x250")
    Thr = Startup(root)

The above, like I said above is from trying most of the day without internet access to get this thing to work right. 就像我上面所说的,以上内容是在一天的大部分时间里都无法上网的情况下进行的,以便使此功能正常运行。 It's definitely written a bit screwy compared to what it should be now that I think I understand the Tkinter limitation. 与我现在应该了解Tkinter的局限性相比,它的写作绝对有些麻烦。

I fess in the original partially finished version I was creating 11 separate guis/programs using subprocess. 在最初的部分完成版本中,我使用子过程创建了11个单独的GUI /程序。 They had no way of sending back the values to the main program(at least not that I know of). 他们无法将这些值发送回主程序(至少不是我所知道的)。 I like the idea much better of using just one program and having the child threads report back and the main thread and having the main thread continually update the screen showing the file number of the file that is currently being looked at in each of the 11 child threads. 我更喜欢只使用一个程序并让子线程报告和主线程并让主线程不断更新屏幕的想法,该屏幕显示11个子进程中每个子进程当前正在查看的文件的文件号线程。 Can I do this and still have the screen updated and be able to continue to use and display other threads(non 11 above) at the same time or not? 我可以这样做,并且仍然可以更新屏幕,并且可以继续使用和显示其他线程(以上非11线程)吗?

I hope this isn't totally confusing...sorry if it is. 我希望这不会完全令人困惑...对不起。

Is threading the best solution ? 穿线是最好的解决方案吗? You could spawn child processes from the gui to download the images look at the process pool class in multiprocessing. 您可以从gui生成子进程以下载映像,然后查看多处理中的进程池类。

eg could a download class that the gui spawns multiple processes of for the downloading. 例如,gui可以生成下载的多个进程的下载类。

Remember threads run in the same memory space, while processes have separate memory. 请记住,线程在相同的内存空间中运行,而进程具有单独的内存。

These may be useful Multiprocessing vs Threading Python Status of mixing multiprocessing and threading in Python Is it safe to fork from within a thread? 这些可能是有用的Multiprocessing vs Threading Python 在Python中混合使用多处理和线程的状态 从线程内派生是否安全?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM