ttk buttons in python dict reference to the same object, generation problem?
I'm really confused about the problem I'm facing. I've spent some time trying to aisle the problem as much as I can, and here it is:
Im working with tkinter and ttk, and I want to create a grid of buttons, just like in this code:(Taken from https://www.edureka.co/community/1539/tkinter-grid-overlapping-issue)
TL;DR: Just a working calendar that has a button per day in a grid
from calendar import *
import datetime
try:
from tkinter import * # Python 3.x
except:
from Tkinter import * # Python 2.x
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid(row=0, column=0, sticky='news')
DateNow = datetime.datetime.now()
month = int(DateNow.month)
year = int(DateNow.year)
self.createDaysOfWeekLabels()
month_name = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
# Create frames and button controls for previous, current and next month.
self.frameList = # List that contains the frame objects.
self.buttonList = # List that contains the button objects.
amonth = month - 1
for i in range(3):
if amonth < 0:
amonth = 11
year -= 1
elif amonth == 12:
amonth = 1
year += 1
mFrame = Frame(self)
self.createMonth(mFrame, amonth, year)
self.frameList.append(mFrame)
mButton = Button(self, text=month_name[amonth-1])
mButton['command'] = lambda f=mFrame, b=mButton: self.showMonth(f, b)
mButton.grid(row=0, column=i)
# Grid each frame
mFrame.grid(row=2, column=0, columnspan=7, sticky='news')
if (i == 1):
mButton['relief'] = 'flat'
else:
# Remove all but the ith frame. More efficient to remove than forget and configuration is remembered.
mFrame.grid_remove()
self.buttonList.append(mButton)
amonth += 1
# Create year widget at top left of top frame
label = Label(self, text=year)#displaying year
label.grid(row=0, column=6)
def createDaysOfWeekLabels(self):
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
for i in range(7):
label = Label(self, text=days[i])
label.grid(row = 1, column = i)
def showMonth(self, mFrame, mButton):
# Display all buttons normally
for button in self.buttonList:
button['relief'] = 'raised'
# Set this month's button relief to flat
mButton['relief'] = 'flat'
# Hide all frames
for frame in self.frameList:
frame.grid_remove()
mFrame.grid()
def createMonth(self, mFrame, month, year):
weekday, numDays = monthrange(year, month)
week = 0
for i in range(1, numDays + 1):
button = Button(mFrame, text = str(i), width=3)
button.grid(row = week, column = weekday)
weekday += 1
if weekday > 6:
week += 1
weekday = 0
mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()
then I tried to do something similar but using a dictionary whose key is a coordinate tuple and the value is the button(which has a frame as a parent), like this:
coords = {(0, 0):ttk.Button(self.frame_p1g), (0, 1): ttk.Button(self.frame_p1g)}
I just used this same dict for my grid, and this code down here, and it works perfectly:
x = 2
for i in coords.values():
i.grid(row=x, column=2)
x += 1
Image of the result
But as soon as I use a simple function to generate a grid automatically, and then place it in the grid, it doesn't work:
def make(width, height, element):
grid = {}
for y in range(height):
for x in range(width):
print ("X: " + str(x))
print ("Y: " + str(y))
grid[x, y] = element
return grid
Image with result
I tried to find the cause, but the only thing I could find was that the function seems to create exact same buttons, and somehow when I try to place them, every button gets the same row and column config:
Dict print from working dict
Dict print from bugged list
And this is the code that places each button(just pretty similar to the other, just using the lengh of the dict to know where to place them)
self.p1g = make(int(self.size[0]), int(self.size[1]), ttk.Button(self.frame_p1g))
print(self.p1g)
x = 2
y = 2
for butt in self.p1g.values():
butt.grid(row=y, column=x)
x += 1
if x > (list(self.p1g.keys())[-1][0]):
x = 2
y += 1
The question: How can I make it work with a dict?(I really need those coordinates to reference the buttons)
python-3.x dictionary tkinter ttk
add a comment |
I'm really confused about the problem I'm facing. I've spent some time trying to aisle the problem as much as I can, and here it is:
Im working with tkinter and ttk, and I want to create a grid of buttons, just like in this code:(Taken from https://www.edureka.co/community/1539/tkinter-grid-overlapping-issue)
TL;DR: Just a working calendar that has a button per day in a grid
from calendar import *
import datetime
try:
from tkinter import * # Python 3.x
except:
from Tkinter import * # Python 2.x
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid(row=0, column=0, sticky='news')
DateNow = datetime.datetime.now()
month = int(DateNow.month)
year = int(DateNow.year)
self.createDaysOfWeekLabels()
month_name = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
# Create frames and button controls for previous, current and next month.
self.frameList = # List that contains the frame objects.
self.buttonList = # List that contains the button objects.
amonth = month - 1
for i in range(3):
if amonth < 0:
amonth = 11
year -= 1
elif amonth == 12:
amonth = 1
year += 1
mFrame = Frame(self)
self.createMonth(mFrame, amonth, year)
self.frameList.append(mFrame)
mButton = Button(self, text=month_name[amonth-1])
mButton['command'] = lambda f=mFrame, b=mButton: self.showMonth(f, b)
mButton.grid(row=0, column=i)
# Grid each frame
mFrame.grid(row=2, column=0, columnspan=7, sticky='news')
if (i == 1):
mButton['relief'] = 'flat'
else:
# Remove all but the ith frame. More efficient to remove than forget and configuration is remembered.
mFrame.grid_remove()
self.buttonList.append(mButton)
amonth += 1
# Create year widget at top left of top frame
label = Label(self, text=year)#displaying year
label.grid(row=0, column=6)
def createDaysOfWeekLabels(self):
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
for i in range(7):
label = Label(self, text=days[i])
label.grid(row = 1, column = i)
def showMonth(self, mFrame, mButton):
# Display all buttons normally
for button in self.buttonList:
button['relief'] = 'raised'
# Set this month's button relief to flat
mButton['relief'] = 'flat'
# Hide all frames
for frame in self.frameList:
frame.grid_remove()
mFrame.grid()
def createMonth(self, mFrame, month, year):
weekday, numDays = monthrange(year, month)
week = 0
for i in range(1, numDays + 1):
button = Button(mFrame, text = str(i), width=3)
button.grid(row = week, column = weekday)
weekday += 1
if weekday > 6:
week += 1
weekday = 0
mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()
then I tried to do something similar but using a dictionary whose key is a coordinate tuple and the value is the button(which has a frame as a parent), like this:
coords = {(0, 0):ttk.Button(self.frame_p1g), (0, 1): ttk.Button(self.frame_p1g)}
I just used this same dict for my grid, and this code down here, and it works perfectly:
x = 2
for i in coords.values():
i.grid(row=x, column=2)
x += 1
Image of the result
But as soon as I use a simple function to generate a grid automatically, and then place it in the grid, it doesn't work:
def make(width, height, element):
grid = {}
for y in range(height):
for x in range(width):
print ("X: " + str(x))
print ("Y: " + str(y))
grid[x, y] = element
return grid
Image with result
I tried to find the cause, but the only thing I could find was that the function seems to create exact same buttons, and somehow when I try to place them, every button gets the same row and column config:
Dict print from working dict
Dict print from bugged list
And this is the code that places each button(just pretty similar to the other, just using the lengh of the dict to know where to place them)
self.p1g = make(int(self.size[0]), int(self.size[1]), ttk.Button(self.frame_p1g))
print(self.p1g)
x = 2
y = 2
for butt in self.p1g.values():
butt.grid(row=y, column=x)
x += 1
if x > (list(self.p1g.keys())[-1][0]):
x = 2
y += 1
The question: How can I make it work with a dict?(I really need those coordinates to reference the buttons)
python-3.x dictionary tkinter ttk
2
I recommend by starting with a single function that creates the grid and does nothing else. You've posted too much extra code that isn't relevant to the question being asked, which makes it hard to read and understand. It's important to narrow the code down to the smallest Minimal, Complete, and Verifiable example possible.
– Bryan Oakley
Nov 21 '18 at 3:37
It references to the same object becausemake
function operates on only oneelement
, hence one element has one set of coordinates at a time. Is there a problem with creating buttons inside of themake
instead of passing one? Looks like someone's inattention or I missed something.
– CommonSense
Nov 21 '18 at 8:03
add a comment |
I'm really confused about the problem I'm facing. I've spent some time trying to aisle the problem as much as I can, and here it is:
Im working with tkinter and ttk, and I want to create a grid of buttons, just like in this code:(Taken from https://www.edureka.co/community/1539/tkinter-grid-overlapping-issue)
TL;DR: Just a working calendar that has a button per day in a grid
from calendar import *
import datetime
try:
from tkinter import * # Python 3.x
except:
from Tkinter import * # Python 2.x
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid(row=0, column=0, sticky='news')
DateNow = datetime.datetime.now()
month = int(DateNow.month)
year = int(DateNow.year)
self.createDaysOfWeekLabels()
month_name = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
# Create frames and button controls for previous, current and next month.
self.frameList = # List that contains the frame objects.
self.buttonList = # List that contains the button objects.
amonth = month - 1
for i in range(3):
if amonth < 0:
amonth = 11
year -= 1
elif amonth == 12:
amonth = 1
year += 1
mFrame = Frame(self)
self.createMonth(mFrame, amonth, year)
self.frameList.append(mFrame)
mButton = Button(self, text=month_name[amonth-1])
mButton['command'] = lambda f=mFrame, b=mButton: self.showMonth(f, b)
mButton.grid(row=0, column=i)
# Grid each frame
mFrame.grid(row=2, column=0, columnspan=7, sticky='news')
if (i == 1):
mButton['relief'] = 'flat'
else:
# Remove all but the ith frame. More efficient to remove than forget and configuration is remembered.
mFrame.grid_remove()
self.buttonList.append(mButton)
amonth += 1
# Create year widget at top left of top frame
label = Label(self, text=year)#displaying year
label.grid(row=0, column=6)
def createDaysOfWeekLabels(self):
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
for i in range(7):
label = Label(self, text=days[i])
label.grid(row = 1, column = i)
def showMonth(self, mFrame, mButton):
# Display all buttons normally
for button in self.buttonList:
button['relief'] = 'raised'
# Set this month's button relief to flat
mButton['relief'] = 'flat'
# Hide all frames
for frame in self.frameList:
frame.grid_remove()
mFrame.grid()
def createMonth(self, mFrame, month, year):
weekday, numDays = monthrange(year, month)
week = 0
for i in range(1, numDays + 1):
button = Button(mFrame, text = str(i), width=3)
button.grid(row = week, column = weekday)
weekday += 1
if weekday > 6:
week += 1
weekday = 0
mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()
then I tried to do something similar but using a dictionary whose key is a coordinate tuple and the value is the button(which has a frame as a parent), like this:
coords = {(0, 0):ttk.Button(self.frame_p1g), (0, 1): ttk.Button(self.frame_p1g)}
I just used this same dict for my grid, and this code down here, and it works perfectly:
x = 2
for i in coords.values():
i.grid(row=x, column=2)
x += 1
Image of the result
But as soon as I use a simple function to generate a grid automatically, and then place it in the grid, it doesn't work:
def make(width, height, element):
grid = {}
for y in range(height):
for x in range(width):
print ("X: " + str(x))
print ("Y: " + str(y))
grid[x, y] = element
return grid
Image with result
I tried to find the cause, but the only thing I could find was that the function seems to create exact same buttons, and somehow when I try to place them, every button gets the same row and column config:
Dict print from working dict
Dict print from bugged list
And this is the code that places each button(just pretty similar to the other, just using the lengh of the dict to know where to place them)
self.p1g = make(int(self.size[0]), int(self.size[1]), ttk.Button(self.frame_p1g))
print(self.p1g)
x = 2
y = 2
for butt in self.p1g.values():
butt.grid(row=y, column=x)
x += 1
if x > (list(self.p1g.keys())[-1][0]):
x = 2
y += 1
The question: How can I make it work with a dict?(I really need those coordinates to reference the buttons)
python-3.x dictionary tkinter ttk
I'm really confused about the problem I'm facing. I've spent some time trying to aisle the problem as much as I can, and here it is:
Im working with tkinter and ttk, and I want to create a grid of buttons, just like in this code:(Taken from https://www.edureka.co/community/1539/tkinter-grid-overlapping-issue)
TL;DR: Just a working calendar that has a button per day in a grid
from calendar import *
import datetime
try:
from tkinter import * # Python 3.x
except:
from Tkinter import * # Python 2.x
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid(row=0, column=0, sticky='news')
DateNow = datetime.datetime.now()
month = int(DateNow.month)
year = int(DateNow.year)
self.createDaysOfWeekLabels()
month_name = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
# Create frames and button controls for previous, current and next month.
self.frameList = # List that contains the frame objects.
self.buttonList = # List that contains the button objects.
amonth = month - 1
for i in range(3):
if amonth < 0:
amonth = 11
year -= 1
elif amonth == 12:
amonth = 1
year += 1
mFrame = Frame(self)
self.createMonth(mFrame, amonth, year)
self.frameList.append(mFrame)
mButton = Button(self, text=month_name[amonth-1])
mButton['command'] = lambda f=mFrame, b=mButton: self.showMonth(f, b)
mButton.grid(row=0, column=i)
# Grid each frame
mFrame.grid(row=2, column=0, columnspan=7, sticky='news')
if (i == 1):
mButton['relief'] = 'flat'
else:
# Remove all but the ith frame. More efficient to remove than forget and configuration is remembered.
mFrame.grid_remove()
self.buttonList.append(mButton)
amonth += 1
# Create year widget at top left of top frame
label = Label(self, text=year)#displaying year
label.grid(row=0, column=6)
def createDaysOfWeekLabels(self):
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
for i in range(7):
label = Label(self, text=days[i])
label.grid(row = 1, column = i)
def showMonth(self, mFrame, mButton):
# Display all buttons normally
for button in self.buttonList:
button['relief'] = 'raised'
# Set this month's button relief to flat
mButton['relief'] = 'flat'
# Hide all frames
for frame in self.frameList:
frame.grid_remove()
mFrame.grid()
def createMonth(self, mFrame, month, year):
weekday, numDays = monthrange(year, month)
week = 0
for i in range(1, numDays + 1):
button = Button(mFrame, text = str(i), width=3)
button.grid(row = week, column = weekday)
weekday += 1
if weekday > 6:
week += 1
weekday = 0
mainWindow = Tk()
obj = Application(mainWindow)
mainWindow.mainloop()
then I tried to do something similar but using a dictionary whose key is a coordinate tuple and the value is the button(which has a frame as a parent), like this:
coords = {(0, 0):ttk.Button(self.frame_p1g), (0, 1): ttk.Button(self.frame_p1g)}
I just used this same dict for my grid, and this code down here, and it works perfectly:
x = 2
for i in coords.values():
i.grid(row=x, column=2)
x += 1
Image of the result
But as soon as I use a simple function to generate a grid automatically, and then place it in the grid, it doesn't work:
def make(width, height, element):
grid = {}
for y in range(height):
for x in range(width):
print ("X: " + str(x))
print ("Y: " + str(y))
grid[x, y] = element
return grid
Image with result
I tried to find the cause, but the only thing I could find was that the function seems to create exact same buttons, and somehow when I try to place them, every button gets the same row and column config:
Dict print from working dict
Dict print from bugged list
And this is the code that places each button(just pretty similar to the other, just using the lengh of the dict to know where to place them)
self.p1g = make(int(self.size[0]), int(self.size[1]), ttk.Button(self.frame_p1g))
print(self.p1g)
x = 2
y = 2
for butt in self.p1g.values():
butt.grid(row=y, column=x)
x += 1
if x > (list(self.p1g.keys())[-1][0]):
x = 2
y += 1
The question: How can I make it work with a dict?(I really need those coordinates to reference the buttons)
python-3.x dictionary tkinter ttk
python-3.x dictionary tkinter ttk
asked Nov 21 '18 at 3:23
Carlos HidalgoCarlos Hidalgo
611
611
2
I recommend by starting with a single function that creates the grid and does nothing else. You've posted too much extra code that isn't relevant to the question being asked, which makes it hard to read and understand. It's important to narrow the code down to the smallest Minimal, Complete, and Verifiable example possible.
– Bryan Oakley
Nov 21 '18 at 3:37
It references to the same object becausemake
function operates on only oneelement
, hence one element has one set of coordinates at a time. Is there a problem with creating buttons inside of themake
instead of passing one? Looks like someone's inattention or I missed something.
– CommonSense
Nov 21 '18 at 8:03
add a comment |
2
I recommend by starting with a single function that creates the grid and does nothing else. You've posted too much extra code that isn't relevant to the question being asked, which makes it hard to read and understand. It's important to narrow the code down to the smallest Minimal, Complete, and Verifiable example possible.
– Bryan Oakley
Nov 21 '18 at 3:37
It references to the same object becausemake
function operates on only oneelement
, hence one element has one set of coordinates at a time. Is there a problem with creating buttons inside of themake
instead of passing one? Looks like someone's inattention or I missed something.
– CommonSense
Nov 21 '18 at 8:03
2
2
I recommend by starting with a single function that creates the grid and does nothing else. You've posted too much extra code that isn't relevant to the question being asked, which makes it hard to read and understand. It's important to narrow the code down to the smallest Minimal, Complete, and Verifiable example possible.
– Bryan Oakley
Nov 21 '18 at 3:37
I recommend by starting with a single function that creates the grid and does nothing else. You've posted too much extra code that isn't relevant to the question being asked, which makes it hard to read and understand. It's important to narrow the code down to the smallest Minimal, Complete, and Verifiable example possible.
– Bryan Oakley
Nov 21 '18 at 3:37
It references to the same object because
make
function operates on only one element
, hence one element has one set of coordinates at a time. Is there a problem with creating buttons inside of the make
instead of passing one? Looks like someone's inattention or I missed something.– CommonSense
Nov 21 '18 at 8:03
It references to the same object because
make
function operates on only one element
, hence one element has one set of coordinates at a time. Is there a problem with creating buttons inside of the make
instead of passing one? Looks like someone's inattention or I missed something.– CommonSense
Nov 21 '18 at 8:03
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404821%2fttk-buttons-in-python-dict-reference-to-the-same-object-generation-problem%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404821%2fttk-buttons-in-python-dict-reference-to-the-same-object-generation-problem%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
I recommend by starting with a single function that creates the grid and does nothing else. You've posted too much extra code that isn't relevant to the question being asked, which makes it hard to read and understand. It's important to narrow the code down to the smallest Minimal, Complete, and Verifiable example possible.
– Bryan Oakley
Nov 21 '18 at 3:37
It references to the same object because
make
function operates on only oneelement
, hence one element has one set of coordinates at a time. Is there a problem with creating buttons inside of themake
instead of passing one? Looks like someone's inattention or I missed something.– CommonSense
Nov 21 '18 at 8:03