I'm relatively new to Python and coding in general, so I'm a bit rubbish with most of the terminology.
I've researched this myself but I'm still relatively unsure (kept messing up), so hope someone can help me.
I'm looking to attach the scrollbar within my code to the right side of the text widget, rather than having it floating around the bottom corner.
My project is a text adventure (learning Python along to a book), and I have been building a very basic GUI to house the game. Essentially the text box here is placeholder, and it'll be replaced with the game code down the line, with graphics making up the rest of the window surrounding the center text/command prompt. I'm assuming doing this would be doable relatively easily?
I'm happy to work out just how to sort the scrollbar currently, as it's helping me learn!
Thanks guys!
from tkinter import *
root = Tk()
root.title("GAME TITLE")
mainframe = Frame(root, width=720, height=540)
mainframe.pack()
gametext = Text(root, width=75, height=15)
gametext.place(relx=0.5, rely=0.7, anchor=CENTER)
scrollbar = Scrollbar(root, command=gametext.yview)
gametext.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side=RIGHT, fill=Y)
gametext.tag_configure('fonttype1', font = ('Arial', '12', 'bold'))
quote = """GAMEPLAY TEXT HERE"""
gametext.insert(END, quote, 'fonttype1')
root.mainloop()
Sample Screenshot of code running
If all you're using is a text widget and scrollbar, use pack for both. place is best used very, very rarely.
scrollbar.pack(side=RIGHT, fill=Y)
gametext.pack(side=LEFT, fill=BOTH, expand=True)
Related
I have an app that I would like to restyle using Customtkinter. I originally used Tkinter.
However I have a ListBox widget connected to a scrollbar and when I run the code it says that Customtkinter does not have CTkListBox as attribute, or that ListBox is not defined.
I have tried o look for the issue online and it seems that other people have asked to the person who created he module if he could add ListBox widgets (the link below).
https://github.com/TomSchimansky/CustomTkinter/issues/69
He did answer, but as I am new to coding, I do not feel very confident with the code attached.
I hope someone can help.
Thank you
This is my original code:
# create listbox and put it on screen
list1 = Listbox(window, height=6, width=35)
list1.grid(row=2, column=0, rowspan=6, columnspan=2)
#create scrollbar and put it on screen
sb1 = Scrollbar(window)
sb1.grid(row=2, column=2, rowspan=6)
# apply configure methods to make list and scrollbar work together
list1.configure(yscrollcommand = sb1.set)
sb1.configure(command=list1.yview)
# bind method takes two args: type of event and function.
list1.bind("<<ListboxSelect>>", get_selected_row)
Here is my code
from tkinter import *
root = Tk()
root.geometry('500x500')
btn = Button(root, text = 'Play', height=5,width=30, command = root.destroy)
btn.place(x=140, y=200)
w = Label(root, text ='Lost', font=("Courier", 50), height=4)
w.pack()
root.mainloop()#
The button is meant to say play on it
This is a side effect of several things. What's happening here is that the text in your label is being centered vertically in a box with room for 4 lines. That text has opaque background, so the bottom of text box is sitting over the top of your button and hiding the text. If you remove height=4, you'll see that it works just fine.
The other problem here is mixing the placement tools. You are mixing place and pack, and that is going to cause trouble. You may need to think about the layout issues some more.
I have this super simple implementation of a textBox:
root = Tk()
root.geometry('1650x900')
center_windows(root)
root.resizable(0, 0)
scrollbar = Scrollbar(root)
old_xml_text = Text(root, wrap=WORD, yscrollcommand=scrollbar.set, height=40, width=60)
old_xml_text.grid(row=0, column=0,pady=(100,0),padx=(50,50),sticky='we')
scrollbar.config(command=old_xml_text.yview)
The problem is that if I paste there a long text (2k lines) it became extremely laggy during scrolling.
How can I solve this?
If there is no solution using Tkinter, is there any other way to achieve this using other package (in Python)? I don't want any kind of lag when I past or scroll the text. Am I forced to use C/C++ ?
Any suggestion appreciated.
The problem lies in the computation time it takes the Text widget to insert all line breaks and thereby to compute the total number of lines and the current position. While scrolling, this computation is too slow and you get lags and the scrollbar is rendered useless.
If you want to speed it up and remove the lags, you have to insert line breaks manually, so that no line extends the 60 character width of your text window. If you insert line breaks and don't pass it to the wrapper, it won't lag. See the following example for reference:
from tkinter import *
root = Tk()
root.geometry('800x600')
#center_windows(root)
root.resizable(0, 0)
scrollbar = Scrollbar(root)
old_xml_text = Text(root, wrap=WORD, yscrollcommand=scrollbar.set, width=60,height=10)
old_xml_text.grid(row=0, column=0,pady=(100,0),padx=(0,0),sticky=N+S+E)
scrollbar.config(command=old_xml_text.yview)
scrollbar.grid(row=0,column=1,pady=(100,0),sticky=N+S+W)
scrollbar2 = Scrollbar(root)
old_xml_text2 = Text(root, wrap=WORD, yscrollcommand=scrollbar2.set, width=60,height=10)
old_xml_text2.grid(row=2, column=0,pady=(100,0),padx=(0,0),sticky=N+S+E)
scrollbar2.config(command=old_xml_text2.yview)
scrollbar2.grid(row=2,column=1,pady=(100,0),sticky=N+S+W)
old_xml_text.insert(END,"Hello World, this is a test of reaction times\n"*1000)
old_xml_text2.insert(END,"Hello World, this is a test of reaction times"*1000)
You can see that the Text widget with line breaks is perfectly well scrollable while the one that uses the Text widget wrapper is not.
I'm making a project where I have to display logs in a frame with the help of Tkinter. Here is my code for that particular frame.
# frame3 for logs
frame3 = Frame(
win,
bg='black',
width=310,
height=140,
padx=0,
pady=0)
frame3.pack(fill=X, expand=True, padx=(0, 10), pady=0)
frame3.pack_propagate(0) # stops frame from shrinking
scroll = Scrollbar(frame3)
scroll.pack(side = RIGHT, fill = Y)
The logs are generated and are printed in that frame. Here is the code for generating and printing logs
logs = Label(frame3, text = (time.ctime()), font=("Consolas", 9), bg="#000000", fg="#ffffff")
logs.pack(pady=(0, 0))
The scrollbar is showing but it is somehow not working. The scroll is sliding if I click and slide it with the mouse. I guess there are 3 types of scrollbars in Tkinter (Correct me if I'm wrong).
window scrollbar.
Frame scrollbar.
Label Scrollbar (not sure about that).
I think the problem is that I made is a scrollbar for a frame. But, I need it for Label. Or is there any way by which I can print logs directly onto the frame? Don't know what the actual problem is. Also, is there a way by which I can make it auto scrollable when the logs are generated?
Any help would be greatly appreciated. Thanks in advance.
Here is an example using tkinter.scrolledtext:
from tkinter import *
from tkinter import scrolledtext
root = Tk()
txt = scrolledtext.ScrolledText(root)
txt['font'] = ('consolas', '12')
txt.pack(expand=True, fill='both')
txt.configure(state=DISABLED)
def log(data):
txt.configure(state=NORMAL)
txt.insert(END, data+'\n')
txt.configure(state=DISABLED)
log('abc')
log('abcde')
root.mainloop()
Hope that's helpful!
.see("end") method helps autoscroll.
Im coding my personal text editor. But i have a problem with the 2 widget text and the scrollbar (connect one scrollbar to two text).
What is my idea and logic (at the beginning)?
I want to display 2 text, one for writing text entered by user, and one to display the number of the line. I pack both of them, in the root. Then i create a scrollbar, that will scroll on Y axes the 2 text, so what i want to do (mainly) is to connect 2 widget (text) to one scrollbar.
But it didn't work.
This system absolutely doesn't work, are there any suggest or fix to fix this first idea?
Other ideas that i found.
After the first attempt, i thought that i can pack the 2 texts into 1 container. I tried to create a frame (packed into root) that contains the 2 texts, i did this because i have to connect the scrollbar only to the frame. But it didn't work, moreover it didnt allow me to write the following snippet: command=frame.yview in the scrollbar option, it seems that i cant connect frame to scrollbar.
So:
I will ask u if my reasoning are good, and how to solve. If not what can i do?
Similar question found on Google: (but that i dont undestand)
How to scroll two parallel text widgets with one scrollbar?
Tkinter adding line number to text widget
from tkinter import *
root = Tk()
root.geometry("480x540+100+100")
root.config(cursor='')
line = Text(root, bg="light grey", font="Roman 24", width=4)
line.pack(side=LEFT, fill=BOTH)
text = Text(root, bg="grey", font="Roman 24")
text.pack(side=LEFT, fill=BOTH, expand=True)
scrollbar = Scrollbar(text, orient=VERTICAL, command=(line.yview, text.yview))
text.configure(yscrollcommand=scrollbar.set)
line.configure(yscrollcommand=scrollbar.set)
scrollbar.pack(side=RIGHT, fill=Y)
for n in range(50):
line.insert("{}.0".format(n+1), "{}\n".format(n+1))
text.insert("{}.0".format(n+1), "Line no. {}\n".format(n+1))
if __name__ == '__main__':
root.mainloop()
There's nothing special about a scrollbar - it just calls a function when you move it. The API for this function is well defined. While it normally should call the yview (or xview) method of a scrollable window, there's no requirement that it must.
If you want to control two widgets with a single scrollbar, create a function for your scrollbar that scrolls both windows.
def multiple_yview(*args):
line.yview(*args)
text.yview(*args)
scrollbar = Scrollbar(text, orient=VERTICAL, command=multiple_yview)
You will have a similar problem when you scroll the text widget while entering new lines or moving around with cursor keys. You'll need to configure the yscrollcommand attribute of the text widget to call a function so that it both updates the scrollbar and also scrolls the other window (and maybe also add additional line numbers)