I got another little question...
I want to make multiple variables which I create with 'setattr'
That works quite fine. It creates these variables:
self.sectionButton_1 = Button(text=x)
self.sectionButton_2 = Button(text=x)
self.sectionButton_3 = Button(text=x)
Now I want them to get displayed on the window with tkinter so that this should happen:
self.sectionButton_1.grid(row=i, column=0)
self.sectionButton_2.grid(row=i, column=0)
and so on..
But how do I have to edit the loop that the sectionButtons gonna be created with .grid from tkinter in a loop without writing the above ten times.
# Display Section selection
def checkSection(self):
# Read all sections from config
self.sections = config.sections()
self.sectionsCount = str(len(self.sections))
self.i = 0
self.text = Label(text="Choose Section:" + self.sectionsCount)
self.text.grid(row=1, column=0)
for x in self.sections:
i = +1
setattr(self, 'sectionButton_' + str(i), Button(text=x))
I'm not that good at explaining but hopefully its enough to understand my problem ^^
If not, just comment, I will try to answer it
If you have a group of related variables of the same type and you're doing the same operations to each one then that's a natural place to switch to using a list instead of individual variables.
Your code would become more like:
self.sectionButtons = []
for i, x in enumerate(self.sections):
button = Button(text=x)
button.grid(row=i+1, column=0)
self.sectionButtons.append(button)
This also has the advantage of no longer needing to construct the variable names as strings and use setattr, which is often a sign there's a better way.
So, I am using Tkinter to make a simple Rock-Paper-Scissors game, and when the score is updated to 1 or when the first point is scored the other widgets are moving by some distance. I tried adding and removing padx values but this doesn't change anything. I am still learning so if I can improve the code, please do suggest me.
Thanks.
computer_score=0
score=0
label_score=None
def Rock():
global computer_score,score
option_list=["Rock","Paper","Scissors"]
rand=rint(0,len(option_list)-1)
label_check=Label(root,text=("Computer chose "+option_list[rand]),font=("Helvetica",11,"bold"),bg="white")
label_check.grid(row=4,column=1,pady=5,padx=20,columnspan=2)
if option_list[rand] == button1.cget("text"):
label_res=Label(root,text="It's a Draw, Try again",font=("Helvetica",11,"bold"),bg="white")
label_res.grid(row=5,column=1,pady=5,padx=20,columnspan=2)
elif option_list[rand] == option_list[1] :
computer_score=computer_score+1
label_score=Label(root,text=computer_score,font=("Helvetica",11,"bold"),bg="white")
label_score.grid(row=0,column=0,padx=4)
label_res=Label(root,text="Computer Won, Try again",font=("Helvetica",11,"bold"),bg="white")
label_res.grid(row=5,column=1,pady=5,padx=20,columnspan=2)
else:
score=score+1
label_score=Label(root,text=score,font=("Helvetica",13,"bold"),bg="white")
label_score.grid(row=0,column=3)
label_res=Label(root,text="You won!!, Play again?",font=("Helvetica",11,"bold"),bg="white")
label_res.grid(row=5,column=1,pady=5,padx=20,columnspan=2)
A similar code is for paper and scissors too and when the score is 1, the other widgets are moving away. Their code is also kept below.
button1=Button(root,text="Rock",command=Rock,height =2, width = 8,font=(8))
button1.grid(row=1,column=1,pady=5,padx=20,columnspan=2)
button2=Button(root,text="Paper",command=Paper,height =2, width = 8,font=(8))
button2.grid(row=2,column=1,pady=5,padx=20,columnspan=2)
button3=Button(root,text="Scissors",command=Scissors,height =2, width = 8,font=(8))
button3.grid(row=3,column=1,pady=5,padx=20,columnspan=2)
label1=Label(root,text="Rock Paper Scissors",font=("Comic Sans MS",22,"italic"),bg="white")
label1.grid(row=0,column=1,sticky=W+E,padx=100,pady=(0,5),columnspan=2)
Hope you all understood it, sorry for any mistakes, this is my first time asking and I am still learning how to write clean code.
Thank you.
Edit: Actually, I tried to use a method where the result is decided by just comparing the text on button pressed, so to avoid the hassle of big code but I couldn't get any help, so if anyone can think of such, help with it too.
Basic Idea:
if button_text== randint_ list item:
it is draw
as such, I wanted to do instead of above mentioned whole code for Rock. But I donno how to get the text of the button.
Here's my approach to this, basically have all the labels pre-paced in the window an then use the .config() method on them to change the texts (you can continue with your approach as well). I have predefined the widths of the label, this will prevent them from resizing dynamically as the text in them changes. Here's the modified code:
from tkinter import *
import random
computer_score=0
score=0
label_score=None
def Rock():
global computer_score,score
option_list=["Rock","Paper","Scissors"]
rand=random.randint(0,len(option_list)-1)
label_check.config(text="Computer chose "+option_list[rand])
if option_list[rand] == button1.cget("text"):
label_res.config(text="It's a Draw, Try again")
elif option_list[rand] == option_list[1] :
computer_score=computer_score+1
computer_score_label.config(text=computer_score)
label_res.config(text="Computer Won, Try again")
else:
score=score+1
player_score_label.config(text=score)
label_res.config(text="You won!!, Play again?")
root=Tk()
button1=Button(root,text="Rock",command=Rock,height =2, width = 8,font=(8))
button1.grid(row=1,column=1,pady=5,padx=20,columnspan=2)
#commented since code was unavailble for this part
'''score_frame=Frame(root)
score_frame.grid(row=0,columnspan=5)
score_frame.pack_propagate(False)
button2=Button(root,text="Paper",command=Paper,height =2, width = 8,font=(8))
button2.grid(row=2,column=1,pady=5,padx=20,columnspan=2)
button3=Button(root,text="Scissors",command=Scissors,height =2, width = 8,font=(8))
button3.grid(row=3,column=1,pady=5,padx=20,columnspan=2)'''
computer_score_label=Label(root,font=("Helvetica",11,"bold"),bg="white",width=3)
computer_score_label.grid(row=0,column=0)
player_score_label=Label(root,font=("Helvetica",11,"bold"),bg="white",width=3)
player_score_label.grid(row=0,column=3)
label_res=Label(root,font=("Helvetica",11,"bold"),bg="white")
label_res.grid(row=5,column=1,pady=5,padx=20,columnspan=2)
label_check=Label(root,font=("Helvetica",11,"bold"),bg="white")
label_check.grid(row=4,column=1,pady=5,padx=20,columnspan=2)
label1=Label(root,text="Rock Paper Scissors",font=("Comic Sans MS",22,"italic"),bg="white")
label1.grid(row=0,column=1,sticky=W+E,padx=100,pady=(0,5),columnspan=2)
root.mainloop()
I am learning python. I am not new to programming, so this is frustrating and a little embarrassing too: I I want to check if the random number is 20 - and if it is, change the background color. If I change comparison to != it works. But I cannot seem to check for a value. I tried making the result a string/int as random generates a float. Any ideas..?
The code follows:
import random
import tkinter as tk
temp_result = 0
pickedColor = ""
def d20roll():
temp_result = random.randint(1, 20) # generates a float
lbl_result["text"] = str(temp_result) # makes the float a string for display
print(temp_result) #shows me the result
if temp_result == 20:# if the rnd is 20, make the color red.
pickedColor = "red"
else:
pickedColor = "black"
window = tk.Tk()
window.columnconfigure(0, minsize=150)
window.rowconfigure([0, 1], minsize=50)
frame = tk.Frame(
master=window,
relief=tk.RAISED,
borderwidth=2)
frame.grid(row=0, column=0, padx=2,pady=2)
btn_d20roll = tk.Button(master=frame, text="D20 Roll", command=d20roll)
lbl_result = tk.Label(fg="white", bg=pickedColor)
btn_d20roll.grid(row=0, column=0, sticky="nsew")
lbl_result.grid(row=1, column=0)
window.mainloop() '''
You're setting the value of temp_result inside a function, and testing that value outside of that function. Without diving too far in your code, I see 2 problems with that:
At the moment you test the value of temp_result, the function has not been called yet. The value of temp_result is therefore still the initial value.
When you assign to a variable inside of a function, Python considers that variable local to the function and no change will be visible outside of the function. You could change that by using global temp_result in the function, but it's generally not recommended to communicate values from inside a function to outside of it. It's better to return a value instead.
You're going to have to arrange your code so that a button press will result in:
a random number being generated
that random number being compared to some value
and the background color being set to some value based on that
I'm not familiar with Tkinter so I can't really help with that.
I've had this problem for a while where my quiz won't work, where certain tkinter windows wouldn't close even though the code was there. However, after speaking to my teacher, he said that it was possible to read my text file to get the questions and answers, then place them in a list so that I could randomly select them to be displayed in the window (That way no question appears twice). He then said that you could have the window refresh after each question is answered, putting a different question up with different answers (Maybe even a "Correct"/"Wrong" inbetween each question). If anyone has an idea how to do ths is would be a massive help. Thanks.
def quiz_easy():
global question
questions = []
correctanswers = []
possibleanswer1s = []
possibleanswer2s = []
possibleanswer3s = []
easy_questions = open("sup.txt", "r")
count = 1
for line in easy_questions:
if count == 1:
questions.append(line.rstrip())
elif count == 2:
correctanswers.append(line.rstrip())
elif count == 3:
possibleanswer1s.append(line.rstrip())
elif count == 4:
possibleanswer2s.append(line.rstrip())
elif count == 5:
possibleanswer3s.append(line.rstrip())
if count == 5:
count = 1
else:
count = count + 1
print(questions)
print (correctanswers)
randno1 = random.randint(0,len(questions)-1)
master = Tk()
text = Text(master)
text.insert(INSERT, questions[randno1])
text.insert(END, "?")
text.pack()
text.tag_add("here","5.0", "1.4")
text.tag_add("start", "1.8", "1.13")
Think OOP intead of sequencial
Your Quiz should be a class.
Avoiding MVC approach, stay simple the class directly handle the UI, the data and the process.
The constructor read the question file and update your internal data representation (That may be reworked too), and start the Root Tk instance
Create a method to display the question (a Label) and the area dedicated to the answer (an Entry)
Add a button "OK" or bind the key on the Entry widget to start a method dedicated to the control of the answer and displaying of the correct answer
Create this method
Add a method for the Tkinter mainloop
In the main of the script instanciate the quizz, call the method "display a question" and then call the method for mainloop()
We are waiting for your code ;-) to assist
tips: 1: Prefer:
import Tkinter as tk # instead of from Tkinter import * to keep your code explicit.
2: Forget the global directive in your code .. non sense here
3: the file reading is rought, the format of your file is not optimised.
to not going too quickly in XML paradygm ..
think about prefix ruler
QUE translate pig in french
COR cochon
ALT proc
ALT truie
ALT verrat
ALT porcelet
ALT cochonet
ALT gorret
ALT nourrin
ALT nourrain
ALT cochette
for each line you just append a possible answer in a list of possible answers
Ready to run your brain ... go. ^^
I wrote my first py code. This code to create a lotto number generator.The problem is that my variable nums will not change. Please help me.
I understand this is not as good as it can be so please tell me how to improve, any comments will be appreciated.I wanted the random numbers to come up in the ladle so i could press the submit button and 5 new numbers to come up.The problem is my veritable "nums" wont change.Thank you for helping.
import random
from tkinter import *
#TK()
window = Tk()
window.title("Lottery Nummber Generator")
#Def Click
def click():
global nums
global numsgen
numsgen = random.sample(range(1, 49), 5)
nums = " ".join(str(x) for x in numsgen)
print(nums)
numsgen = random.sample(range(1, 49), 5)
nums = " ".join(str(x) for x in numsgen)
#Fake just to make it look nice
Label(window,text="").grid(row=1, column=0,sticky=W)
Label(window,text="").grid(row=2, column=1,sticky=W)
Label(window,text="").grid(row=2, column=3,sticky=W)
#Submit button
Button(window, text="Submit", width=5,command=click).grid(row=3, column=1, sticky=W)
#Label
group = LabelFrame(window, text="Lottery Numbers:", padx=5, pady=5,fg="dark orange")
group.pack(padx=10, pady=10,)
group.grid(row=2, column=1,sticky=W)
w = Label(group, text=nums)
w.pack()
mainloop()
To get a label to update, you must do one of two things:
Associate a StringVar with the label. When you update the variable (via its set method), any labels associated with it will automatically change. This is a great solution if more than one widget needs to display the same value.
Directly configure the label. This requires that you save a reference to the widget(s) so that you can later reconfigure them. For example, you could put w.configure(text=nums) in your click function. This solution is a bit simpler than using a StringVar, simply because it requires one less object.