Выполнение цикла while в основном потоке до тех пор, пока мы не получим возвращаемое значение из функции, вызываемой во вторичном потоке

#python #multithreading #selenium #kivymd

Вопрос:

Я хочу написать код, который делает что-то вроде-

В потоке вызовите функцию, которая вернет две ссылки, и в основном потоке продолжайте печатать «обработка…», пока эта функция, вызванная во вторичном потоке, не вернет эти значения

и когда мы получаем эти возвращаемые значения, цикл while основного потока завершается и выводит эти значения.

Теперь я попробовал написать несколько кодов на python, но не смог этого сделать! Я только начал программировать на python, поэтому я с ним не знаком.

Кстати, вышеупомянутый сценарий-это всего лишь прототип.

Реальный случай выглядит примерно так:-

     def search_button(self):              #main thread
        mname = self.root.ids.name.text
        quality = Quality
        
        #print(mname)
        #print(quality)

            
        global link4, link5

        with concurrent.futures.ThreadPoolExecutor() as executor:
            futures = executor.submit(movie_bot, mname, quality)    #movie_bot is function
            link4, link5 = futures.result()                         #returning two links



        while(link4==None and link5==None):
            self.root.ids.status.text = 'Searching, please wait...'
            self.root.ids.status.text = ''

        print(link4)
        print(link5) 
 

В случае, если потребуются дополнительные подробности, пожалуйста, просто дайте мне знать.

Спасибо вам за помощь.

Ответ №1:

Перепробовал много вещей, и теперь, наконец, все разрешилось.

В основном, что я хотел сделать, это взять два ввода из графического интерфейса, затем вызвать функцию (из другой программы на python) с этими двумя параметрами, а затем, как только обработка будет завершена, затем от пользователя графического интерфейса и либо посмотреть, либо загрузить этот контент, нажав кнопки «Посмотреть» или «загрузить» соответственно.

Поэтому, чтобы сделать это раньше, я возвращал ссылку на просмотр и загрузку из этого потока, называемого функцией, и даже при вызове этой функции в другом потоке, так как она возвращала значения после выполнения, поэтому графический интерфейс зависает и показывает, что он не отвечает

Затем, после многих попыток, я наткнулся на демона, поэтому я просто создал демона потока, и это решило основную проблему замораживания, но теперь я не мог принимать возвращаемые значения (когда я попытался принять возвращаемые значения, он снова начал замораживать графический интерфейс).

Поэтому я нашел альтернативу доступу к этим ссылкам из основного потока.

Здесь дело в том, что если функция не возвращает ничего, что вызывается в потоке, то просто сделайте ее демоном thread_name.daemon() = True , и теперь она не будет замораживать графический интерфейс

Теперь, если вы хотите что-то сделать именно после завершения потока, это можно использовать thread_name.is_alive()

МОЙ КОД ВЫГЛЯДИТ ПРИМЕРНО ТАК:-

 from selenium_l_headless import movie_bot
from kivy.lang import Builder 
from kivymd.app import MDApp
from  kivy.properties import ObjectProperty
from selenium_l_headless import *
import threading
import time
from kivy.clock import Clock


class MovieBot(MDApp):

    mname = ObjectProperty(None)
    quality = ObjectProperty(None)
    Quality = ObjectProperty(None)
    link4 = ObjectProperty(None)
    link5 = ObjectProperty(None)


    checks = []
    def build(self):
        self.theme_cls.theme_style= "Dark"
        self.theme_cls.primary_palette = "Teal" 
        return Builder.load_file('kivy_bot_md.kv')

        def checkBox_click(self, instance, value, Q):
            global Quality
            if value==True:
                MovieBot.checks.append(Q)
                Quality=''
                for x in MovieBot.checks:
                    Quality = f'{Quality}{x}'
            else:
                MovieBot.checks.remove(Q) 
                Quality = ''
                for x in MovieBot.checks:
                    Quality = f'{Quality} {x}'    
        def complete(self):
            self.root.ids.status.text = 'Searching completed, Now you can
                                         download or watch the movie!'
            global flag
            flag=0

        def status_sleep(self, *args):
        
            try:
                self.root.ids.status.text = 'Searching, please wait...'
            
                if(t1.is_alive() is False):
                    self.complete()
            except:
                pass

        
        def search_button(self):
            try:
                mname = self.root.ids.name.text
                quality = Quality

            
                global link4,link5
        
                global t1, flag
                flag=1
                t1 = threading.Thread(target = movie_bot, args= [mname, quality])
                t1.daemon = True
                t1.start()
        
                if(t1.is_alive()):
                    Clock.schedule_interval(self.status_sleep,1)
            except:
                pass

    def watch(self):
        try:
            if(flag is 1):
                pass
            else:
                self.root.ids.status.text = ''
                t2 = threading.Thread(target=watch_now)
                t2.daemon = True
                t2.start()
            except:
                pass

    def download(self):
        try:
            if(flag is 1):
                pass
            else:
                self.root.ids.status.text = ''
                t3 = threading.Thread(target=download_movie)
                t3.daemon = True
                t3.start()
        except:
            pass

    def close(self):
        exit(0) 


MovieBot().run()