Adding scrollbar widget to Tkinter GUI results in errors - python

I have written the following code to get the user input. But I am not able to add a scrollbar to it. I want to place a vertical scrollbar because I am not able to view all the input labels on my screen.
I first tried:
v = Scrollbar(root, orient='vertical')
v.config(command=root.yview)
It gave me the following error:
File "/Users/aaditya/Desktop/Blender_software/Blender_algo_exp/testing.py", line 235, in <module>
label1.grid(row = 1, column = 0, padx = 10, pady = 10)
File "/opt/anaconda3/envs/blender_env/lib/python3.9/tkinter/__init__.py", line 2486, in grid_configure
self.tk.call(
_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack
After that I tried the following:
myscroll = Scrollbar(root)
myscroll.pack(side = RIGHT, fill = Y)
Which resulted in the following error:
AttributeError: '_tkinter.tkapp' object has no attribute 'yview'
How can I fix this?
This is my entire code:
# Driver code
if __name__ == "__main__" :
root = Tk()
# v = Scrollbar(root, orient='vertical')
# v.config(command=root.yview)
# myscroll = Scrollbar(root)
# myscroll.pack(side = RIGHT, fill = Y)
root.configure(background = 'light gray')
root.geometry("700x700")
root.title("Blender Software")
label1 = Label(root, text = "Total Quantity: ",
fg = 'black', bg = 'white')
label2 = Label(root, text = "Percentage of Solid Scrap : ",
fg = 'black', bg = 'white')
label3 = Label(root, text = "Cr min : ",
fg = 'black', bg = 'white')
label4 = Label(root, text = "Cr max : ",
fg = 'black', bg = 'white')
label1.grid(row = 1, column = 0, padx = 10, pady = 10)
label2.grid(row = 2, column = 0, padx = 10, pady = 10)
label3.grid(row = 3, column = 0, padx = 10, pady = 10)
label4.grid(row = 4, column = 0, padx = 10, pady = 10)
# Create a entry box
# for filling or typing the information.
total_quantity = Entry(root)
per_solid_scrap = Entry(root)
Cr_min_input = Entry(root)
Cr_max_input = Entry(root)
# grid method is used for placing
# the widgets at respective positions
# in table like structure .
total_quantity.grid(row = 1, column = 1, padx = 10, pady = 10)
per_solid_scrap.grid(row = 2, column = 1, padx = 10, pady = 10)
Cr_min_input.grid(row = 3, column = 1, padx = 10, pady = 10)
Cr_max_input.grid(row = 4, column = 1, padx = 10, pady = 10)
button1 = Button(root, text = "Submit", bg = "red",
fg = "black", command = calculate_op)
button1.grid(row = 21, column = 1, pady = 10)
# Start the GUI
root.mainloop()

Pack and grid cannot be used at the same time. So since you called the pack for the scrollbar, you cannot manage the following widgets by grid anymore. An easy fix is to place the scrollbar with grid function instead. Apart from that, try using a function or class to make your code less lengthy because now it seems hard to read and purposeless.

Related

best way to make a text box that will show text

I am new to Python and am using Tkinter to create a basic GUI for a game.
I have got some buttons an image and numerous labels to work, but I am wondering..
What is the best way to get a large, initially blank text box on the GUI, and how would I go about having the text box update on the press of a "next" button.
I need it to scroll through text with each press, showing the next relevant line.
The text that is shown will depend on the choice(s) that are made, so variables like current location etc are necessary.
The aim is to make a simple game that allows you to read through the text with the Next button, then make choices etc, a mostly text-based adventure game.
I'll post what I have already below. Yes I know it's terrible, this is my first try so don't judge too harshly on my mistakes.
Any tips, advice or methods are much appreciated.
Some things to note:
My quit button isn't working yet, not too sure why.
I would love to figure out how to store variables based on what the user inputs, via an input box that can be prompted when an input is required from the user.
Also, happy to start from scratch if it's easier.
# Widgets:
import sys #Imports the system commands which makes it possible to terminate the program
import time #Imports the time module to allow delays in script
import os #Imports os to make it possible to play music/sound
import random #Imports random variable to allow for random number generation
import pickle #allows the game state to be saved.
from tkinter import * # imports tkinter
import tkinter as tk
from tkinter import *
from tkinter import messagebox
from textwrap import wrap # imports text wrap
#base variables for testing
character_Gold = 1
character_Health = 100
character_base_Health = 100
character_Strength = 10
character_Dexterity = 10
character_Constitution = 10
character_Intelligence = 10
character_Wisdom = 10
character_Charisma = 10
character_base_Perception = 10
#Text Boxes
#Base Geometry and image
window = Tk()
TitleScreen = PhotoImage( file = 'test.gif' )
window.geometry("1100x600")
#defines
def close():
#win.destroy()
window.quit()
imgLbl = Label( window, image = TitleScreen )
label1 = Label( window, relief = 'groove', width = 4)
label2 = Label( window, relief = 'groove', width = 4)
label3 = Label( window, relief = 'groove', width = 4)
label4 = Label( window, relief = 'groove', width = 4)
label5 = Label( window, relief = 'groove', width = 4)
label6 = Label( window, relief = 'groove', width = 4)
label7 = Label( window, relief = 'groove', width = 4)
label8 = Label( window, relief = 'groove', width = 4)
label9 = Label( window, relief = 'groove' , width = 3)
label10 = Label( window, relief = 'groove' , width = 3)
label11 = Label( window, relief = 'groove' , width = 3)
label12 = Label( window, relief = 'groove' , width = 3)
label13 = Label( window, relief = 'groove' , width = 3)
label14 = Label( window, relief = 'groove' , width = 3)
label15 = Label( window, relief = 'groove' , width = 3)
label16 = Label( window, relief = 'groove' , width = 3)
TextLabel = Label( window, relief = 'groove', width = 50)
LocationLabel = Label( window, relief = 'groove', width = 18)
LocationBase = Label( window, relief = 'groove', width = 13)
NextBtn = Button( window )
MainText = Label( window, relief = 'groove', width = 40, height = 8)
QuitButton = Button(window, text="Quit",command=close)
# Geometry:
imgLbl.grid( row = 1, column = 1 , rowspan = 24 ) # Change Rowspan here to increase number of Rows and shrink gaps
label1.grid( row = 1, column = 2, padx = 10 )
label2.grid( row = 1, column = 4, padx = 10 )
label3.grid( row = 1, column = 5, padx = 10 )
label4.grid( row = 1, column = 6, padx = 10 )
label5.grid( row = 1, column = 7, padx = 10 )
label6.grid( row = 1, column = 8, padx = 10)
label7.grid( row = 1, column = 9, padx = 10)
label8.grid( row = 1, column = 10, padx = 5)
label9.grid( row = 2, column = 2, padx = (1, 10)) #Health
label10.grid(row = 2, column = 4, padx = 10) #STR
label11.grid(row = 2, column = 5, padx = 10) # DEX
label12.grid(row = 2, column = 6, padx = 10) # CON
label13.grid(row = 2, column = 7, padx = 10) #INT
label14.grid(row = 2, column = 8, padx = 10) #WIS
label15.grid(row = 2, column = 9, padx = 10) # CHA
label16.grid(row = 2, column = 10, padx= 10) # gold
TextLabel.grid( row = 26, column = 1, padx = 10) # instruction label
LocationLabel.grid( row = 2, column = 11, padx = 10) # dynamic location label, changes
LocationBase.grid( row = 1, column = 11, padx = 10) # location text only not dynamic
MainText.grid( row = 30, column = 1, padx = 10) # main text box
QuitButton.grid(row = 34, column = 14 , padx = 10) #Quit Button
NextBtn.grid( row = 26, column = 2, columnspan = 4 )
# Static Properties
window.title( ' The Adventure ')
NextBtn.configure( text = 'Next')
Current_Location = "Title Screen"
#DynamicProperties. BD is button facelift level, bg is colour.
label1.configure( text = 'HP:', bg = 'Red' )
label1.configure( bd = 8, relief=RAISED)
label2.configure( text = 'STR:', bg = 'Orange')
label2.configure( bd = 8, relief=RAISED)
label3.configure( text = 'DEX:', bg = 'Purple')
label3.configure( bd = 8, relief=RAISED)
label4.configure( text = 'CON:', bg = 'Green')
label4.configure( bd = 8, relief=RAISED)
label5.configure( text = 'INT:', bg = 'light green')
label5.configure( bd = 8, relief=RAISED)
label6.configure( text = 'WIS:', bg = 'white')
label6.configure( bd = 8, relief=RAISED)
label7.configure( text = 'CHA:', bg = 'light blue')
label7.configure( bd = 8, relief=RAISED)
label8.configure( text = 'GP:', bg = 'yellow')
label8.configure( bd = 8, relief=RAISED)
label9.configure( text = character_Health)
label9.configure( bd = 6, relief=RAISED)
label10.configure( text = character_Strength)
label10.configure( bd = 6, relief=RAISED)
label11.configure( text = character_Dexterity)
label11.configure( bd = 6, relief=RAISED)
label12.configure( text = character_Constitution)
label12.configure( bd = 6, relief=RAISED)
label13.configure( text = character_Intelligence)
label13.configure( bd = 6, relief=RAISED)
label14.configure( text = character_Wisdom)
label14.configure( bd = 6, relief=RAISED)
label15.configure( text = character_Charisma)
label15.configure( bd = 6, relief=RAISED)
label16.configure( text = character_Gold)
LocationLabel.configure( text = Current_Location, fg = 'White', bg = 'Black')
LocationLabel.configure( bd = 8, relief=RAISED) # raises the button up to look 3d
LocationBase.configure( text = "Your Location:", fg = "black", bg = "White") #"location" text above tab that changes actual location
LocationBase.configure( bd = 8, relief=RAISED)
TextLabel.configure( text = "Welcome To The Adventure. Click 'Next' to begin!") # instruction label
TextLabel.configure( bd = 2, relief=RAISED)
MainText.configure( text = '''This is the large box where \n the main game text should go.''', fg = "Black", bg = "White") # use \n for a NEWLINE
MainText.configure( bd = 10, relief=RAISED)
NextBtn.configure( bd = 8, relief=RAISED) # raises next button
QuitButton.configure( bd = 2, relief=RAISED, text="Quit",command=close)
#Sustain Window:
window.mainloop()

Checkbutton is not clickable after adding an image to it

I started working with tkinter recently and I have the following problem, I need to make the check box bigger but that is only possible with adding an image. The problem is that whenever I add an image to a button it becomes unclickable and the image is not displayed, here is my source code (part of a bigger project). My goal is to display some information and let the user decide which option he gets to keep using the check button. Any help is appreciated.
import tkinter as tk
import tkcalendar as tkc
LARGE_FONT = ("HELVETICA", 32, 'bold')
NORMAL_FONT = ("calibri", 18)
class ConstituireDosar(tk.Toplevel):
def __init__(self, controller):
tk.Toplevel.__init__(self)
self.update_idletasks()
# self.dosar = dosar
self.controller = controller
self.minsize(651, 569)
# self.maxsize(651, 569)
frame_titlu = tk.Frame(self)
frame_titlu.grid(row = 0, column = 0)
frame_continut = tk.Frame(self)
frame_continut.grid(row = 1, column = 0, sticky = "w")
frame_acte = tk.Frame(self)
frame_acte.grid(row = 2, column = 0)
titlu = tk.Label(frame_titlu, font = LARGE_FONT, text = "Constituire Dosar")
titlu.grid(row = 0 , column = 0, padx = 10, pady = 15)
data_emiterii = tk.Label(frame_continut, font = NORMAL_FONT,text = "Data emiterii documentului:")
data_emiterii.grid(row = 1, column = 0, padx = 10, pady = 5, sticky = "w")
self.cal = tkc.DateEntry(frame_continut, date_pattern = "DD/MM/YYYY", width = 20)
self.cal.grid(row = 2, column = 0, padx = 10, pady = 5, sticky = "w")
debitori_label = tk.Label(frame_continut, font = NORMAL_FONT, text = "Selecteaza debitorii.")
debitori_label.grid(row = 3, column = 0, padx = 10, pady = 5, sticky = "w")
debitori = []
tip_debitori = []
for i in range(2):
debitori.append("Person %s " % str(i))
tip_debitori.append("Person %s type" % str(i))
for i in range(len(debitori)):
print(debitori[i])
row_i = 4
self.vars_debitori = []
on_image = tk.PhotoImage(width=48, height=24)
off_image = tk.PhotoImage(width=48, height=24)
on_image.put(("green",), to=(0, 0, 23,23))
off_image.put(("red",), to=(24, 0, 47, 23))
for i in range(len(debitori)):
var = tk.IntVar(frame_continut, value = 0)
interior = debitori[i] + " - " + tip_debitori[i]
# Checkbutton(ws, image=switch_off, selectimage=switch_on, onvalue=1, offvalue=0, variable=cb1, indicatoron=False, command=switchState)
checkbuton = tk.Checkbutton (frame_continut, bd = 5, image = off_image, selectimage = on_image, indicatoron = False, onvalue = 1, offvalue = 0, variable = var, state = tk.ACTIVE, command = lambda: self.toggle(var))
checkbuton.grid(row = row_i, column = 0, padx = 20, pady = 5, sticky = "nw")
checkbuton.image = off_image
# checkbuton.select()
self.vars_debitori.append(var)
row_i += 1
self.vars_acte = []
acte = ["Acte de Procedura", "Incheiere de Admitere", "Cerere de Incuviintare", "Instiintare Creditor"]
for i in range(4):
v = tk.IntVar()
check = tk.Checkbutton(frame_acte, font = NORMAL_FONT, text = acte[i], variable = v)
check.grid(row = row_i, column = 0, padx = 10, pady = 5)
check.select()
self.vars_acte.append(v)
row_i += 1
emite_acte = tk.Button(frame_acte, font = NORMAL_FONT, text = "Emite acte.", command = self.emite_acte)
emite_acte.grid(row = row_i, column = 1, padx = 15, pady = 30, ipadx = 70, ipady = 10)
emite_acte.configure(bg = '#218838', fg = '#FFFFFF')
buton_cancel = tk.Button(frame_acte, font = NORMAL_FONT, text = "Cancel", command = lambda: self.destroy())
buton_cancel.grid(row = row_i, column = 0, padx = 15, pady = 30, ipadx = 70, ipady = 10)
buton_cancel.configure(bg = "red", fg = '#FFFFFF')
def emite_acte(self):
print(self.cal.get_date().strftime("%d/%m/%y"))
print(self.winfo_height(), self.winfo_width())
if __name__ == "__main__":
root = tk.Tk()
app = ConstituireDosar(root)
app.protocol("WM_DELETE_WINDOW", root.destroy)
root.withdraw()
root.mainloop()
I tried some options that I saw on the forum, in another file they worked fine but when I tried to implement it in the project itself the checkbutton is still unclickable and it doesn't display the images either. tkinter checkbutton different image I tried to replicate Bryan's answer, but no luck there. Also didn't receive any console error message.
As #furas pointed in the comments above, the problem got fixed with keeping the images as member variables of the class, also the button became clickable after removing the self.toggle(var) command from checkbutton

TypeError: Iniciar() missing 1 required positional argument: 'data' and failed append

Im trying to append the input numbers to my array data everytime I click the button "agregar", however it seems like it only appends the value i just inserted and completely forgets about the previous append. I don't get any error messaged with that one. Also, when I click "iniciar" it should draw ovals with the values in data but I get the error
TypeError: Iniciar() missing 1 required positional argument: 'data'
I'm not sure what I'm doing wrong and would appreciate it if anyone could help.
from tkinter import *
from tkinter import ttk
from array import *
import random
tk = Tk()
tk.title('Bubble Sort')
tk.maxsize(900, 600)
tk.config(bg = 'black')
#Variables
algoritmo = StringVar()
#comandos
def dibujar(data):
c.delete("all")
cHeight = 380
cWidth = 600
#para escalar
algoWidth = cWidth / (len(data) + 1)
algoHeight = cWidth / (len(data) + 1)
offset = 20
spacing = 10
tamData = [i / max(data) for i in data]
for i, height in enumerate(tamData):
#top left
x0 = i * algoWidth + offset + spacing
y0 = cHeight - height * 50
#botom right
x1 = (i+1) * algoWidth + offset
y1 = cHeight
c.create_oval(x0,y0,x1,y1, fill = 'red')
c.create_text(x0+2,y0, anchor = SW, text=str(data[i]))
def Iniciar(data):
print("Se selecciono: " + algoritmo.get())
dibujar(a)
def agregar():
data = array('i', [1, 3, 5, 7, 9])
input = int(inputVal.get())
data.append((input))
print("valor input:")
print(input)
print(str(data))
def limpiar():
c.delete("all")
#Frame
box = Frame(tk, width = 600, height = 200, bg = 'black' )
box.grid(row = 0, column = 0, padx=10, pady=5)
c = Canvas(tk, width = 600, height = 380, bg = 'grey')
c.grid(row = 1, column = 0, padx=10, pady=5)
#UI
#Row-0
label = Label(box, text='Lista Algoritmos: ', font = ("Arial",15), borderwidth=1, bg = "black" , fg = 'white')
label.grid(row=0,column=0, padx=5, pady=5, sticky = W)
menu = ttk.Combobox(box, textvariable = algoritmo, values=['BUBBLE SORT', 'MERGE SORT', 'HASH TABLES', 'ARBOL AVL', 'ARBOLES ROJO Y NEGRO'])
menu.grid(row=0, column=1, padx=5, pady=5)
menu.current(0)
botonStart = Button(box, text = 'Iniciar', command = Iniciar, bg = 'lime green')
botonStart.grid(row = 0, column = 2, padx = 5, pady = 5)
#Row-1
label = Label(box, text='Insertar valor: ', font = ("Arial",15), borderwidth=1, bg = "black" , fg = 'white')
label.grid(row=1,column=0, padx = 5, pady = 5, sticky = W)
inputVal = Entry(box)
inputVal.grid(row=1,column=1, padx = 5, pady = 5, sticky = W)
botonAdd = Button(box, text = 'Agregar', command = agregar, bg = 'lime green')
botonAdd.grid(row = 1, column = 2, padx = 5, pady = 5, sticky = W)
botonClear = Button(box, text = 'Limpiar', command = limpiar, bg = 'lime green')
botonClear.grid(row = 1, column = 3, padx = 5, pady = 5, sticky = W)
tk.mainloop()
You are defining Iniciar here:
def Iniciar(data):
print("Se selecciono: " + algoritmo.get())
dibujar(a)
But when you call it below you aren't passing a data argument to it
botonStart = Button(box, text = 'Iniciar', command = Iniciar, bg = 'lime green')

Tkinter: Irregular spacing for widgets in frames using grid columns

I am attempting to create a relatively simple survey like form in Tkinter, and I'm relatively new to the GUI framework. I'm having real issues trying to figure out why there are so many inconsistencies, especially when working with grid placement+frames+multiple widgets in same row. Especially this specific example. I'm tying together all my questions into a single frame, and it seems to work out... sort of half. Though the rows seem to cooperate nicely, the columns are where the whole thing gets erupted.
qframe1 = Frame(question, bg='black')
qframe1.grid(row=1, padx = 20, sticky = W)
q1l = Label(qframe1, text = 'Question 1: How often do you eat at Mcdonalds?', font = ('Calibri', 14), bg = 'azure')
q1l.grid(columnspan = 4, pady = 5, sticky = W)
q1 = StringVar()
q1.set('None')
q1r1 = Radiobutton(qframe1, text = 'Everyday!', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Always')
q1r1.grid(row=1, column = 0, pady = 5, sticky = W)
q1r2 = Radiobutton(qframe1, text = 'Sometimes', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Sometimes')
q1r2.grid(row=1, column = 1, pady = 5, sticky = W)
q1r3 = Radiobutton(qframe1, text = 'Not Frequently', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Infrequent')
q1r3.grid(row=1, column = 2, pady = 5, sticky = W)
q1r4 = Radiobutton(qframe1, text = 'Never', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Never')
q1r4.grid(row=1, column = 3, pady = 5, sticky = W)
This is the bare code for the section that's messing up.
Also, I have made sure that it's not the length of each radio button that is causing the issue. When I change the text of the radio buttons, they still get placed in the same irregular positions.
Here's the code for another section of the trivia.
q2l = Label(qframe1, text = 'Question 2: What meal do you normally order?', font = ('Calibri', 14), bg = 'azure')
q2l.grid(row=2, columnspan = 4, pady = 5, sticky = W)
q2 = StringVar()
q2.set('None')
q2r1 = Radiobutton(qframe1, text = 'Fries', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Fries')
q2r1.grid(row=3, column = 0, pady = 5, sticky = W)
q2r2 = Radiobutton(qframe1, text = 'Hamburgers', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Hamburgers')
q2r2.grid(row=3, column = 1, pady = 5, sticky = W)
q2r3 = Radiobutton(qframe1, text = 'Chicken Nuggets', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Chicken Nuggets')
q2r3.grid(row=3, column = 2, pady = 5, sticky = W)
q2r4 = Radiobutton(qframe1, text = 'Coffee', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Coffee')
q2r4.grid(row=3, column = 3, pady = 5, sticky = W)
This again causes an irregular spacing. But this time, the spacing is completely different from the radio buttons in question 1. And rinse and repeat with every new question set of radio buttons.
There are no issues with the buttons on the right side. Perhaps it's because they're aligned in rows and not columns which are causing the spacing issue.
bframe = Frame(question, bg='black')
bframe.grid(row=1, padx = 20, sticky = E)
audioq1 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q1audio)
audioq1.grid(ipadx = 5, pady = 20)
audioq2 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q2audio)
audioq2.grid(row = 1, ipadx = 5, pady = 20)
audioq3 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q3audio)
audioq3.grid(row = 2, ipadx = 5, pady = 20)
audioq4 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q4audio)
audioq4.grid(row = 3, ipadx = 5, pady = 20)
audioq5 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q5audio)
audioq5.grid(row = 4, ipadx = 5, pady = 20)
Any help would be greatly appreciated!
If, as mentioned in the comments, "weight isn't necessarily the problem", the placement of the radiobuttons can be realized using pack instead of grid.
This gives something like this (on a mac):
If you want a more evenly placed buttons to fill the available width, you can achieve this with grid:
I also rewrote a portion of the code to make it easier to add questions to the form. Each question is now in its own frame, allowing for more flexibility.
import tkinter as tk
class QFrame(tk.Frame):
id = 1
def __init__(self, master, question):
self.master = master
super().__init__(self.master)
self.id = QFrame.id
QFrame.id += 1
self.q = tk.StringVar()
self.q.set('None')
self.question, self.choices = question
self.q_label = tk.Label(self, text=f'Question {self.id}: {self.question}')
self.q_label.pack(expand=True, anchor=tk.W)
self.choose = []
for idx, choice in enumerate(self.choices):
txt, value = choice
qr = tk.Radiobutton(self, text=txt, variable=self.q, value=value)
self.choose.append(qr)
qr.pack(side=tk.LEFT)
class App(tk.Tk):
def __init__(self, questions):
self.questions = questions
super().__init__()
for question in questions:
self.qframe = QFrame(self, question)
self.qframe.pack(fill=tk.X)
q1 = ['How often do you eat at Mcdonalds?',
(('Everyday!', 'Always'),
('Sometimes', 'Sometimes'),
('Not Frequently', 'Infrequent'),
('Never', 'Never'))]
q2 = ['What meal do you normally order?',
(('Fries!', 'Fries'),
('Hamburgers', 'Hamburgers'),
('Chicken Nuggets', 'Chicken Nuggets'),
('Coffee', 'Coffee'))]
q3 = ['how large is your usual party?',
(('alone!', 'alone'),
('two', 'two'),
('less than 5', 'less than 5'),
('5 or more', '5 or more'))]
questions = [q1, q2, q3]
app = App(questions)
app.mainloop()
The code for grid geometry manager:
class QFrame(tk.Frame):
id = 1
def __init__(self, master, question):
self.master = master
super().__init__(self.master)
self.id = QFrame.id
QFrame.id += 1
self.q = tk.StringVar()
self.q.set('None')
self.question, self.choices = question
self.grid_rowconfigure(0, weight=1)
for idx in range(4):
self.grid_columnconfigure(idx, weight=1)
self.q_label = tk.Label(self, text=f'Question {self.id}: {self.question}')
self.q_label.grid(row=0, column=0, columnspan=4, sticky="w")
self.choose = []
for idx, choice in enumerate(self.choices):
txt, value = choice
qr = tk.Radiobutton(self, text=txt, variable=self.q, value=value)
self.choose.append(qr)
qr.grid(row=1, column=idx, columnspan=1, sticky="ew")

Python GUI only shows one label instead of two

So I'm making a game and I was wondering why the num of rows/columns show one instead of showing both. When I comment one out, the other shows and vice versa instead of both showing.
class OthelloGUI():
def __init__(self):
self._root_window = tkinter.Tk()
self._root_window.title('Othello')
self.read_row()
self.read_column()
def read_row(self) -> int:
self.row_text =tkinter.StringVar()
self.row_text.set('Num of rows:')
row_label = tkinter.Label(
master = self._root_window, textvariable = self.row_text,
background = 'yellow', height = 1, width = 10, font = DEFAULT_FONT)
row_label.grid(row=1, column = 0, padx = 10, pady=10, sticky = tkinter.W+tkinter.N)
return self.row.get()
def read_column(self) -> int:
self.column_text =tkinter.StringVar()
self.column_text.set('Num of columns:')
column_label = tkinter.Label(
master = self._root_window, textvariable = self.column_text,
background = 'yellow', height = 1, width = 13, font = DEFAULT_FONT)
column_label.grid(row=1, column = 0, padx = 10, pady=50, sticky = tkinter.W+tkinter.N)
return self.column.get()
You are calling grid with the same coordinates:
row_label.grid(row=1, column = 0, padx = 10, pady=10, sticky = tkinter.W+tkinter.N)
column_label.grid(row=1, column = 0, padx = 10, pady=50, sticky = tkinter.W+tkinter.N)
When you grid both at (1, 0), the second one will override the first. Instead, use different row/column arguments:
row_label.grid(row=1, column = 0, padx = 10, pady=10, sticky = tkinter.W+tkinter.N)
column_label.grid(row=2, column = 0, padx = 10, pady=50, sticky = tkinter.W+tkinter.N)
Of course, set the row/column to whatever you want in your interface.

Categories