I am redesigning the GUI of a program that uses tkinter in python. I used ttk widgets for this program, but I think, even on W10, the interface is way too old so I decided to update the visual interface for the program using METRO interface or W10 alike UI.
The first thing that come in mind, is that W10 have a left-side "tabs" that are very beautiful and useful, and the question is if is that a way to using the ttk.notebook widget, change the position of the tabs?
Otherwise, I could do buttons placed on the side and load frame widgets on every button clicked, but I think this could overload so much the program loading constantly frames and widgets, and I am trying to avoid this way.
Thanks to everyone.
It is possible to change the position of the tabs by configuring the tabposition option of the TNotebook style.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
style = ttk.Style(root)
style.configure('lefttab.TNotebook', tabposition='ws')
notebook = ttk.Notebook(root, style='lefttab.TNotebook')
f1 = tk.Frame(notebook, bg='red', width=200, height=200)
f2 = tk.Frame(notebook, bg='blue', width=200, height=200)
notebook.add(f1, text='Frame 1')
notebook.add(f2, text='Frame 2')
notebook.pack()
root.mainloop()
This is how it looks like with the default theme on linux:
However, the text inside the tabs is always horizontal. I don't have Windows, so I don't know exactly how the W10 UI looks like, but I guess that you would like to rotate the tabs, not just change there position and I don't know how to do that.
Related
Advice: i'm working on Windows 8.1, with Python and Tkinter at last version; i wrote from tkinter import * to post less code here, i know that it is a bad practice, use for example import tkinter as tk instead.
I'm coding my first text editor, and i have a problem when i resize the main windows. When i run the program it display on screen a window with dimension 750x500 pixel. So far, all ok, i can write text without problem (note that menu_bar and other features are work-in progress, but we dont care about them). Problem is with Text widget when user tries to resize window with cursor. The content of the text practically adapts to the size of the window (the length of each string is reduced or increased based on the width of the window). But i don't want that this happen. I want that Text widget changes his width automatically in base of window size, but the content mustn't be adapted. I hope that you understand my question, if not, i will try to explain better.
I have searched on online reference if there's a parameter to set this option, but i haven't found anything.
How to solve the problems concerning the Text widget and resizing the window?
from tkinter import *
root = Tk()
root.geometry("750x500")
content_text = Text(root, wrap=WORD, bg="grey25", undo=True, cursor="",
insertbackground="red", foreground="white", font="courier 12")
content_text.pack(fill=BOTH, expand=True)
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set, selectbackground="dodgerblue")
scroll_bar.configure(command=content_text.yview)
scroll_bar.pack(side=RIGHT, fill=Y)
if __name__ == '__main__':
root.mainloop()
You can't do what you want. If you have wrapping turned on, text will always wrap at the edge of the window. When you change the width of the window, the text will re-wrap to the new width. There is no configuration option to tell the widget to wrap at any other place.
This question already has answers here:
Adding a scrollbar to a group of widgets in Tkinter
(3 answers)
Closed 4 years ago.
My code is working well in itself, but doesn't scroll through the Labels (which is what i'm trying to achieve).
I don't want to use canvas or listbox or anything.
import tkinter as tk
master = tk.Tk()
scrollbar = tk.Scrollbar(master).pack(side=tk.RIGHT, fill=tk.Y,command=tk.yview)
label = tk.Label(text="llklkl")
label.place(x=100,y=500)
label2 = tk.Label(text="llklkl")
label2.place(x=1000,y=5000)
tk.mainloop()
Hello and welcome to SO.
The tkinter Scrollbar widget sadly can not be used on a _tkinter.tkapp object, i.e. your main window called master. From effbot.org:
This widget is used to implement scrolled listboxes, canvases, and text fields.
and
The Scrollbar widget is almost always used in conjunction with a Listbox, Canvas, or Text widget. Horizontal scrollbars can also be used with the Entry widget.
That means that you absolutely HAVE to create some widget inside your main window in order to be able to scroll anything, you can`t just scroll the window itself.
That being said, if you wanted to add a Scrollbar to, let's say, a Listbox, that's how you would do it (also taken from the above mentioned website, you should really check it out):
First of all, you have to set the widget’s yscrollcommand callbacks to the set method of the scrollbar.
Secondly, you have to set the scrollbar’s command to the yview method of the widget, much like you did already, but like name_of_object.yview, not tk.yview.
import tkinter as tk
master = tk.Tk()
scrollbar = tk.Scrollbar(master)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
listbox = tk.Listbox(master, yscrollcommand=scrollbar.set)
for i in range(20):
listbox.insert(tk.END, str(i))
listbox.pack(side=tk.LEFT, fill=tk.BOTH)
scrollbar.config(command=listbox.yview)
master.mainloop()
Also, pack the scrollbar in a seperate line. This will produce a window with numbers from 1 to 50 in a scrollable Listbox widget. If i get you right, you want to be able to scroll between your labels? well, i guess you'll have to use some kind of wrapping widget for that, i would recommend a Canvas. But that's really up to you and i'm sure you'll figure it out yourself. If you need any more help, let me know - but please read the docs before asking ;-)
I am familiarizing myself with Tkinter, and I am attempting to write a very simple program, which displays a button in a window, using the pack geometry manager.
I was experimenting with various configuration options for pack(), such as expand, fill, and side, and I've run into a peculiar problem. I have written the following code:
from Tkinter import *
root = Tk()
widget = Button(root, text='text')
widget.pack(expand=YES, fill=BOTH)
root.mainloop()
The problem is that the button expands to fill the window in the horizontal direction, but not the vertical direction. This is the same result that I get if instead of specifying fill=BOTH I use fill=X. In addition, if I specify instead fill=Y the button does not expand in either direction. Something seems to be going wrong with the fill in the vertical direction, and I cannot figure out what it might be.
I attempted to Google this problem and surprisingly found no mention of this happening to anyone else. I am using a Mac with OS X Yosemite and running python 2.7.5. I also attempted to compile with python 3.4.1 and saw no change.
Edit:
Based off of the answer and comments below, it is clear that there is nothing wrong with my code, because it seems to work on other machines. If not an error in the code, does anyone know what could possibly be causing the button to not stretch vertically when I run the above code?
This is a feature of native buttons on OSX. Buttons on OSX will be a fixed height and will not expand vertically. There is nothing you can do, short of using a different widget such as a label.
try running this code to see the behavior of fill and expand
from Tkinter import *
root = Tk()
root.geometry("500x500")
widget = Button(root, text='text1')
widget.pack(fill=X, expand=1)
widget = Button(root, text='text2')
widget.pack(fill=Y, expand=1)
widget = Button(root, text='text3')
widget.pack(fill=BOTH, expand=1)
root.mainloop()
Argument fill does fill in vertical direction as well
I am also beginner, defining geometry for fill was missing in your code as given below:
from Tkinter import *
root = Tk()
root.geometry("600x400")
widget = Button(root, text='text')
widget.pack(expand=YES, fill=BOTH)
root.mainloop()
I used the code below (with different variable names for each section) to create a background image for each tkinter window. Each of these is initiated in a function and both work fine independently.
When loading one function from another however, the second fails to display an image. (I have tried importing all relevant in each function aswell). It works in the case that use tk.destruct(), however if If I want to keep it open, or hide it with . withdraw(), the image fails to display, rendering the second window useless.
background_image=tk.PhotoImage(...)
background_label = tk.Label(parent, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
Ok I've made up a solution for you. Basically all you need is to use tk.Toplevel() for the second tkinter window and make sure that the 'parent' is root2 so the image will appear in the second window.
I have used buttons for the images, you had labels so you may wish to change this, but buttons gave me a way to open a new tk window easily, I have also used .pack(), not .place(), as it was faster for me. May also be helpful for you to know that I used python 3.3 with windows so you might need a capital T for tkinter.
import tkinter as tk
root1 = tk.Tk()
def new_window():
root2 = tk.Toplevel()
# click the last button and all tk windows close
def shutdown():
root1.destroy()
root2.destroy()
background_image2 = tk.PhotoImage(file = '...')
background_button2 = tk.Button(root2, image = background_image2, command = shutdown)
background_button2.pack()
root2.mainloop()
background_image1 = tk.PhotoImage(file = '...')
# have used a button not a label for me to make another tk window
background_button1 = tk.Button(root1, image = background_image1, command = new_window)
background_button1.pack()
root1.mainloop()
#user2589273 Next time you should add more code so answers can be easily given, and tailored to you, just a suggestion. Hope this helps.
I'm adding several widgets to a Frame which is located in a tix.NoteBook. When there are too much widgets to fit in the window, I want to use a scrollbar, so I put tix.ScrolledWindow inside that Frame and add my widgets to this ScrolledWindow instead.
The problem is that when using the grid() geometry manager, the scrollbar appears, but it is not working (The drag bar occupies the whole scroll bar).
from Tkinter import *
import Tix
class Window:
def __init__(self, root):
self.labelList = []
self.notebook = Tix.NoteBook(root, ipadx=3, ipady=3)
self.notebook.add('sheet_1', label="Sheet 1", underline=0)
self.notebook.add('sheet_2', label="Sheet 2", underline=0)
self.notebook.add('sheet_3', label="Sheet 3", underline=0)
self.notebook.pack()
#self.notebook.grid(row=0, column=0)
tab1=self.notebook.sheet_1
tab2=self.notebook.sheet_2
tab3=self.notebook.sheet_3
self.myMainContainer = Frame(tab1)
self.myMainContainer.pack()
#self.myMainContainer.grid(row=0, column=0)
scrwin = Tix.ScrolledWindow(self.myMainContainer, scrollbar='y')
scrwin.pack()
#scrwin.grid(row=0, column=0)
self.win = scrwin.window
for i in range (100):
self.labelList.append((Label(self.win)))
self.labelList[-1].config(text= "Bla", relief = SUNKEN)
self.labelList[-1].grid(row=i, column=0, sticky=W+E)
root = Tix.Tk()
myWindow = Window(root)
root.mainloop()
Whenever I change at least one of the geometry managers from pack() to grid(), the problem occurs. (Actually, I'd prefer using grid() for all containers.)
When I don't use the NoteBook widget, the problem does not occur either. The other examples here all seem to rely on pack().
Any ideas?
Many thanks,
Sano
I solved it without using ´tix.scrolledWindow´. Instead, I went for the autoscrollbar suggested by Fred Lundh here.
The main problem was the adaption to the NoteBook widget. First, I tried to put the scrollbar to the root, so that they would surround the whole window. Now, I wanted to change the hook for the scrollbar whenever I changed a tab, but the ´raisecmd´ of the Notebook did not work. Next, I thought of using the configure event on each tab - whenever a new tab is raised, its size changes and configure is called.
Well, after much trying without ever being satisfied I changed my approach and put the scrollbars inside of the tabs. The tabs and all subcontainers must get the ´grid_columnconfigure(0, weight=1)´ and ´grid_rowconfigure(0, weight=1)´ settings, or else they will not grow with the tabs.