首页 > 解决方案 > 使线程函数等待其内部主线程中强制执行的操作完成 - Kivy

问题描述

我在 kivy 中有一个需要时间的大函数,我想踩它,但这个函数有一些与 opengl 相关的操作,所以我制作了这些操作的 3 个函数并在它们上使用 @mainthread 装饰器来强制它们运行主线程,它工作得很好,但有一个大问题,那些使用 @mainthread 装饰器的函数等待下一帧运行,所以线程在这些操作运行之前运行它的所有代码,线程代码依赖于那些 opegl要执行的操作,所以会发生错误,我尝试了很多,但我不能强迫它等待 opengl 操作完成。

这是该功能的简化结构:-

def func1():
    code
    code

    @mainthread
    def func2()
        code
    
    func2()

    code
    code

threading.Thread(target=func1).start()

如果要看的话,这是原始功能:-

            def load_data():
                global original_len

                if not exists(self.file_path + ".pycsv"):

                    for row in csv.reader(f, encoding='utf-8'):

                        if self.row_num == 0:
                            original_len = len(row)
                            if args[0]:

                                if int(args[0][-1]) > len(row):
                                    args[0] = ""
                                    self.row_len = len(row)

                                else:
                                    self.row_len = len(args[0])

                            else:
                                self.row_len = len(row)

                            self.title_grid.cols = self.row_len
                            self.cells_grid.cols = self.row_len
                            
                            @mainthread
                            def add_no():
                                
                                self.title_grid2.add_widget(JoButtonLabel(text="No.", width=50, height=35,
                                                                          size_hint=[None, None]))
                            
                            add_no()
                        while len(row) != original_len:
                            row.append("")

                        if args[0]:
                            extra_data = row[:]

                            if self.row_num == 0:
                                self.title_row = deepcopy(extra_data)

                            for i in sorted(args[0], reverse=True, key=lambda s: int(s)):
                                extra_data.pop(int(i) - 1)

                            if self.row_num == 0:
                                self.title_grid2.children[0].extra = extra_data

                            row = [row[int(i) - 1] for i in args[0]]

                            if self.row_num == 0:
                                self.displayed_titles = row

                        else:
                            extra_data = []


                        if self.row_num != 0:
                            #Adding row numbers
                            self.data2.append({'text': str(self.row_num), 'width': 50, 'height': 35, 'font_name': 'MEIRYO.TTC', 'font_size': '15sp', 'size_hint': [None, None], 'background_color': self.theme[0]})

                            if args[0]:
                                self.data2[-1]['extra'] = extra_data

                        for i in enumerate(row):

                            if self.row_num == 0:
                                #Adding titles
                                
                                @mainthread
                                def add_titles():
                                    if sizes:
    
                                        try:
                                            self.title_grid.add_widget(JoTitle(text=i[1], size=sizes[(i[0] * -1) - 1]))
    
                                        except IndexError:
                                            self.title_grid.add_widget(JoTitle(text=i[1], size=[int(args[3]), 35]))
                                    else:
                                        self.title_grid.add_widget(JoTitle(text=i[1], size=[int(args[3]), 35]))
                                
                                add_titles()
                                
                            else:
                                #Adding cells
                                size = self.title_grid.children[(i[0] * -1) - 1].size[:]

                                self.data.append({'dyn_size': size, 'multiline': False, 'text': i[1], 'font_name': 'MEIRYO.TTC', 'size_hint': [None, None], 'index': len(self.data)})

                                if args[0]:
                                    self.data[-1]['extra_index'] = int(args[0][i[0]])-1

                        self.row_num += 1

                    self.find_col = self.row_len - 1
                    self.title_grid.children[(self.find_col * -1) - 1].children[2].background_color = [0, 0, 0, 1]

                else:
                    with open(self.file_path + ".pycsv", 'r', encoding='utf-8') as df:
                        lines = []
                        for i in df:
                            lines.append(i)

                        self.title_row = ast.literal_eval(lines[0])
                        dc = ast.literal_eval(lines[1])
                        self.title_grid2.add_widget(JoButtonLabel(text="No.", width=50, height=35,
                                                                  size_hint=[None, None]))

                        for t in enumerate(dc):
                            self.title_grid.add_widget(JoTitle(text=t[1], size=ast.literal_eval(lines[2])[(t[0] * 1) - 1]))

                        self.title_grid2.children[0].extra = ast.literal_eval(lines[3])
                        self.args = ast.literal_eval(lines[4])

                        temp = lines[5].split(",")
                        self.row_num = int(temp[0])
                        self.row_len = int(temp[1])
                        self.find_col = int(temp[2].strip("\n"))

                        self.title_grid.cols = self.row_len
                        self.cells_grid.cols = self.row_len
                        self.title_grid.children[self.find_col].children[2].background_color = [0, 0, 0, 1]
                        self.duplicates_list = ast.literal_eval(lines[6])
                        self.marked_rows = ast.literal_eval(lines[7])
                        self.data2 = ast.literal_eval(lines[8])
                        self.data = ast.literal_eval(lines[9])
                        
                @mainthread
                def add_data_recycler():
                    self.scroll.data = self.data
                    self.scroll2.data = self.data2
                
                add_data_recycler()

threading.Thread(target=load_data).start()

标签: pythonmultithreadingkivy

解决方案


像这样的东西会起作用吗?

@mainthread
def add_no():
    self.title_grid2.add_widget(JoButtonLabel(text="No.", width=50, height=35,size_hint=[None, None]))
    lock.release()
lock.acquire()
add_no()
if lock.acquire():
    lock.release()

推荐阅读