Tkinter progressbar działający równloegle z wykonywanym kodem

0

Witam, próbuję napisać aplikację, która wyszukuje dane w internecie. Chciałbym, żeby w między czasie pokazywała progressbar z postępem wyszukiwań. Napisałem taki kod:

import requests
from bs4 import BeautifulSoup
from Service import SQLLiteService as SQL
from GUI import Tools
from tkinter import *
from tkinter import ttk
import time

class OLXService:
    def __init__(self, url):
        self.Url = url
        self.Sql = SQL.DataStorage()
        self.Progress = None
        self.AllRows = 1100

    def init_progress(self):
        pw = Tk()
        pw.title("Pozyskiwanie danych z serwisu OLX")
        pw.resizable(False, False)
        Tools.window_size_position(600, 10, pw)

        self.Progress = ttk.Progressbar(pw, orient = HORIZONTAL, length = 600, mode = 'indeterminate')
        self.Progress.grid(column = 0, row = 0)
        time.sleep(2)

    def make_step(self):
        self.Progress['value'] += 100 / self.AllRows
        print(self.Progress['value'])

    def get_urls(self):
        self.init_progress()
        page = requests.get(self.Url)
        i = 0
        end = False
        while end != True:
            links = BeautifulSoup(page.content, 'html.parser')
            for a in links.find_all('a', href = True, attrs= {'class' : 'marginright5'}):
                self.make_step()
                self.Sql.exec_query("delete from offerlinks where link = '%s'" % a['href'].split('?')[0])

                webpage = None
                if 'olx' in a['href'].split('?')[0]:
                    webpage = 'olx'
                else:
                    webpage = 'otodom'

                self.Sql.exec_query("insert into offerlinks (link, webpage) values ('{}', '{}')".format(a['href'].split('?')[0], webpage))
            try:
                page = requests.get(links.find('a', href = True, attrs= {'data-cy' : 'page-link-next'})['href'])
            except:
                end = True

    def update(self):
        return

Niestety progressbar uruchamia się dopiero po tym jak funkcja zakończy swoją pracę :/ Da się jakoś to rozwiązać?

1

Nie umiem Pythona, nie wiem jak działa w środku a w połączeniu z GUI już zupełnie jestem noga... Dlatego stwierdziłem, że się wypowiem :-)

Generalnie masz wszystko w jednej pętli i w czasie jej wykonywania aplikacja nie przetwarza komunikatów systemowych w tym komunikacji z GUI co powoduje efekt "zawieszenia aplikacji" na czas jej wykonywania.
Musisz użyć odpowiednika stdout.flush tylko dla GUI. Aplikacja musi przetworzyć ( odebrać / wysłać ) komunikaty systemowe żeby odświeżyć to co na ekranie.

Wygląda na to, że kluczem jest funkcja: update_idletasks

Chwilę poszukałem i widziałem, że robią to na wątkach lub poprzez:

  1. https://stackoverflow.com/questions/36516497/how-to-update-a-progress-bar-in-a-loop
  2. https://www.programcreek.com/python/?CodeExample=process%20messages
  3. oraz TQDM.

1 użytkowników online, w tym zalogowanych: 0, gości: 1