屏幕未在 kivy 中更新

Screen isn't updated in kivy

所以这是带有回溯(使用递归)的简单数独求解器。每次递归后屏幕都会更新(以显示更改),但在完全完成之前不会显示任何内容。问题在哪里?也可能有更好的方法在每次更改后更新屏幕?

代码:

'''

def update_numbers(self):
    self.clear_widgets()
    
    greeting = Label(text="Sudoku", pos=(self.width/2 - 70, 1200), size_hint=(0.2, 0.08))
    self.add_widget(greeting)
    
    v_x, v_y = 15, 955
    for k, row in enumerate(board, start=1):
        for k1, col in enumerate(row, start=1):
            self.add_widget(Label(text=str(col), pos=(v_x, v_y), size_hint=(0.3, 0.3)))
            v_x += 60
        
        v_x = 15
        v_y -= 60
    
def solve(self, bo):
    self.update_numbers() # should update the screen

    #everything further is solver itself

    find = find_empty(bo)
    if find:
        row, col = find
    else:
        return True
    
    for i in range(1, 10):
        if valid(bo, (row, col), i):
            bo[row][col] = i
            
            if self.solve(bo):
                return True
            
            bo[row][col] = 0

    return False

'''

编辑: 在此处查看类似问题后:How do I update Kivy elements from a thread?

我找到了解决这个问题的方法: '''

def display_setup(self):
    greeting = Label(text="Sudoku", pos=(self.width/2 - 70, 1200), size_hint=(0.2, 0.08))
    self.add_widget(greeting)
    
    v_x, v_y = 15, 955
    for k, row in enumerate(board, start=1):
        for k1, col in enumerate(row, start=1):
            the_label = Label(text=str(col), pos=(v_x, v_y), size_hint=(0.3, 0.3))
            self.labels.append(the_label)
            self.add_widget(the_label)
            
            v_x += 60
            
        
        v_x = 15
        v_y -= 60

@mainthread
def update_numbers(self, *dt):
    for k, label in enumerate(self.labels):
        row = k // 9
        label.text = str(board[row][k % 9])
    
def solve(self, bo):
    Clock.schedule_once(self.update_numbers, 0)
    time.sleep(0.05)
            .....

如果您在主线程上 运行ning solve()(如果它是由 Button 触发的),则显示无法更新,直到 solve()方法returns。显示只能在主线程上更新,并且只有当主线程可用时才可以。

修复方法是在另一个线程中启动 solve() 进程(参见 threading),然后将 update_numbers() 方法标记为 mainthread 方法:

@mainthread
def update_numbers(self):

这导致 update_numbers() 方法在主线程上 运行。