How to change widget's size without pushing others - python-3.x

The "ok" button separates the two entry boxes from each other. I want them to stick together and the button making a square at the end of the two entries:
Here's the code
ventana = Tk()
ventana.geometry("500x300")
pathLabel = Label(ventana, text="Path of file: ").grid(row=0)
nameLabel = Label(text="Name of file").grid(row=1)
ePath = Entry()
eName = Entry()
ePath.grid(row=0, column=1)
eName.grid(row=1, column=1)
Ok = Button(text="okay", command=savepath)
Ok.grid(row=1, column=2, sticky=N)
Ok.configure(height=5)
ventana.mainloop()
This is how it looks
I want it to look like this
Thanks.

It sounds like what you want is for the button to be on row zero and extend to row one. So, that's exactly what you should tell grid.
If you want the button to exactly fit those two rows, I recommend not giving the button an explicit size. Instead, let grid make the button expand to fill the two rows by using the sticky option.
Ok.grid(row=0, column=2, rowspan=2, sticky="nsew")

Related

How do I put a button to the left of the button in the bottom right of my ktinker program?

I'm trying to write a program with ktinker with buttons in the top/bottom left and the top/bottom right. The issue is, I cannot put any buttons next to pre-existing buttons, only next to them, how would I do this?
#Welcome text and version number
Label(root, text="Wecome to %s" % banicVer).place(relx=0.5, rely=0.5, anchor=CENTER)
#Confirm button
#Button(root,text="Confirm\nand Save", command=root.destroy,).pack(side=BOTTOM,anchor=SE)
Button(root,text="Confirm\nand Save", command=root.destroy,).pack(side=BOTTOM,anchor=SE)
#Revert
#Button(root,text="Reset\nBootscreen", command=root.destroy,).pack(side=LEFT,anchor=SE)
Button(root,text="Reset\nBootscreen", command=root.destroy,).pack(side=BOTTOM,anchor=SE)
root.mainloop()

How to add a scrollbar to an overlapping canvas in Python tkinter

I am trying to make an application for a school project, one of the features is a messaging service where users can message each other, this is accessed via a button in which the messaging GUI is loaded. I have already added a canvas as the background for the main GUI at the start of the program but for the message interface I have added another canvas which overlaps and will be using a scrollbar to scroll through the messages and display them.
In essence my problem is that I would like to position another canvas on top of the main canvas using co-ordinates and add a scrollbar which only fits to the right hand side of this smaller canvas.
Thanks in advance :)
I have tried to add a scrollbar to it using pack(), grid(), place() and canvas.create_window() however in all instances the scrollbar either does not appear, does not fill the entire right hand side of the second canvas, or is not placed in the correct position. The closest I got was with the place() function where I have managed to position the scrollbar and canvas using "relx", "rely" and "relheight" however the scrollbar is not scrolling the canvas.
root = Tk() #creates the GUI
root.title("Eclass")
root.iconbitmap(default='icon.ico') #sets icon
root.state('zoomed')
backgroundcolour = root.cget("bg")
screen_width = root.winfo_screenwidth() - 15
screen_height = root.winfo_screenheight()
canvas = Canvas(root, width = screen_width, height = screen_height)
def messaging():
canvas.delete("all")
msg_canvas = Canvas(canvas, width = 1530, height = 730, bg = "red")
#canvas.create_window(1123,600, window = msg_canvas) this is where I tried to add the second canvas using the create_Window function
msg_canvas.place(relx=0.186, rely=0.227)
msg_scrollbar = Scrollbar(canvas, orient="vertical",command=msg_canvas.yview)
msg_scrollbar.place(relx=0.975,rely=0.2295, relheight = 0.717)
msg_canvas.config(scrollregion=msg_canvas.bbox(ALL))
I expect the canvas to be placed within the current co-ordinates given via relx and rely or in previous trial the co-ordinates in canvas.create_window(), I then expect the msg_scrollbar to be on the right hand side of msg_canvas and fill to its Y (the height of the scrollbar should be the same as the height of the canvas). In actuality the canvas and scrollbar are in the correct co-ordinates however the scrollbar does not scroll the msg_canvas even after moving it.
, In essence, my problem is that I would like to position another canvas on top of the main canvas using co-ordinates and add a scrollbar which only fits the right-hand side of this smaller canvas.
I recommend against using place. Both pack and grid are better for creating code that is responsive to changes in resolution, window size, and fonts.
IMHO, the simplest solution is to use pack to put the main canvas at the bottom, then in the remaining space put the scrollbar on the right and the secondary canvas on the left. Note: the order is important, as each time you call pack it will use up all of the space on the given side, reducing the space available to future widgets.
canvas.pack(side="bottom", fill="both", expand=True)
msg_scrollbar.pack(side="right", fill="y")
msg_canvas.pack(side="left", fill="both", expand=True)
You can accomplish the same thing with grid, but it requires additional lines of code to configure row and column weights. With grid order isn't as important since you are explicitly setting rows and columns.
msg_canvas.grid(row=0, column=0, sticky="nsew")
msg_scrollbar.grid(row=0, column=1, sticky="ns")
canvas.grid(row=1, column=0, columnspan=2, sticky="nsew")
root.grid_rowconfigure((0,1), weight=1)
root.grid_columnconfigure(0, weight=1)

How do i store two values into variables from two entries with a single button press?

This is my first python application guys so don't laugh if the answer is obvious.
I need to get from 2 entries 2 values and then store them into variables with a single button press. I use tkinter to design my GUI. I am able to make the button store the value entered in 'entry1' in the variable entry1 but cannot make the button store a second one at the same time.
TLDR:
when button press
text from entry1 gets stored into entry1 variable
text from entry2 gets stored into entry2 variable
Below you will find the code that i am using for only 1 action (get the text from entry1 in entry1 variable)
def get_code_cl(entry1):
print(entry1)
def get_Dade_cl(entry):
print(entry2)
button = tk.Button(frame, text="Search",bg='red',font=20,fg='white', command=lambda: get_code_cl(entry.get()))
button.place(relx=0.21, rely=0.01, relheight=0.23, relwidth=0.11)
Welcome to stack overflow florin!
To solve your problem you can make the command of the button a subroutine that creates both of the variables.
For example, in the example code below, the button's command is the storevaluessubroutine subroutine.
This subroutine creates two variables: 'entry1value' and 'entry2value' that store the values of the 'entry1' and 'entry2' entry fields.
I made the entry1 and entry2 entry fields global entry fields so that their values can be fetched in the storevaluessubroutine subroutine.
global entry1
entry1 = Entry(frame)
entry1.pack()
global entry2
entry2 = Entry(frame)
entry2.pack()
def storevaluessubroutine():
entry1value = entry1.get()
entry2value = entry2.get()
button = tk.Button(frame, text="Search",bg='red',font=20,fg='white', command=storevaluessubroutine)
button.place(relx=0.21, rely=0.01, relheight=0.23, relwidth=0.11)

Tkinter Treeview heading styling

I want to change the background colour of the treeview headings. I have identified the element option of the Treeview.Heading layout responsible for this: Treeheading.cell. The problem is that this setting does not work on the 'vista' theme (Due to drawing issues I assume).
working code (theme looks terrible though):
from tkinter import *
from tkinter import ttk
p=Tk()
separator = PanedWindow(p,bd=0,bg="#202322",sashwidth=2)
separator.pack(fill=BOTH, expand=1)
_frame = Frame(p,bg="#383838")
t=ttk.Treeview(_frame)
t["columns"]=("first","second")
t.column("first",anchor="center" )
t.column("second")
t.heading("first",text="first column")
t.heading("second",text="second column")
t.insert("",0,"dir1",text="directory 1")
t.insert("dir1","end","dir 1",text="file 1 1",values=("file 1 A","file 1 B"))
id=t.insert("","end","dir2",text="directory 2")
t.insert("dir2","end",text="dir 2",values=("file 2 A","file 2 B"))
t.insert(id,"end",text="dir 3",values=("val 1 ","val 2"))
t.insert("",0,text="first line",values=("first line 1","first line 2"))
t.tag_configure("ttk",foreground="black")
ysb = ttk.Scrollbar(orient=VERTICAL, command= t.yview)
xsb = ttk.Scrollbar(orient=HORIZONTAL, command= t.xview)
t['yscroll'] = ysb.set
t['xscroll'] = xsb.set
print(ttk.Style().theme_names())
ttk.Style().theme_use('default')
ttk.Style().configure("Treeview", background="#383838",foreground="white")
ttk.Style().configure("Treeview.Heading",background = "blue",foreground="Black")
p.configure(background='black')
t.grid(in_=_frame, row=0, column=0, sticky=NSEW)
ysb.grid(in_=_frame, row=0, column=1, sticky=NS)
xsb.grid(in_=_frame, row=1, column=0, sticky=EW)
_frame.rowconfigure(0, weight=1)
_frame.columnconfigure(0, weight=1)
separator.add(_frame)
w = Text(separator)
separator.add(w)
p.mainloop()
my attempt using 'vista' theme:
ttk.Style().element_create("Treeheading.cell","from","default")
ttk.Style().configure("Treeview", background="#383838",foreground="white")
ttk.Style().configure("Treeview.Heading",background = "Blue")
element_create has worked in other instances of this problem but with different widgets.
Thank you, any help would be appreciated.
working in python 3. Also the code is not mine, I found it and used it to test.
You are on the right track but need to change the border element rather than the cell element. As you are working on Windows, the treeview cells are being displayed using a system provided theme element from the Visual Styles API. In this case it is a HP_HEADERITEM part from the HEADER class. As this is drawn by the system theme engine you don't get to customise it from Tk aside from selecting alternate looks according to the state.
If you must customise the look of the header then you have to replace the theme part with one that Tk can customise and the default theme is a good choice. I would also recommend that you define this as a custom style so that you can re-style specific widgets and not necessarily all of them.
style = ttk.Style()
style.element_create("Custom.Treeheading.border", "from", "default")
style.layout("Custom.Treeview.Heading", [
("Custom.Treeheading.cell", {'sticky': 'nswe'}),
("Custom.Treeheading.border", {'sticky':'nswe', 'children': [
("Custom.Treeheading.padding", {'sticky':'nswe', 'children': [
("Custom.Treeheading.image", {'side':'right', 'sticky':''}),
("Custom.Treeheading.text", {'sticky':'we'})
]})
]}),
])
style.configure("Custom.Treeview.Heading",
background="blue", foreground="white", relief="flat")
style.map("Custom.Treeview.Heading",
relief=[('active','groove'),('pressed','sunken')])
What we are doing is defining a new widget style using the same layout as for the standard treeview style and replacing the border element. While we have not defined the other custom elements, these are looked up hierarchically so in the absence of a Custom.Treeheading.text it will use a Treeheading.text.
To use this, we set the style of the treeview widget:
t=ttk.Treeview(_frame, style="Custom.Treeview")
Ends up looking like this on Windows 10:

Python - Configuring multiple buttons at once in Tk

I have eighteen buttons that need to all change from one image to another upon the press of another button. I could just call .configure on each and set it that way, however, I feel as though there is a much cleaner simpler way. Any ideas?
If the buttons are all in a list, you can loop over them, like this:
self.buttons = [button1, button2, ..., button18]
def updateButtonImage(self):
for button in self.buttons:
button.configure(image=self.newImage)
updateButton = Button(root, text="Change button image", command=self.updateButton)
Is that what you had in mind?

Resources