Cannot make a label wider - python

I have this reproducible code, and I cannot understand why when I set the width value to 100 in the self.display_tcm_18 variable, it still does not increase its width. This self.display_tcm_18 lies within the self.xf Frame, which I set to a width value of 300 (wide enough to host a Label widget of 100). I don't know what I am missing in the Logic of building this GUI with tkinter. Does anyone could give me some hint?
import Tkinter
from Tkinter import *
import tkFileDialog
from tkFileDialog import askopenfilename
from tkFileDialog import askdirectory
class Window(Frame):
def __init__(self, master = None):
self.master = master
path = "logo.gif"
self.image = Tkinter.PhotoImage(file=path)
self.f = Frame(master, width=300, height =70)
self.sf = Frame(master, width=300, height=70)
self.xf = Frame(self.f,width = 300, relief=GROOVE, borderwidth = 2)
self.file_name_18 = ''
self.var = IntVar()
def browse_button():
filename = askopenfilename(filetypes = (("GEOTIFF Files", "*.tif"),))
self.file_name = filename
self.display.config(text = filename)
print(self.file_name)
self.Logo = Label(self.master, image = self.image).pack(side=TOP, padx=5)
self.open_tcm_button = Button(self.xf, text = "Open..", command = browse_button).pack(side=LEFT, padx = 5, pady = 10)
self.display_tcm_18 = Label(self.xf, width = 100, bg = "white", textvariable = self.file_name_18, relief = SUNKEN, anchor = W)
self.display_tcm_18.pack(side=LEFT)
self.tcm18_label = Label(self.f, text = "Tree Cover Mask 2018 ").place(relx=0.06, rely=0.125,anchor=W)
self.xf.place(relx=0.01, rely=0.125, anchor=NW)
self.f.pack(side=TOP)
root = Tk()
root.geometry("600x400")
app = Window(root)
root.mainloop()

Related

How do I proceed with the rest of the function to keep updating my message box in tkinter?

I am trying to do a message box to warns the user in my UI that they will be moved to the homepage after 10 seconds, codes are as following:
from tkinter import *
import warnings
import random
import time
import sqlite3
from tkinter import simpledialog
from tkinter import messagebox
from tkcalendar import *
from tkinter import ttk
import math
from PIL import Image, ImageTk
import winsound
##-------------Frames setup--------------------------
class VendingApp(Tk):
def __init__(self):
Tk.__init__(self)
self._frame = None
self.switch_frame(Home)
def switch_frame(self, frame_class):
#Destroys current frame and replaces it with a new one.
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
####-----------------------Home page---------------------------
class Home(Frame):
def __init__(self, master):
Frame.__init__(self, master)
##-----------------------fuctions-----------------------------------
def clicked(a):
if (a.x <=1920) and (a.y<=1080):
master.switch_frame(Store)
print ("1")
else:
None
None
##----------------setup------------------------------------------
self._images = list()
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((400,100), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
self._images.append(banner)
##---------------------Top frame Home------------------------------------
topFrame = Frame(self,width = 1920, height = 1080)
topFrame.pack()
canvasM = Canvas(topFrame,height=1080, width=1920)
canvasM['highlightthickness'] = 0
canvasM.pack()
body = canvasM.create_rectangle(0, 0,1920,1080, fill = 'gray95')
mylabel = canvasM.create_text((960, 390),font=("Purisa", 40), text="Touch anywhere to continue")
canvasM.tag_bind(body,"<Button>",clicked)
canvasM.tag_bind(mylabel,"<Button>",clicked)
#-------------------------Store page--------------------------------------------------------------
class Store(Frame):
def __init__(self, master):
Frame.__init__(self, master)
def timeset():
global time
time = 15
def active(event):
global time
time = 15
print (time)
def timeout():
global time
if time >= 10:
time -= 1
master.after(1000, timeout)
elif time <= 10 and time > 0:
askuser()
time -= 1
master.after(1000, timeout)
elif time <= 0:
master.switch_frame(Home)
print(time)
def askuser():
ask = messagebox.showinfo('Are you there?','Returning to home page in ' + (str(time)) + ' seconds. \n please touch the screen to continue using the app')
self._images = list()
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((400, 100), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
self._images.append(banner)
##---------------------pictures and filters Store------------------------------------
PicFrame = Frame(self, width=400, height=100)
PicFrame.grid(row = 0, column = 0)
PicFrame.grid_propagate(False)
canvas_for_banner = Canvas(PicFrame, height=100, width=400 ) # banner image
canvas_for_banner.pack(anchor = N)
canvas_for_banner['highlightthickness'] = 0
canvas_for_banner.grid_propagate(False)
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)
##---------------------------------Midd store-------------------
FilterFrame =Frame(self, width=400, height=930, relief = RAISED, bd =1)
FilterFrame.grid(row = 1, column = 0)
FilterFrame.pack_propagate(0)
Ava_title = Label(FilterFrame, text = "Availability", font = ('Helvetica', 20, 'bold'))
Ava_title.pack(pady = (100,0))
self.stock_yes = IntVar()
self.stock_no = IntVar()
check_ava = Checkbutton(FilterFrame, text = 'Avaliable', variable = self.stock_yes, font = 20, command = None)
check_ava.pack( anchor = 'w', padx = 30, pady =10)
check_unava = Checkbutton(FilterFrame, text = 'Unavaliable', font = 20, variable = self.stock_no, command = None)
check_unava.pack(anchor = 'w', padx = 30, pady = 10)
gend_title = Label(FilterFrame, text = "Gender", font = ('Helvetica', 20, 'bold'))
gend_title.pack(pady = (30,0))
self.boi = IntVar()
self.girl = IntVar()
check_boi = Checkbutton(FilterFrame, text = 'Male', font = 20, variable = self.boi)
check_boi.pack( anchor = 'w', padx = 30, pady = 10)
cehck_girl = Checkbutton(FilterFrame, text = 'Female', font = 20, variable = self.girl)
cehck_girl.pack(anchor = 'w', padx = 30, pady =10)
Class_title = Label(FilterFrame, text = "Uniform class", font = ('Helvetica', 20, 'bold'))
Class_title.pack(pady = (30,0))
self.formal = IntVar()
self.sport = IntVar()
check_formal = Checkbutton(FilterFrame, text = 'Formal', font = 20, variable = self.formal)
check_formal.pack( anchor = 'w', padx = 30, pady =10)
check_sport = Checkbutton(FilterFrame, text = 'Sport', font = 20, variable = self.sport)
check_sport.pack(anchor = 'w', padx = 30, pady =10)
type_title = Label(FilterFrame, text = "Type", font = ('Helvetica', 20, 'bold'))
type_title.pack(pady = (30,0))
self.shirts = IntVar()
self.pants = IntVar()
self.misc = IntVar()
check_shirts = Checkbutton(FilterFrame, text = 'Shirts', font = 20, variable = self.shirts)
check_shirts.pack( anchor = 'w', padx = 30, pady =10)
check_pants = Checkbutton(FilterFrame, text = 'Pants', font = 20, variable = self.pants)
check_pants.pack(anchor = 'w', padx = 30, pady =10)
check_misc = Checkbutton(FilterFrame, text = 'Misc', font = 20, variable = self.misc)
check_misc.pack(anchor = 'w', padx = 30, pady =10)
##------------------------\\\\\\\\\\\\\\\\\\\\\\---------------------------------------------
MidFrame = Frame(self,width = 1520, height = 1030, relief = SUNKEN, bd = 2)
MidFrame.grid(row = 0, column = 1, rowspan = 2)
MidFrame.grid_propagate(False)
store_canvas = Canvas(MidFrame, width = 1520, height = 1030)
store_canvas.pack()
store_canvas.pack_propagate(0)
frames = []
frame_order = []
num = 1
for x in range(4):
frames.append([])
for y in range(4):
frames[x].append(0)
for x in range(4):
for y in range(4):
frames[x][y] = Frame(store_canvas, width=1520 / 4, height=1030 / 4, bd = 2, relief = SOLID)
frames[x][y].grid(row=y, column=x)
frames[x][y].pack_propagate(False)
frame_order.append(frames[x][y])
for frame in frame_order:
Label(frame, text=num, anchor='nw').pack( side = 'left')
num += 1
##------------------------\\\\\\\\\\\\\\\\\\\\\\---------------------------------------------
BottomFrame = Frame(self,width = 1920, height = 50, bd = 2, relief = RAISED)
BottomFrame.grid(row = 2, column =0, columnspan = 2)
BottomFrame.pack_propagate(False)
help_btn = Button(BottomFrame, width = 5, height = 3, text = '?', image = None)
help_btn.pack(side = 'right')
master.bind("<Button>",active)
timeset()
timeout()
#----------------------------------------------------------------------------------------
if __name__ == "__main__":
root = VendingApp()
#Renames the TITLE of the window
root.title("Vending machine")
root.geometry("1920x1080")
root.attributes('-fullscreen', True)
root.resizable(False, False)
root.mainloop()
The problem is that the whole program 'freezes' every time the msg box pop up and unless the user confirms 'ok' then the function will pick up where it left off. Is there any way to keep the function going, hence the number in the msg box will update according to the time remaining? Am I approaching this problem the wrong way? Is there another module for this all along and I am just using the wrong module for the task? Please go easy on me, I am still learning. All responses all much appreciated.
messagebox will pause the further execution until it receives an input. To prevent this you can try the following
Use threading
from tkinter import *
from tkinter import messagebox
from threading import Thread
def msgbox():
def _display():
messagebox.showinfo('Info','Self distruction after 2 seconds')
Thread(target=_display).start()
root.after(2000,root.destroy)
root=Tk()
button=Button(root,text='Run',command=msgbox)
button.pack()
root.mainloop()
Create your own info box using Toplevel (the below example will create a replica (sort of) of standard windows info box)
from tkinter import *
import tkinter.ttk as ttk
class InfoBox(Toplevel):
def __init__(self,title,message,parent=None):
Toplevel.__init__(self,parent)
self.bell()
self.transient(self.master)
self.title(title)
self.config(bg='white')
top_frame=Frame(self,bd=0,bg=self['bg'])
top_frame.pack(side='top',fill='x',pady=20)
bottom_frame=Frame(self,bd=0)
bottom_frame.pack(side='bottom',fill='x')
self.info_icon=Canvas(top_frame,width=36,height=36
,bg=self['bg'],bd=0,highlightthickness=0)
self.info_icon.create_oval(0,0,30,30,fill='#0077be',outline='#0077be')
self.info_icon.create_text(15,16,text='i',font=('',18),fill='white')
self.info_icon.pack(side='left',padx=(20,0),anchor='center')
self.label=Label(top_frame,text=message,bg=self['bg'])
self.label.pack(padx=(1,20),pady=5,anchor='center')
self.ok_button=ttk.Button(bottom_frame,text='OK',
state='active',command=self.destroy)
self.ok_button.pack(anchor='e',padx=15,pady=10)
self.update()
center_x=self.winfo_screenwidth()//2-self.winfo_width()//2
center_y=self.winfo_screenheight()//2-self.winfo_height()//2
self.geometry(f'+{center_x}+{center_y}')
def msgbox():
InfoBox('Info','Self distruction after 2 seconds')
root.after(2000,root.destroy)
root=Tk()
button=Button(root,text='Run',command=msgbox)
button.pack()
root.mainloop()
UPDATE
Stacking is automatically prevented
from tkinter import *
import tkinter.ttk as ttk
class InfoBox(Toplevel):
def __init__(self):
self.exists=False
def call(self,title,message,parent=None):
if self.exists:
self._destroy()
Toplevel.__init__(self,parent)
self.bell()
self.transient(self.master)
self.title(title)
self.config(bg='white')
top_frame=Frame(self,bd=0,bg=self['bg'])
top_frame.pack(side='top',fill='x',pady=20)
bottom_frame=Frame(self,bd=0)
bottom_frame.pack(side='bottom',fill='x')
self.info_icon=Canvas(top_frame,width=36,height=36
,bg=self['bg'],bd=0,highlightthickness=0)
self.info_icon.create_oval(0,0,30,30,fill='#0077be',outline='#0077be')
self.info_icon.create_text(15,16,text='i',font=('',18),fill='white')
self.info_icon.pack(side='left',padx=(20,0),anchor='center')
self.label=Label(top_frame,text=message,bg=self['bg'])
self.label.pack(padx=(1,20),pady=5,anchor='center')
self.ok_button=ttk.Button(bottom_frame,text='OK',
state='active',command=self._destroy)
self.ok_button.pack(anchor='e',padx=15,pady=10)
self.update()
center_x=self.winfo_screenwidth()//2-self.winfo_width()//2
center_y=self.winfo_screenheight()//2-self.winfo_height()//2
self.geometry(f'+{center_x}+{center_y}')
self.protocol('WM_DELETE_WINDOW',self._destroy)
self.exists=True
def _destroy(self):
self.destroy()
self.exists=False
root=Tk()
infobox=InfoBox()
button=Button(root,text='Hello',command=lambda:infobox.call('Info','Hello'))
button.pack()
button1=Button(root,text='World',command=lambda:infobox.call('Info','World'))
button1.pack()
root.mainloop()

Create another window in tkinter class

I have made "sticky notes" in python but how do I make the same open in another window when I press the new File (+ on the title bar) button? I thought of creating an object within the class but I don't think that's possible. Should I import and run similar file? Please suggest a method to do so. Suggestions to improve the code are welcomed.
Here's the code
from tkinter import *
import tkinter.scrolledtext as tkst
from tkinter import messagebox
from tkinter import font
class StickyNotes:
xclick = 0
yclick = 0
def __init__(self,master):
def get_pos(event):
self.xclick = event.x
self.yclick = event.y
def move_window(event):
master.geometry('+{0}+{1}'.format(event.x_root-self.xclick, event.y_root-self.yclick))
def another_window(event):
pass
def quit_window(event):
self.closebutton.config(relief = 'flat', bd = 0)
if(messagebox.askyesno('Delete Note?','Are you sure you want to delete this note?')):
master.destroy()
return
self.closebutton.config(relief = 'flat', bd = 0, bg = '#F8F7B6')
# master (root) window
master.overrideredirect(True)
master.geometry('250x250')
master.config(bg = '#838383')
master.resizable(True,True)
# titlebar
self.titlebar = Frame(root, bg = '#F8F796', relief = 'flat', bd = 2)
self.titlebar.bind('<Button-1>', get_pos)
self.titlebar.bind('<B1-Motion>', move_window)
self.titlebar.pack(fill = X, expand = 1, side = TOP)
self.closebutton = Label(self.titlebar, text = 'X', bg = '#F8F7B6', relief = 'flat')
self.closebutton.bind('<Button-1>', quit_window)
self.closebutton.pack(side = RIGHT)
self.newbutton = Label(self.titlebar, text = '+', bg = '#F8F7B6', relief = 'flat')
self.newbutton.pack(side = LEFT)
self.newbutton.bind('<Button-1>', another_window)
# main text area
self.mainarea = tkst.ScrolledText(master, bg = '#FDFDCA', font=('Comic Sans MS', 14, 'italic'), relief = 'flat', padx = 5, pady = 10)
self.mainarea.pack(fill = BOTH, expand = 1)
# frames to introduce shadows
self.shadow = Frame(root).pack(side=BOTTOM)
self.shadow = Frame(root).pack(side=RIGHT)
root = Tk()
root.attributes('-topmost', 'true')
sticky = StickyNotes(root)
root.mainloop()
You are using classes all wrong. One of the biggest advantages to using classes is the ability to steal code from Tkinter (or whatever GUI or framework you are trying to use). The Tkinter window class is called Toplevel, so you want to subclass that and use the class itself (named "self") for all your operations. I rewrote it for you:
from tkinter import *
import tkinter.scrolledtext as tkst
from tkinter import messagebox
from tkinter import font
class StickyNotes(Toplevel):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.xclick = 0
self.yclick = 0
# master (root) window
self.overrideredirect(True)
self.geometry('250x250+500+500')
self.config(bg = '#838383')
self.attributes('-topmost', 'true')
self.resizable(True,True)
# titlebar
self.titlebar = Frame(self, bg = '#F8F796', relief = 'flat', bd = 2)
self.titlebar.bind('<Button-1>', self.get_pos)
self.titlebar.bind('<B1-Motion>', self.move_window)
self.titlebar.pack(fill = X, expand = 1, side = TOP)
self.closebutton = Label(self.titlebar, text = 'X', bg = '#F8F7B6', relief = 'flat')
self.closebutton.bind('<Button-1>', self.quit_window)
self.closebutton.pack(side = RIGHT)
self.newbutton = Label(self.titlebar, text = '+', bg = '#F8F7B6', relief = 'flat')
self.newbutton.pack(side = LEFT)
self.newbutton.bind('<Button-1>', self.another_window)
# main text area
self.mainarea = tkst.ScrolledText(self, bg = '#FDFDCA', font=('Comic Sans MS', 14, 'italic'), relief = 'flat', padx = 5, pady = 10)
self.mainarea.pack(fill = BOTH, expand = 1)
# frames to introduce shadows
self.shadow = Frame(self).pack(side=BOTTOM)
self.shadow = Frame(self).pack(side=RIGHT)
def get_pos(self, event):
self.xclick = event.x
self.yclick = event.y
def move_window(self, event):
self.geometry('+{0}+{1}'.format(event.x_root-self.xclick, event.y_root-self.yclick))
def another_window(self, event):
sticky = StickyNotes(root)
def quit_window(self, event):
self.closebutton.config(relief = 'flat', bd = 0)
if(messagebox.askyesno('Delete Note?','Are you sure you want to delete this note?')):
self.destroy()
return
self.closebutton.config(relief = 'flat', bd = 0, bg = '#F8F7B6')
root = Tk()
root.withdraw()
sticky = StickyNotes(root) # make the first note.
root.mainloop()

Can't write full text in an Entry - tkinter

I'm working on a GUI software with Tkinter which basically print a general plane of the product after pushing the "Crear" button, as you can see at the following images:
GUI Interface
After pushing "Crear" Button
As you may have appreciated, once you give the full information at the entries and push the "Crear" button, a dynamic table (made with labels and entries in a for cycle) appear with the dimensions of the modules seen at the "Esquema" frame. The problem I have is that, when I edit the information at the dynamic table, I have an immediate change on the graph (which is possible thanks to the trace method) without letting me finish the number I'm already writing; I mean: I can't write the full number at the entries on the dynamic table before it make the changes on the graph. So, my question is: which function or command can I apply to make the program stop and reactivate after I finish writing the full number at the entries on the table?
Any help will be highly appreciated,
PS: I have already tried the "time.stop" and "after" functions. The first one crashed the program, which is unacceptable, and the second one increased the waiting time before I could continue writing numbers at the table. The full code of the program is really extensive, but here I share a runnable code:
Code
from tkinter import *
from tkinter import filedialog as fd
from tkinter import messagebox as ms
from tkinter import ttk
from io import open
import tkinter as tk
from pathlib import Path
import PIL
from PIL import Image, ImageTk
import glob
import sys
import numpy as np
import os
import os, os.path
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import time
#Made by:
#Juan David Argüello Plata
#----------------------------------------------CLASSES AND FUNCTIONS-----------------------------------------------------
class Interface():
def __init__(self, inter, w=860,h=700, titulo = "Example", titulo_principal = "EXAMPLE"):
inter.title(titulo)
inter.resizable(False, False)
#Dimensions of the screen
ws = inter.winfo_screenwidth()
hs = inter.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
#Position of the interface
inter.geometry('%dx%d+%d+%d' % (w, h, x, y))
titulo = Label(inter, text = titulo_principal, font=(fuente,24, "bold italic"))
titulo.pack()
self.inter = inter
#---Frames, labels and general data---
self.Principal_frames()
self.subframes()
self.Data()
#---Actions to execute---
Action(self)
def Principal_frames(self):
self.Frame_Table = Frame(self.inter)
self.Frame_Table.config(width = "400", height = "600", bd = 2, relief = "groove")
self.Frame_Table.place(x=10, y=50)
titulo = Label(self.Frame_Table, text = "Data", font=(fuente,20, "bold italic"))
titulo.place(x=180, y=5)
self.Frame_graph = Frame(self.inter)
self.Frame_graph.config(width = "400", height = "600", bd = 2, relief = "groove")
self.Frame_graph.place(x=450, y=50)
titulo = Label(self.Frame_graph, text = "Graph", font=(fuente,20, "bold italic"))
titulo.place(x=150, y=5)
def subframes(self):
self.subframe_Data = Frame(self.Frame_Table)
self.subframe_Data.config(width = "300", height = "200", bd = 2, relief = "groove")
self.subframe_Data.place(x=80, y=50)
self.subframe_graph = Frame(self.Frame_graph)
self.subframe_graph.config(width = "395", height = "400", bd = 2, relief = "flat")
self.subframe_graph.place(x=0, y=50)
def Data(self):
Length = Label(self.subframe_Data, text = "Length", font = Font)
Length.grid(row=0, column = 0, sticky=W, padx=3)
self.Length=Entry(self.subframe_Data, width=8)
self.Length.grid(row=0,column=1, sticky=W, padx=3)
self.Sub_Length=Entry(self.subframe_Data, width=8)
self.Sub_Length.grid(row=0,column=2, sticky=W, padx=3)
Width = Label(self.subframe_Data, text = "Width", font = Font)
Width.grid(row=1, column = 0, sticky=W, padx=3)
self.Width=Entry(self.subframe_Data, width=8)
self.Width.grid(row=1,column=1, sticky=W, padx=3)
self.Sub_Width=Entry(self.subframe_Data, width=8)
self.Sub_Width.grid(row=1,column=2, sticky=W, padx=3)
class Action(Interface):
def __init__(self, inter):
self.Interface = inter
self.modification = 0
Create = Button(self.Interface.subframe_Data, text="Create", font = Font, command = self.Table)
Create.grid(row=1,column=3)
def Table(self):
self.Table = Frame(self.Interface.Frame_Table)
self.Table.config(width = "150", height = "400", bd=2, relief="groove")
self.Table.place(x=80, y=150)
#Dimensions of the labels and entries of the table
Length = 176
Width = 200
#Reading of Data
self.Data = np.zeros(4)
self.Data[0] = float(self.Interface.Length.get())
self.Data[1] = float(self.Interface.Sub_Length.get())
self.Data[2] = float(self.Interface.Width.get())
self.Data[3] = float(self.Interface.Sub_Width.get())
#---Dynamic table ---
if self.Data[1] > self.Data[3]:
self.Max = self.Data[1]
else:
self.Max = self.Data[3]
#-Variables-
label = "label"
Entry_length = "length"
Entry_width = "width"
Numbers_label = [""]*(int(self.Max)+1)
self.width_data = [""]*(int(self.Max)+1)
self.length_data=[""]*(int(self.Max)+1)
self.First_Time = 0 #Counter that depends of the size of the table (help the program to recognize if it's the first time the "Create" button is pressed)
self.Modules = np.zeros((int(self.Max),2)) #Matrix which contains the table info
#--Scorllbar--
self.canvas_table = Canvas(self.Table)
self.canvas_table.pack(side="left", fill="both", expand = True)
self.canvas_table.config(width=str(Width), height=str(Length))
self.Frame_table = Frame(self.canvas_table)
self.Frame_table.config(width=str(Width), height=str(Length), relief="flat")
self.canvas_table.create_window(0,0,window= self.Frame_table, anchor = 'nw')
self.yscroll = Scrollbar(self.Table, orient = "vertical", command = self.canvas_table.yview)
self.yscroll.pack(side='right', fill='y')
self.canvas_table['yscrollcommand'] = self.yscroll.set
self.Frame_table.bind("<Configure>", self.AuxscrollFunction)
self.yscroll.grid_forget()
Number = Label(self.Frame_table, text="", width=4, font = Font, bd = 2, relief="groove")
Number.grid(row=0,column=0,sticky=W)
L = Label(self.Frame_table, text="L", width=8, font = Font, bd = 2, relief="groove")
L.grid(row=0,column=1,sticky=W)
Wid = Label(self.Frame_table, text="W", width=8, font = Font, bd = 2, relief="groove")
Wid.grid(row=0,column=2,sticky=W)
#Subdivisions (defect values)
Wth = self.Data[2]/self.Data[3]
l = self.Data[0]/self.Data[1]
self.var_length = []
self.var_width = []
for i in range(int(self.Max)+1):
if i != 0:
Numbers_label[i] = label + str(i)
Numbers_label[i] = Label(self.Frame_table, text=str(i), width=4, font = Font, bd = 2, relief="groove")
Numbers_label[i].grid(row=i,column=0,sticky=W)
if i <= self.Data[1]:
text = str(l)
else:
text = "0.0"
var_length = StringVar()
self.var_length.append(var_length)
self.length_data[i] = Entry_length + str(i)
self.length_data[i] = Entry(self.Frame_table, width=9, font = Font, bd = 2, relief="groove", textvariable = self.var_length[i-1])
self.var1 = self.length_data[i]
self.var_length[i-1].trace("w", lambda name, index, mode, envio=self: Action.callback(envio))
self.length_data[i].grid(row=i,column=1,sticky=W)
self.length_data[i].insert(0, text)
if i <= self.Data[3]:
text = str(Wth)
else:
text = "0.0"
var_width = StringVar()
self.var_width.append(var_width)
self.width_data[i] = Entry_width + str(i)
self.width_data[i] = Entry(self.Frame_table, width=9, font = Font, bd = 2, relief="groove", textvariable = self.var_width[i-1])
self.var1 = self.width_data[i]
self.var_width[i-1].trace("w", lambda name, index, mode, envio=self: Action.callback(envio))
self.width_data[i].grid(row=i,column=2,sticky=W)
self.width_data[i].insert(0, text)
self.yscroll.pack(side='right', fill = 'y')
def AuxscrollFunction(self,event):
self.canvas_table.configure(scrollregion=self.canvas_table.bbox("all"))
def callback(self, *args):
self.First_Time = self.First_Time+1
if self.First_Time >= 2*int(self.Max) and self.modification == 0:
try:
for i in range(int(self.Max)+1):
if i != 0:
self.Modules[i-1][0] = float(self.length_data[i].get())
self.Modules[i-1][1] = float(self.width_data[i].get())
self.Data[0] = 0
self.Data[2] = 0
for i in range(int(self.Max)):
self.Data[0] = self.Data[0]+self.Modules[i][0]
self.Data[2] = self.Data[2]+self.Modules[i][1]
self.Interface.Length.delete(0, 'end')
self.Interface.Width.delete(0, 'end')
self.Interface.Length.insert(0, str(self.Data[0]))
self.Interface.Width.insert(0, str(self.Data[2]))
#self.var1.focus()
self.Graph()
except ValueError:
pass
def Graph(self):
#---Area---
f=Figure(figsize=(3,3), dpi=100)
a=f.add_subplot(111)
type_line = 'r--' #Línea de borde de área
a.plot([0,self.Data[2]], [0,0], type_line)
a.plot([0,self.Data[2]], [self.Data[0],self.Data[0]], type_line)
a.plot([0,0], [0,self.Data[0]], type_line)
a.plot([self.Data[2],self.Data[2]], [0,self.Data[0]], type_line)
canvas = FigureCanvasTkAgg(f, self.Interface.subframe_graph)
canvas.draw()
canvas.get_tk_widget().place(x=0,y=0)
#--------------------------------------------------------INTERFACE-----------------------------------------------
#---Beginning of the interface---
root = Tk()
#Font
fuente = "TkFixedFont"
Font = (fuente, 10)
Interface(root)
root.mainloop()

canvas command not working inside function

Help! I am using python 3.5.2 and the function self.new_game is not working. It is supposed to put text on the canvas but it does nothing! There are also no errors that appear in the shell.
from tkinter import *
import time
import os
WIDTH = 1920
HEIGHT = 1080
root = Tk()
root.state('zoomed')
planet_selected = 0
planet_name = "nothing"
planet_temp = -270
planet_size = 0.0
planet_life = 0.0
class Space(Frame):
def __init__(self):
Frame.__init__(self)
frame1 = Frame(self)
self.canvas = Canvas(frame1, width = WIDTH, height = HEIGHT, bg ="white")
self.canvas.focus_set()
self.canvas.create_text(1920,1000,text='Planetary Creator',font=('Arial',15))
self.master.title("Planetary Creator Alpha 0.1")
frame = Frame(root, bg='grey', width=1920, height=40)
frame.pack(fill='x')
button1 = Button(frame, text='New Game',command=lambda : self.new_game())
button1.pack(side='left', padx=10)
button2 = Button(frame, text='Quit Game',command=lambda : os._exit(0))
button2.pack(side='left')
#this function below does not work!!!
def new_game(self):
self.canvas.delete(ALL)
size = self.canvas.create_text(960,540,text=str(planet_size) + "moon",font=("Arial",10))
life = self.canvas.create_text(960,520,text="✣" + str(planet_life) + "%",font=("Arial",10))
temp = self.canvas.create_text(960,500,text=str(planet_temp) + "°C",font=("Arial",10))
name = self.canvas.create_text(960,480,text=planet_name,font=("Arial",15))
Space().mainloop()
I removed frame1 and put Canvas in root , and use canvas.pack() to see canvas in window.
(but I could use self instead of root and use self.pack() because Space inherits from Frame. it would ne more logical)
After that I had to only change text positions because windows was too big for my screen.
I used variables CENTER_X, CENTER_Y to put text in center regardless of the size of the screen.
from tkinter import *
import time
import os
class Space(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master.title("Planetary Creator Alpha 0.1")
self.canvas = Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
self.canvas.pack()
self.canvas.focus_set()
self.canvas.create_text(CENTER_X, CENTER_Y, text='Planetary Creator', font=('Arial',15))
frame = Frame(root, bg='grey', width=WIDTH, height=40)
frame.pack(fill='x')
button1 = Button(frame, text='New Game', command=self.new_game)
button1.pack(side='left', padx=10)
button2 = Button(frame, text='Quit Game', command=root.destroy)
button2.pack(side='left')
def new_game(self):
self.canvas.delete(ALL)
size = self.canvas.create_text(CENTER_X, CENTER_Y, text=str(planet_size) + "moon", font=("Arial",10))
life = self.canvas.create_text(CENTER_X, CENTER_Y-20, text="✣" + str(planet_life) + "%", font=("Arial",10))
temp = self.canvas.create_text(CENTER_X, CENTER_Y-40, text=str(planet_temp) + "°C", font=("Arial",10))
name = self.canvas.create_text(CENTER_X, CENTER_Y-60, text=planet_name, font=("Arial",15))
# --- main ---
WIDTH = 800 #1920
HEIGHT = 500 #1080
CENTER_X = WIDTH//2
CENTER_Y = HEIGHT//2
planet_selected = 0
planet_name = "nothing"
planet_temp = -270
planet_size = 0.0
planet_life = 0.0
root = Tk()
#root.state('zoomed')
Space(root)
root.mainloop()

Fill space with widgets on resize

How to do that the 'label' and the 'text' widgets fill all the space when 'root' is being resized?
I'd like to use the 'grid' method if it's possible.
from tkinter import *
root = Tk()
root.resizable(width = True, height = True)
label = Label(root, text = "Text")
label.grid()
text = Text(root)
text.grid()
root.mainloop()
It doesn't work when I try to use in a class.
Application.py
from tkinter import *
import menu
import workPlace
class Application(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
self.master.title("Title")
self.master.grid_columnconfigure(0, weight = 1)
self.master.grid_rowconfigure(1, weight = 1)
self.master.resizable(width = True, height = True)
self.menu = menu.MenuBar(self)
self.menu.grid(sticky = W)
self.workPlace = workPlace.WorkPlace(self)
self.workPlace.grid(sticky = "NEWS")
if __name__ == "__main__":
Application().mainloop()
workPlace.py
from tkinter import *
import tkinter.scrolledtext as scr
class WorkPlace(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
self.scrText = scr.ScrolledText(self)
self.scrText.grid()
self.label = Label(self,text = "Label")
self.label.grid()
menu.py
from tkinter import *
class MenuBar(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
fileMenu = Menubutton(self, text = 'File')
fileMenu.grid(row = 0, column = 0)
me1 = Menu(fileMenu)
fileMenu.configure(menu = me1)
findMenu = Menubutton(self, text = 'Find')
findMenu.grid(row = 0, column = 1)
me1 = Menu(findMenu)
findMenu.configure(menu = me1)
optionMenu = Menubutton(self, text = 'Option')
optionMenu.grid(row = 0, column = 2)
me1 = Menu(optionMenu)
optionMenu.configure(menu = me1)
Two steps are required.
Call grid_rowconfigure and grid_columnconfigure to set the weight of each of the grid's rows and columns. Rows and columns with a weight of zero don't stretch at all during a resize. This is the default behavior.
When calling grid on your widgets, specify the sticky parameter so the widgets stretch whenever their row or column stretches.
from tkinter import *
root = Tk()
root.grid_columnconfigure(0, weight=1)
#uncomment this line if you want the Label widget to stretch vertically.
#or leave it as is if you only want the Text widget to stretch.
#root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.resizable(width = True, height = True)
label = Label(root, text = "Text")
label.grid(sticky="NEWS")
text = Text(root)
text.grid(sticky="NEWS")
root.mainloop()
In the specific case of your WorkPlace object, you need to configure both the root object and the WorkPlace object, and you need to specify stickiness for the WorkPlace object and its child objects.
from tkinter import *
import tkinter.scrolledtext as scr
class WorkPlace(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.scrText = scr.ScrolledText(self)
self.scrText.grid(sticky="NEWS")
self.label = Label(self,text = "Label")
self.label.grid()
If you are okay with using pack instead of grid, you can do
from tkinter import *
root = Tk()
root.resizable(width = True, height = True)
label = Label(root, text = "Text")
label.pack(fill=X)
text = Text(root)
text.pack(fill=BOTH, expand=True)
root.mainloop()

Categories

Resources