Python Tkinter message box with multiple text - python

http://i.imgur.com/0dLxzzc.png
How can I make the text on the right hand side(stored in variable msg2) to start from the top, ie same horizontal level as message on left hand side(msg)
Here is my code
from Tkinter import *
top = Tk()
msg = """I very soon decided that until I had done something towards naming and describing the most important groups in my collection, and had worked out some of the more interesting problems of variation and geographical distribution (of which I had had glimpses while collecting them), I would not attempt to publish my travels.GoodBye!!"""
w= Message(top,text=msg)
msg2="""I feel bound to give them full satisfaction on this point"""
v= Message(top,text=msg2)
w.grid(row=0,column=0)
v.grid(column=1,row=0)
top.mainloop()

Use sticky option (See grid documentation):
w.grid(row=0, column=0, sticky=N)
v.grid(row=0, column=1, sticky=N)

Related

How to create a ListBox widget on Customtkinter

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)

My second StringVar fails to show text, shows blank

I was writing a pixel editor in Tkinter, to practice Tkinter and GUI programming. And I was thinking to add a "bottom frame" to show informations like the current tool, the canvas size, etc. But for some reason, the second defined StringVar doesn't seems to work, while the first one works just fine. By this, I mean the code runs just fine but the second StringVar doesn't show anything.
Here is the code, for the bottom frame so far:
# Bottom frame
ttk.Style().configure('Interface.TFrame', background='#dbdbdb')
bottomframe = ttk.Frame(root, style='Interface.TFrame')
bottomframe.grid(column=0, row=2, sticky=(N, S, W, E), pady=4)
# An indicator that shows the current selected tool.
toolname = StringVar()
toolname.set('paint tool')
tool_label = ttk.Label(bottomframe, textvariable=toolname, width=11, background='#dbdbdb', anchor='center')
tool_label.grid(column=0, row=0, sticky=(W, E), padx=2)
# A thin separator.
ttk.Separator(bottomframe, orient=VERTICAL).grid(column=1, row=0, sticky=(N, S, W, E))
# An indicator that shows the canvas size.
cvsize = StringVar()
cvsize.set('50x50 px')
cv_size_label = ttk.Label(bottomframe, textvariable=cvsize, width=11, background='#dbdbdb', anchor='center')
cv_size_label.grid(column=2, row=0, sticky=W, padx=2)
So, why it's not working? The first and the second indicator look nearly same (except the bind operation) and the second one still fails. I also tried removing the first, but it also failed.
I have no idea how can I fix it. I think, I am either missing something and using the StringVar wrong, or there is something in my code that causes this behavior.
So, how can I fix it? And also, why it's happening?
EDIT: Removed the function definiton part. It wasn't really part of the question.
So, I finally understood the reason behind this behavior, thanks to #BryanOakley. Python was removing those unusued variables to free up memory. Because even though they are used in tkinter window, it doesn't really matter for Python, since the mainloop() is what organizing the window. So, it is necessary to save a reference of the variable somewhere, to prevent Python from removing it. And the easiest way of doing this, is saving the variable with self. Which won't get removed even after the class definiton ends.

Tkinter Text scroll lag issue

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.

Creating GUI with multiple function buttons

I am trying to create a GUI as shown in the attached picture
I wrote the following code which does the job but not the way I need it to.
try:
import Tkinter as tk
import tkMessageBox as mb
except ImportError:
import tkinter as tk
import tkinter.messagebox as mb
root = tk.Tk()
root.geometry("500x300")
tk.Label(root, text="Python First GUI Template", bg="goldenrod", font="bold").pack()
tk.Label(root, text="").pack()
def addFn():
a = int(input('enter first number'))
b = int(input('enter second number'))
mb.showinfo('showinfo', a+b)
def subtractFn():
a = int(input('enter first number'))
b = int(input('enter second number'))
mb.showinfo('showinfo', a - b)
tk.Button(root, text="Add Function", bg="SkyBlue1", command=addFn).pack()
tk.Label(root, text="").pack()
tk.Button(root, text="Subtract Function", bg="SkyBlue1", command=subtractFn).pack()
root.mainloop()
So, I have the following problems:
(1) I am not able to create the design as I want in the attached picture in terms of relative color and relative location of "add" and "subtract" buttons.
(2) When I hit the buttons to activate "add" or "subtract" functions, the inputs are required on the console. I need a pop up with input box and drop down for two numbers I want to add. I am looking for following format for "add" function.
(3) I want to add a "quit" button to close the console when I am done
I'm new to this myself, and unfortunately can't answer most of your questions, but regarding the quit button, I'm thinking you can write a function that calls quit(), just like you would type in order to exit the Python interactive interpreter. Then you link that function to a button just as you did for the first two buttons. This is the same idea with a lambda expression:
from tkinter import *
root =Tk()
root.geometry("500x300")
Button(root,text="QUIT",bg='Red',command=lambda:(quit())).pack(side=BOTTOM)
root.mainloop()
This here is a TKinter frame that gives you a red quit button at the bottom whose sole reason for existence is to quit the frame it's in.
Regarding the layout, I think the pack method requires you to indicate where pack should prefer to put the widget, but doesn't give you much absolute control. Wouldn't grid method allow for better alignment?
Why do your input boxes have to pop out? Why can't they be embedded into the app frame? I would think that would eliminate some difficulty with the issue, no?
Sorry this isn't the most helpful answer ever... but I hope it gives you something to work with until someone more knowledgeable happens by. Cheers.
There are a couple of ways you could do this, the simplest being using .grid() instead of .pack():
from tkinter import *
root = Tk()
title = Label(root, text="Python First GUI Template")
add = Button(root, text="Add")
subtract = Button(root, text="Subtract")
_quit = Button(root, text="Quit")
title.grid(row=0, column=1, padx=5, pady=5)
add.grid(row=1, column=0, padx=5, pady=5)
subtract.grid(row=1, column=2, padx=5, pady=5)
_quit.grid(row=2, column=3, padx=5, pady=5)
root.mainloop()
.grid() allows you to place widgets on the window in a grid fashion, imagine there are cells which you are placing each widget into, whereas .pack() by default will place items stacked on top of eachother unless certain attributes are given values.
You could also use .place() which allows you to place the widgets based on coordinates but this requires a lot more effort make responsive to window size changes or adding new widgets and the like.
On a side note, Stack Overflow is not a free programming resource, we will not write programs for you based on a list of demands. There are plenty of freelance programmers who are happy to do that in exchange for money. I would recommend in future that rather than asking a question about an incredibly well documented library with over 17000 questions on Stack Overflow, a large number of which are about the difference in the three geometry managers you instead find a tutorial or ask a colleague, schoolmate, teacher or friend for help.

tkinter puts WAY too much space between checkbuttons

I can't figure out how to get tkinter to put checkbuttons and radiobuttons closer together. Even specifying pady=0 anyplace it seems valid has no effect. The vertical distance between the buttons is unnaturally large, ugly, and just wastes space. In order to make a set of buttons appear as a group separate from other controls requires that I add extra space elsewhere, which just gets out of control.
Here's a working example I extracted:
from Tkinter import *
def rbtest(frame):
group = LabelFrame( frame, text="Target", padx=0, pady=0)
btnVal = StringVar(frame,' ')
for b in ( "option1", "another option", "Someth Else", "go away"):
rb=Radiobutton( group, text=b, value=b, variable=btnVal)
rb.pack( anchor=W, pady=2)
boardname = StringVar()
Label( group, text="Name").pack( anchor=W)
Entry( group, text=boardname).pack()
group.pack( side=LEFT, fill=Y, padx=0, pady=0)
tk = Tk()
rbtest(tk)
tk.mainloop()
[Well, I can't post an image showing what it produces because I don't have enough reputation, so sorry about that... I tried.]
Edit: I'm using Python 2.6.6 and Windows 7.
Considering how closely together it packs other elements, I'm surprised this is normal behavior, but all the examples I've found on the web look similar...
I ran your code on a Mac and on a windows box, and in both cases it looked about right to me. If you want them literally as close as possible, set the borderwidth to zero and the pady option to zero.
To eek out another two pixels between each button, set the highlightthickness to zero, though that affects the user experience when they are using keyboard traversal.
It looks pretty normal to me:
If it really needs to be made super-compact, there are ways of doing so, but I suspect your system is rendering the window differently.

Categories

Resources