Python Forum
[Tkinter] tkinter freezes by clicking button
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] tkinter freezes by clicking button
#11
(Mar-31-2018, 09:18 AM)Zatox11 Wrote: but even after waiting for several minutes nothing happens.
What happens if you run solvesudo.py alone? After some time it should raise SolutionFound and stop.

Also, based on this answer, you can try to put code in tksudo.py in a if __name__ == '__main__' block, for example
# tksudo.py

if __name__ ==  '__main__':
    from tkinter import Tk, Frame, Entry, Label, Button, IntVar, StringVar, LEFT
    from tkinter import messagebox
    from tkcallasync import tk_call_async, MULTIPROCESSING
    import solvesudo

    def do_solve(sudoku):
        status = solvesudo.wsolve(sudoku)
        return status, sudoku

    disabled = False

    def execute_solver():
        global disabled
        if disabled:
            messagebox.showinfo("warning", "It's still calculating...")
            return

        def callback(result):
            global disabled
            disabled = False
            status, sudoku = result
            solvesudo.printSUDOKU(sudoku)
            result_var.set('Found!' if status else 'Not Found!')

        disabled = True
        tk_call_async(root, do_solve, args=(solvesudo.sudoku,), callback=callback, method=MULTIPROCESSING)

    root = Tk()

    row = Frame(root)
    row.pack()
    Button(row, text="Solve Sudoku", command =execute_solver).pack(side=LEFT)
    Button(row, text="It's responsive", command= lambda: messagebox.showinfo("info", "it's responsive")).pack(side=LEFT)

    result_var = StringVar()
    Label(root, textvariable=result_var).pack()

    root.mainloop()
Reply
#12
Yes, when I run solvesudo.py alone, I get "solution found" after a few seconds.
When I put tksudo.py code in if __name__ == '__main__' block, I dont get a second instance of the root window anymore by pressing solve sudoku. But still there is no solution showing up in python shell. The programm remains responsive and when I click on solve sudoku again he says that its still calculating.
Reply
#13
(Mar-31-2018, 10:23 AM)Zatox11 Wrote: there is no solution showing up in python shell.
Does it write 'Found!' in the GUI after some time? Also what happens if you run the program from a cmd window? Are you running the program from a IDE?
Reply
#14
No, it does not write "Found!" in the GUI. I was running the program in IDE before. When I run the program from a cmd window I get the following error msg when I press Solve Sudoku:
[Image: errormsgsho8z.jpg]
Reply
#15
The child process cannot find do_solve, probably because the if __name__ == '__main__' part is not executed in the child process. Try to refactor the code this way
# tksudo.py

import solvesudo

def do_solve(sudoku):
    status = solvesudo.wsolve(sudoku)
    return status, sudoku

if __name__ ==  '__main__':
    from tkinter import Tk, Frame, Entry, Label, Button, IntVar, StringVar, LEFT
    from tkinter import messagebox
    from tkcallasync import tk_call_async, MULTIPROCESSING

    disabled = False

    def execute_solver():
        global disabled
        if disabled:
            messagebox.showinfo("warning", "It's still calculating...")
            return

        def callback(result):
            global disabled
            disabled = False
            status, sudoku = result
            solvesudo.printSUDOKU(sudoku)
            result_var.set('Found!' if status else 'Not Found!')

        disabled = True
        tk_call_async(root, do_solve, args=(solvesudo.sudoku,), callback=callback, method=MULTIPROCESSING)

    root = Tk()

    row = Frame(root)
    row.pack()
    Button(row, text="Solve Sudoku", command =execute_solver).pack(side=LEFT)
    Button(row, text="It's responsive", command= lambda: messagebox.showinfo("info", "it's responsive")).pack(side=LEFT)

    result_var = StringVar()
    Label(root, textvariable=result_var).pack()

    root.mainloop()
Reply
#16
Yes it works! Dance Now I have to implement this into my GUI. GL me
Reply
#17
(Mar-31-2018, 02:15 PM)Zatox11 Wrote: Yes it works! Now I have to implement this into my GUI. GL me
It is not very comfortable to write a lot of code in a if __name__ == '__main__' block. I strongly suggest that you split your code into several files. For example the do_solve() function could go in solvesudo module, and you could write
# tksudo.py
if __name__ == '__main__':
    from guicode import main
    main()
This allows you to write the GUI code in a separate module guicode without the __name__ == '__main__'. The child process would not import the guicode module because the import statement is in the __name__ == '__main__' part.
Reply
#18
Okay, I have split my code into 4 files:

1. main function:
# SudokuSolver_main.py
import SudokuSolver_class as Sudokuolver
from tkinter import *


def main():
    root = Tk()
    app = Sudokuolver.SudokuSolver(root)
    root.mainloop()

if __name__ == '__main__':
    main()
2. Class with Userinterface
# SudokuSolver_class.py
import os
import SudokuSolver_solver as Solver
from random import randint
from tkinter import *
from tkcallasync import tk_call_async, MULTIPROCESSING


class SudokuSolver(Frame):

    disabled = False
    backtrack_ctr = 0
    sudoku = [[" " for col in range(9)] for row in range(9)]
    solution = [[" " for col in range(9)] for row in range(9)]
    exampleSudoku = [[' ',' ',' ','2','1',' ',' ',' ',' '],
                     [' ',' ','7','3',' ',' ',' ',' ',' '],
                     [' ','5','8',' ',' ',' ',' ',' ',' '],
                     ['4','3',' ',' ',' ',' ',' ',' ',' '],
                     ['2',' ',' ',' ',' ',' ',' ',' ','8'],
                     [' ',' ',' ',' ',' ',' ',' ','7','6'],
                     [' ',' ',' ',' ',' ',' ','2','5',' '],
                     [' ',' ',' ',' ',' ','7','3',' ',' '],
                     [' ',' ',' ',' ','9','8',' ',' ',' ']]

    def __init__(self, parent):
        Frame.__init__(self, parent, name='frame')
        self.parent = parent
        self.initUI()
        self.blankSUDOKU()

    def initUI(self):
        self.message_txt = StringVar()
        self.values = {}

        self.parent.title('Sudoku Solver')
        self.pack(fill=BOTH, expand=True)

        self.message = Label(self, textvariable=self.message_txt)
        self.message.grid(row=10,column=0,columnspan=8, sticky=E+W)

        self.solveBtn = Button(self, text="solve",width=6,command=self.execute_solver)
        self.solveBtn.grid(row=0,column=0)

        self.newBtn = Button(self, text="new",width=6,command=self.blankSUDOKU)
        self.newBtn.grid(row=0,column=1)

        self.initBtn = Button(self, text="init",width=6,command=self.initSUDOKU)
        self.initBtn.grid(row=0,column=2)

        self.printBtn = Button(self, text="print",width=6,command=self.printSUDOKU)
        self.printBtn.grid(row=0,column=8)

        self.checkBtn = Button(self, text="check",width=6,command=self.checkSOLUTION)
        self.checkBtn.grid(row=0,column=6)

        self.saveBtn = Button(self, text="save",width=6,command=self.saveSUDOKU)
        self.saveBtn.grid(row=0,column=7)

    # --- clear all fields and delete all values in sudoku[][] and solution[][] --- #
    def blankSUDOKU(self):
        self.message_txt.set('')
        for row in range(9):
            for col in range(9):
                self.sudoku[row][col] = ' '
                self.solution[row][col] = ' '
                self.numEntry = Entry(self, width=5, justify=CENTER,
                                 font="Helvetica 12 bold")
                self.values[row,col] = self.numEntry
                self.numEntry.grid(row=row+1,column=col, ipady=5)

    # ----- get a random Sudoku from textfiles ----- #
    def initSUDOKU(self):
        self.blankSUDOKU()
        self.message_txt.set('')
        L = len(os.listdir(os.getcwd() + "\sudokus")) / 2
        if L < 1:
            self.message_txt.set('No Sudokus saved, yet! Try this one')
            self.sudoku = self.copySUDOKU(self.exampleSudoku)
        else:
            # ----- fill sudoku array with values from textfile ----- #
            sudokuFile = open(os.getcwd() + "\sudokus\Sudoku%s.txt" % (randint(1, L)))
            row, col = 0, 0
            for value in sudokuFile.read():
                if value.isdigit() or value==' ':
                    self.sudoku[row][col] = value
                    col += 1
                    if col==9:
                        if row==8: break
                        row += 1
                        col = 0
            sudokuFile.close()
        # ----- make values from random sudoku appear in the GUI ----- #
        for row in range(9):
            for col in range(9):
                value = self.sudoku[row][col]
                if value!=' ':
                    self.values[row,col].insert(0,value)

    def printSUDOKU(self, matrix):
        for row in range(9):
            print("|-----------------------------------|")
            for col in range(9):
                print("| " + matrix[row][col] + " ",end='')
            print("|")
        print("|-----------------------------------|")

    def saveSUDOKU(self):
       CHECK = self.checkSUDOKU(self.solution)
       if CHECK[0] and CHECK[1]:    # check if Sudoku is valid and complete
           filecount = 1    # variable for how many sudoku files are already existing
           while os.path.isfile(os.getcwd() + "\sudokus\sudoku%s.txt" % filecount):
               filecount += 1
           sudokuFile = open(os.getcwd() + "\sudokus\sudoku%s.txt" % filecount, 'w')
           solutionFile = open(os.getcwd() + "\sudokus\solution%s.txt" % filecount, 'w')
           # ----- create textfiles for sudoku and the solution ----- #
           for row in range(9):
               for col in range(9):
                   sudokuFile.write(self.sudoku[row][col])
                   solutionFile.write(self.solution[row][col])
               sudokuFile.write('\n')
               solutionFile.write('\n')
           sudokuFile.close()
           solutionFile.close()
           self.message_txt.set('Files saved...')
       else:
           self.message_txt.set('Sudoku must be valid and complete!')

    def copySUDOKU(self, matrix):
        matrix_copy = [[" " for col in range(9)] for row in range(9)]
        for row in range(9):
            for col in range(9):
                matrix_copy[row][col] = matrix[row][col]
        return matrix_copy

    # ----- check if user input makes sense -----#
    def checkSUDOKU(self, matrix):
        valid, complete, ctr = True, True, 0
        for row in range(9):
            for col in range(9):
                value = matrix[row][col]
                if value!=' ':
                    matrix[row][col]=' '
                    if not self.consistent(matrix, row, col, value):
                        valid, complete = False, True
                        return valid, complete, row, col
                    matrix[row][col] = value
                    ctr += 1
                else: complete = False
        if ctr<17: valid = False
        return valid, complete

    # ----- check if solution is valid ----- #
    def checkSOLUTION(self):
        self.getinput(self.sudoku)
        CHECK = self.checkSUDOKU(self.sudoku)
        if CHECK[0] and CHECK[1]: self.message_txt.set("Solution correct!")
        elif not CHECK[1]: self.message_txt.set("Sudoku is not complete!")
        elif not CHECK[0]: self.message_txt.set("Mistake at row %s, col %s"
                                      % (CHECK[2], CHECK[3]))

    # ----- write user input into values{} ----- #
    def getinput(self, matrix):
        for row in range(9):
            for col in range(9):
                value = self.values[row,col].get()
                if value=='': matrix[row][col] = ' '
                elif len(value)!=1: matrix[row][col] = ' '
                elif not value.isdigit(): matrix[row][col] = ' '
                elif int(value)<1 or int(value)>9: matrix[row][col] = ' '
                else : matrix[row][col] = value

    # ----- check if this input leads to a valid solution ----- #
    def consistent(self, matrix, row, col, value):
        for i in range(9):
            if matrix[row][i]==value: return False
            if matrix[i][col]==value: return False
        rowStart = row - row%3
        colStart = col - col%3
        for m in range(3):
            for k in range(3):
                if matrix[rowStart+k][colStart+m]==value: return False
        return True

    def execute_solver(self):
        self.getinput(self.sudoku) # user input from GUI -> sudoku array
        if not self.checkSUDOKU(self.sudoku)[0]:    # check if user input makes sense
            self.message_txt.set("This sudoku does not have a solution")
        else:
            if self.disabled:
                self.message_txt.set("warning, It's still calculating...")
                return
        
            def callback(result):
                self.disabled
                self.disabled = False
                status, self.solution = result
                self.printSUDOKU(self.sudoku)
                self.printSUDOKU(self.solution)
                self.message_txt.set('Solution found!' if status else 'No Solution found!')
                self.fill_solution()

            self.disabled = True
            tk_call_async(self, Solver.do_solve, args=(self.sudoku,),
                      callback=callback, method=MULTIPROCESSING)

    def fill_solution(self):
        for row in range(9):
            for col in range(9):
                self.values[row,col].delete(0,END)
                self.values[row,col].insert(0,self.solution[row][col])
3. the actual solving algorithm
# SudokuSolver_solver.py
def do_solve(sudoku):
    status = wsolve(sudoku)
    return status, sudoku

def consistent(matrix, row, col, value):
    for i in range(9):
        if matrix[row][i]==value: return False
        if matrix[i][col]==value: return False
    rowStart = row - row%3
    colStart = col - col%3
    for m in range(3):
        for k in range(3):
            if matrix[rowStart+k][colStart+m]==value: return False
    return True
 
class SolutionFound(Exception):
    pass
  
def wsolve(sudoku):
    try:
        solve(sudoku, 0)
    except SolutionFound:
        return True
    return False
 
def solve(sudoku, num):
    if num==81:
        raise SolutionFound
        return True
    else:
        row = int(num / 9)
        col = num % 9
        if sudoku[row][col]!=' ':
            solve(sudoku, num+1)
        else:
            for value in range(1,10):
                if consistent(sudoku, row, col, str(value)):
                    sudoku[row][col] = str(value)
                    if solve(sudoku, num+1): return True
                sudoku[row][col]=' '
            return False
  
if __name__ == '__main__':
    printSUDOKU(sudoku)
    solve(sudoku, 0)
4. tkcallasync.py - nothing changed on that code

I am very open to improvement suggestions.
Reply
#19
This is very nice. I had some problems with the paths to the files, because I'm a linux user, so here are a few changes to handle the paths in a platform-independent way. First I change saveSudoku() to
    def saveSUDOKU(self):
       CHECK = self.checkSUDOKU(self.solution)
       if CHECK[0] and CHECK[1]:    # check if Sudoku is valid and complete
           filecount = 1    # variable for how many sudoku files are already existing
           while os.path.isfile(self.path_to("sudoku%s.txt" % filecount)):
               filecount += 1
           sudokuFile = open(self.path_to("sudoku%s.txt" % filecount), 'w')
           solutionFile = open(self.path_to("solution%s.txt" % filecount), 'w')
           # ----- create textfiles for sudoku and the solution ----- #
           for row in range(9):
               for col in range(9):
                   sudokuFile.write(self.sudoku[row][col])
                   solutionFile.write(self.solution[row][col])
               sudokuFile.write('\n')
               solutionFile.write('\n')
           sudokuFile.close()
           solutionFile.close()
           self.message_txt.set('Files saved...')
       else:
           self.message_txt.set('Sudoku must be valid and complete!')
Then at the beginning of the SudokuSolver class
    def __init__(self, parent):
        Frame.__init__(self, parent, name='frame')
        self.parent = parent
        self.initUI()
        self.blankSUDOKU()
        self.sudokudir = os.path.join(os.getcwd(), 'sudokus')
        
    def path_to(self, name):
        return os.path.join(self.sudokudir, name)
You also need to change one line in initSUDOKU()
            sudokuFile = open(self.path_to("sudoku%s.txt" % (randint(1, L))))
The print button does not work, you need to change the callback for this.

I suggest to change SudokuSolver_main like so
# SudokuSolver_main.py
if __name__ == '__main__':
    from tkinter import Tk
    import SudokuSolver_class as Sudokuolver

    def main():
        root = Tk()
        app = Sudokuolver.SudokuSolver(root)
        root.mainloop()
 
    main()
because the child process does not need to import tkinter at all.
Reply
#20
*** UPDATES ***

- save function checks wether sudokufile dir already exists. if not -> makedir
- filepaths should be platform independent
- init function can now handle cases: where there are non sudoku.txt files in the dir, where sudoku.txt file does not contain a valid sudoku
- sudoku.txt files can also use "0" as " "
- progressbar implemented
- print button works
- main function changed the way you suggested

# SudokuSolver_main.py

if __name__ == '__main__':
    import SudokuSolver_class as Sudokuolver
    from tkinter import Tk

    def main():
        root = Tk()
        app = Sudokuolver.SudokuSolver(root)
        root.mainloop()

    main()
# SudokuSolver_class.py

import os
import SudokuSolver_solver as Solver
from random import randint
from tkinter import ttk
from tkinter import *
from tkcallasync import tk_call_async, MULTIPROCESSING


class SudokuSolver(Frame):

    disabled = False
    backtrack_ctr = 0
    sudoku = [[" " for col in range(9)] for row in range(9)]
    solution = [[" " for col in range(9)] for row in range(9)]
    exampleSudoku = [[' ',' ',' ','2','1',' ',' ',' ',' '],
                     [' ',' ','7','3',' ',' ',' ',' ',' '],
                     [' ','5','8',' ',' ',' ',' ',' ',' '],
                     ['4','3',' ',' ',' ',' ',' ',' ',' '],
                     ['2',' ',' ',' ',' ',' ',' ',' ','8'],
                     [' ',' ',' ',' ',' ',' ',' ','7','6'],
                     [' ',' ',' ',' ',' ',' ','2','5',' '],
                     [' ',' ',' ',' ',' ','7','3',' ',' '],
                     [' ',' ',' ',' ','9','8',' ',' ',' ']]

    def __init__(self, parent):
        Frame.__init__(self, parent, name='frame')
        self.parent = parent
        self.initUI()
        self.blankSUDOKU()
        self.sudokudir = os.path.join(os.getcwd(), 'sudokus')

    def initUI(self):
        self.message_txt = StringVar()
        self.values = {}

        self.parent.title('Sudoku Solver')
        self.pack(fill=BOTH, expand=True)

        self.message = Label(self, textvariable=self.message_txt)
        self.message.grid(row=10,column=0,columnspan=9, sticky=E+W)

        self.solveBtn = Button(self, text="solve",width=6,command=self.execute_solver)
        self.solveBtn.grid(row=0,column=0)

        self.newBtn = Button(self, text="new",width=6,command=self.blankSUDOKU)
        self.newBtn.grid(row=0,column=1)

        self.initBtn = Button(self, text="init",width=6,command=self.initSUDOKU)
        self.initBtn.grid(row=0,column=2)

        self.printBtn = Button(self, text="print",width=6,command=self.printALL)
        self.printBtn.grid(row=0,column=8)

        self.checkBtn = Button(self, text="check",width=6,command=self.checkSOLUTION)
        self.checkBtn.grid(row=0,column=6)

        self.saveBtn = Button(self, text="save",width=6,command=self.saveSUDOKU)
        self.saveBtn.grid(row=0,column=7)

        self.pbar = ttk.Progressbar(self, mode='indeterminate')
        self.pbar.grid(row=11,column=0, columnspan=9, sticky=W+E)

    # --- clear all fields and delete all values in sudoku[][] and solution[][] --- #
    def blankSUDOKU(self):
        self.message_txt.set('')
        for row in range(9):
            for col in range(9):
                self.sudoku[row][col] = ' '
                self.solution[row][col] = ' '
                self.numEntry = Entry(self, width=5, justify=CENTER,
                                 font="Helvetica 12 bold")
                self.values[row,col] = self.numEntry
                self.numEntry.grid(row=row+1,column=col, ipady=5)

    # ----- get a random Sudoku from textfiles ----- #
    def initSUDOKU(self):
        self.blankSUDOKU()
        self.message_txt.set('')
        Files = []
        valid = True
        for filename in os.listdir(self.sudokudir):
            if filename.startswith('sudoku') and filename.endswith('.txt'):
                Files.append(filename)
        L = len(Files)
        if L < 1:
            self.message_txt.set('No Sudokus saved, yet! Try this one')
            self.sudoku = self.copySUDOKU(self.exampleSudoku)
        else:
            # ----- fill sudoku array with values from textfile ----- #
            R = randint(0, L-1)
            sudokuFile = open(os.path.join(self.sudokudir,Files[R]))
            row, col = 0, 0
            for value in sudokuFile.read():
                if value.isdigit() or value==' ':
                    if value=='0': value = ' '      # zeros can also be used as blanks
                    self.sudoku[row][col] = value
                    col += 1
                    if col==9:
                        if row==8: break
                        row += 1
                        col = 0
            sudokuFile.close()
            valid = self.checkSUDOKU(self.sudoku)[0]
        if not valid:
            self.message_txt.set('%s does not contain a valid sudoku' % Files[R])
        else:
        # ----- make values from random sudoku appear in the GUI ----- #
            for row in range(9):
                for col in range(9):
                    value = self.sudoku[row][col]
                    if value!=' ':
                        self.values[row,col].insert(0,value)

    def printSUDOKU(self, matrix):
        for row in range(9):
            print("|-----------------------------------|")
            for col in range(9):
                print("| " + matrix[row][col] + " ",end='')
            print("|")
        print("|-----------------------------------|")

    def printALL(self):
        print('Sudoku:')
        self.printSUDOKU(self.sudoku)
        print('Solution:')
        self.printSUDOKU(self.solution)

    def saveSUDOKU(self):
       CHECK = self.checkSUDOKU(self.solution)
       if CHECK[0] and CHECK[1]:    # check if Sudoku is valid and complete
           filecount = 1    # variable for how many sudoku files are already existing
           if not os.path.exists(self.sudokudir): os.makedirs(self.sudokudir)
           while os.path.isfile(self.path_to("sudoku%s.txt" % filecount)):
               filecount += 1
           sudokuFile = open(self.path_to("sudoku%s.txt" % filecount), 'w')
           solutionFile = open(self.path_to("solution%s.txt" % filecount), 'w')
           # ----- create textfiles for sudoku and the solution ----- #
           for row in range(9):
               for col in range(9):
                   sudokuFile.write(self.sudoku[row][col])
                   solutionFile.write(self.solution[row][col])
               sudokuFile.write('\n')
               solutionFile.write('\n')
           sudokuFile.close()
           solutionFile.close()
           self.message_txt.set('Files saved...')
       else:
           self.message_txt.set('Sudoku must be valid and complete!')

    def copySUDOKU(self, matrix):
        matrix_copy = [[" " for col in range(9)] for row in range(9)]
        for row in range(9):
            for col in range(9):
                matrix_copy[row][col] = matrix[row][col]
        return matrix_copy

    # ----- check if user input makes sense -----#
    def checkSUDOKU(self, matrix):
        valid, complete, ctr = True, True, 0
        for row in range(9):
            for col in range(9):
                value = matrix[row][col]
                if value!=' ':
                    matrix[row][col]=' '
                    if not self.consistent(matrix, row, col, value):
                        valid, complete = False, True
                        return valid, complete, row, col
                    matrix[row][col] = value
                    ctr += 1
                else: complete = False
        if ctr<17: valid = False
        return valid, complete

    # ----- check if solution is valid ----- #
    def checkSOLUTION(self):
        self.getinput(self.sudoku)
        CHECK = self.checkSUDOKU(self.sudoku)
        if CHECK[0] and CHECK[1]: self.message_txt.set("Solution correct!")
        elif not CHECK[1]: self.message_txt.set("Sudoku is not complete!")
        elif not CHECK[0]: self.message_txt.set("Mistake at row %s, col %s"
                                      % (CHECK[2], CHECK[3]))

    # ----- write user input into values{} ----- #
    def getinput(self, matrix):
        for row in range(9):
            for col in range(9):
                value = self.values[row,col].get()
                if value=='': matrix[row][col] = ' '
                elif len(value)!=1: matrix[row][col] = ' '
                elif not value.isdigit(): matrix[row][col] = ' '
                elif int(value)<1 or int(value)>9: matrix[row][col] = ' '
                else : matrix[row][col] = value

    # ----- check if this input leads to a valid solution ----- #
    def consistent(self, matrix, row, col, value):
        for i in range(9):
            if matrix[row][i]==value: return False
            if matrix[i][col]==value: return False
        rowStart = row - row%3
        colStart = col - col%3
        for m in range(3):
            for k in range(3):
                if matrix[rowStart+k][colStart+m]==value: return False
        return True

    def path_to(self, name):
        return os.path.join(self.sudokudir, name)

    def execute_solver(self):
        self.getinput(self.sudoku) # user input from GUI -> sudoku array
        if not self.checkSUDOKU(self.sudoku)[0]:    # check if user input makes sense
            self.message_txt.set("This sudoku does not have a solution")
        else:
            if self.disabled:
                self.message_txt.set("warning, It's still calculating...")
                return
        
            def callback(result):
                self.disabled
                self.disabled = False
                status, self.solution = result
                self.pbar.stop()
                self.printSUDOKU(self.sudoku)
                self.printSUDOKU(self.solution)
                self.message_txt.set('Solution found!' if status else 'No Solution found!')
                self.fill_solution()

            self.disabled = True
            self.pbar.start(20)
            tk_call_async(self, Solver.do_solve, args=(self.sudoku,),
                      callback=callback, method=MULTIPROCESSING)

    def fill_solution(self):
        for row in range(9):
            for col in range(9):
                self.values[row,col].delete(0,END)
                self.values[row,col].insert(0,self.solution[row][col])
what I want to do/fix next:
- the "check" button overwrites the original sudoku to the current sudoku. if you press check before save, then the sudoku.txt and the solution.txt file are identical. this should be relativly easy to fix
- implementing a stop button to interrupt the backtracking algorithm. this is probably a bit harder.
- making some kind of .exe file so that someone cand launch the program without using cmd or IDE
- ...
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] TKinter Remove Button Frame Nu2Python 8 1,014 Jan-16-2024, 06:44 PM
Last Post: rob101
  tkinter - touchscreen, push the button like click the mouse John64 5 869 Jan-06-2024, 03:45 PM
Last Post: deanhystad
  Centering and adding a push button to a grid window, TKinter Edward_ 15 4,861 May-25-2023, 07:37 PM
Last Post: deanhystad
  [Tkinter] Clicking on the button crashes the TK window ODOshmockenberg 1 2,252 Mar-10-2022, 05:18 PM
Last Post: deanhystad
  Can't get tkinter button to change color based on changes in data dford 4 3,437 Feb-13-2022, 01:57 PM
Last Post: dford
  Creating a function interrupt button tkinter AnotherSam 2 5,563 Oct-07-2021, 02:56 PM
Last Post: AnotherSam
  [Tkinter] Have tkinter button toggle on and off a continuously running function AnotherSam 5 5,031 Oct-01-2021, 05:00 PM
Last Post: Yoriz
  tkinter showing image in button rwahdan 3 5,649 Jun-16-2021, 06:08 AM
Last Post: Yoriz
  tkinter button image Nick_tkinter 4 4,068 Mar-04-2021, 11:33 PM
Last Post: deanhystad
  tkinter python button position problem Nick_tkinter 3 3,575 Jan-31-2021, 05:15 AM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020