Помогите добавить потоки для прогресса GUI - PullRequest
3 голосов
/ 02 августа 2011

У меня есть функция FTP, которая отслеживает ход выполнения загрузки, но мое понимание многопоточности ограничено, и я не смог реализовать работающее решение ... Я хотел бы добавить индикатор прогресса графического интерфейса в мое текущее приложение.используя потоки.Может кто-нибудь показать мне основную функцию, используя асинхронные потоки, которые могут быть обновлены из другого запущенного потока?

def ftpUploader():
    BLOCKSIZE = 57344 # size 56 kB

    ftp = ftplib.FTP()
    ftp.connect(host)
    ftp.login(login, passwd)
    ftp.voidcmd("TYPE I")
    f = open(zipname, 'rb')
    datasock, esize = ftp.ntransfercmd(
        'STOR %s' % os.path.basename(zipname))
    size = os.stat(zipname)[6]
    bytes_so_far = 0
    print 'started'
    while 1:
        buf = f.read(BLOCKSIZE)
        if not buf:
            break
        datasock.sendall(buf)
        bytes_so_far += len(buf)
        print "\rSent %d of %d bytes %.1f%%\r" % (
              bytes_so_far, size, 100 * bytes_so_far / size)
        sys.stdout.flush()

    datasock.close()
    f.close()
    ftp.voidresp()
    ftp.quit()
    print 'Complete...'

1 Ответ

1 голос
/ 02 августа 2011

Вот краткий обзор потоков, на всякий случай :) Я не буду вдаваться в подробности графического интерфейса, кроме как сказать, что вы должны проверить wxWidgets. Всякий раз, когда вы делаете что-то, что занимает много времени, например:

from time import sleep
for i in range(5):
    sleep(10)

Вы заметите, что пользователю кажется, что весь блок кода занимает 50 секунд. В течение этих 5 секунд ваше приложение не может ничего сделать, как обновить интерфейс, и похоже, что оно заморожено. Для решения этой проблемы мы используем многопоточность.

Обычно есть две части этой проблемы; общий набор вещей, которые вы хотите обработать, и операция, которая занимает некоторое время, которую мы хотели бы разделить. В этом случае общий набор - это цикл for, а операция, которую мы хотим нарезать, - это функция sleep (10).

Вот быстрый шаблон для кода потоков, основанный на нашем предыдущем примере. Вы должны быть в состоянии обработать ваш код в этом примере.

from threading import Thread
from time import sleep

# Threading.
# The amount of seconds to wait before checking for an unpause condition.
# Sleeping is necessary because if we don't, we'll block the os and make the
# program look like it's frozen.
PAUSE_SLEEP = 5

# The number of iterations we want.
TOTAL_ITERATIONS = 5

class myThread(Thread):
    '''
    A thread used to do some stuff.
    '''
    def __init__(self, gui, otherStuff):
        '''
        Constructor. We pass in a reference to the GUI object we want
        to update here, as well as any other variables we want this
        thread to be aware of.
        '''
        # Construct the parent instance.
        Thread.__init__(self)

        # Store the gui, so that we can update it later.
        self.gui = gui

        # Store any other variables we want this thread to have access to.
        self.myStuff = otherStuff

        # Tracks the paused and stopped states of the thread.
        self.isPaused = False
        self.isStopped = False

    def pause(self):
        '''
        Called to pause the thread.
        '''
        self.isPaused = True

    def unpause(self):
        '''
        Called to unpause the thread.
        '''
        self.isPaused = False

    def stop(self):
        '''
        Called to stop the thread.
        '''
        self.isStopped = True

    def run(self):
        '''
        The main thread code.
        '''
        # The current iteration.
        currentIteration = 0

        # Keep going if the job is active.
        while self.isStopped == False:
            try:
                # Check for a pause.
                if self.isPaused:
                    # Sleep to let the os schedule other tasks.
                    sleep(PAUSE_SLEEP)
                    # Continue with the loop.
                    continue

                # Check to see if we're still processing the set of
                # things we want to do.
                if currentIteration < TOTAL_ITERATIONS:
                    # Do the individual thing we want to do.
                    sleep(10)
                    # Update the count.
                    currentIteration += 1
                    # Update the gui.
                    self.gui.update(currentIteration,TOTAL_ITERATIONS)
                else:
                    # Stop the loop.
                    self.isStopped = True

            except Exception as exception:
                # If anything bad happens, report the error. It won't
                # get written to stderr.
                print exception
                # Stop the loop.
                self.isStopped = True

        # Tell the gui we're done.
        self.gui.stop()

Чтобы вызвать эту тему, все, что вам нужно сделать, это:

aThread = myThread(myGui,myOtherStuff)
aThread.start()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...