Theta56
Theta56

Reputation: 1

I can't change the background of the tkinter canvas in python

Despite using the config() method, my canvas's background color won't change. I've made sure the if statement is correct by using some print statements, I've done some research and this is the only way to change the color of an existing canvas- google search results for how to change the canvas background color

screenshot of program when executed (the canvas is the white thing with the question text, the score is a label, the check mark and X buttons are buttons, and I've used the grid() methods to make them display)

In addition, after browsing some old questions, one of the potential causes for this was that a new canvas was being created after each iteration, and since I've defined the cavas in the innit() method, this isn't the case.

So what exactly should I do?

QuizBrain Class-

import html


class QuizBrain:

def __init__(self, q_list):
    self.question_number = 0
    self.score = 0
    self.question_list = q_list
    self.current_question = None

def still_has_questions(self):
    return self.question_number < len(self.question_list)

def next_question(self):
    self.current_question = self.question_list[self.question_number]
    self.question_number += 1
    q_text = html.unescape(self.current_question.text)
    return f"Q.{self.question_number}: {q_text}"

def check_answer(self, user_answer):
    correct_answer = self.current_question.answer
    if user_answer.lower() == correct_answer.lower():
        self.score += 1
        return True
    else:
        return False

QuizInterface Class- look at the def give_feedback(self, is_right: bool) method, it's responsible for changing the canvas background which tells the user if they got it right(green) or wrong(red). I've also shared the other classes (above and below) for context and incase the problem is there.

from tkinter import *
from quiz_brain import QuizBrain
THEME_COLOR = "#375362"


class QuizInterface:

def __init__(self, quiz_brain: QuizBrain):
    self.quiz = quiz_brain

    self.window = Tk()
    self.window.config(background=THEME_COLOR, padx=20, pady=20)
    self.window.title("Quiz")

    self.score_label = Label(text="score: 0", font=("Arial", 20, "italic"), padx=20, pady=20, bg=THEME_COLOR,
                             fg="white")
    self.score_label.grid(row=0, column=1)

    self.canvas = Canvas(width=300, height=250, background="white")
    self.question_text = self.canvas.create_text(150, 125, text="SAMPLE",
                                                 font=("Arial", 20, "italic"), fill="black", width=250)
    self.canvas.grid(column=0, row=1, columnspan=2, pady=40)

    true_image = PhotoImage(file="images/true.png")
    false_image = PhotoImage(file="images/false.png")

    self.true_button = Button(image=true_image, command=self.true_pressed)
    self.true_button.grid(row=2, column=0)

    self.false_button = Button(image=false_image, command=self.false_pressed)
    self.false_button.grid(row=2, column=1)

    self.get_next_question()

    self.window.mainloop()

def get_next_question(self):
    question_text = self.quiz.next_question()
    self.canvas.itemconfig(self.question_text, text=question_text)

def true_pressed(self):
    is_right = self.quiz.check_answer("True")
    self.give_feedback(is_right)

def false_pressed(self):
    is_right = self.quiz.check_answer("False")
    self.give_feedback(is_right)

def give_feedback(self, is_right: bool):
    print("Called")
    if is_right:
        print("Called-2")
        self.canvas.configure(bg="green")
        print("Executed")
    elif not is_right:
        print("called-3")
        self.canvas.configure(bg="red")
        print("Executed")

    self.window.after(3000, self.get_next_question)
    self.canvas.config(background="white")

Question Class-

class Question:

def __init__(self, q_text, q_answer):
    self.text = q_text
    self.answer = q_answer

How I get my questions-

import requests

parameters = {
    "amount": 10,
    "type": "boolean"
}

quiz_data = requests.get(url="https://opentdb.com/api.php", params=parameters)

quiz_data.raise_for_status()
quiz_questions = quiz_data.json()

question_data = quiz_questions["results"]

Main.py-

from question_model import Question
from data import question_data
from quiz_brain import QuizBrain
from ui import QuizInterface

question_bank = []
for question in question_data:
    question_text = question["question"]
    question_answer = question["correct_answer"]
    new_question = Question(question_text, question_answer)
    question_bank.append(new_question)


quiz = QuizBrain(question_bank)
quiz_interface = QuizInterface(quiz)

#
# while quiz.still_has_questions():
#     quiz.next_question()
#
# print("You've completed the quiz")
# print(f"Your final score was: {quiz.score}/{quiz.question_number}")

Upvotes: 0

Views: 1072

Answers (4)

Robert_Alex
Robert_Alex

Reputation: 1

You have to add self.canvas.update() right after each color change.

def get_next_question(self):
    q_text = self.quiz.next_question()
    self.canvas.itemconfig(self.question_text, text=q_text)
    self.canvas.config(bg="white")

def true_pressed(self):
    is_right = self.quiz.check_answer("true")
    self.give_feedback(is_right)

def false_pressed(self):
    is_right = self.quiz.check_answer("false")
    self.give_feedback(is_right)

def give_feedback(self, is_right: bool):
    print(is_right)
    if is_right:
        self.canvas.config(bg="green")
        self.canvas.update()
    else:
        self.canvas.config(bg="red")
        self.canvas.update()
    self.window.after(1000, self.get_next_question())

Upvotes: 0

navalega0109
navalega0109

Reputation: 392

In your code self.canvas.config(bg="white") will never get executed. Put it inside the get_next_question method.

Upvotes: 0

Ruan
Ruan

Reputation: 1

I think we are doing the same course, i had the same issue on this part. You just need to update the screen:

def give_feedback(self, is_right: bool):
if is_right:
    self.canvas.configure(bg="green")
elif not is_right:
    self.canvas.configure(bg="red")
self.canvas.update()
self.window.after(3000, self.get_next_question)

And put the self.canvas.config(bg="white") into the get_next_question(self) method:

def get_next_question(self):
self.canvas.config(background="white")
question_text = self.quiz.next_question()
self.canvas.itemconfig(self.question_text, text=question_text)

Upvotes: 0

yes72002
yes72002

Reputation: 1

Move the line

self.canvas.config(background="white")

from give_feedback function to get_next_question function.

Upvotes: 0

Related Questions