How to copy data from one Tkinter Text widget to another? - python

from Tkinter import *
root = Tk()
root.title("Whois Tool")
text = Text()
text1 = Text()
text1.config(width=15, height=1)
text1.pack()
def button1():
text.insert(END, text1)
b = Button(root, text="Enter", width=10, height=2, command=button1)
b.pack()
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)
text.config(width=60, height=15)
text.pack(side=LEFT, fill=Y)
scrollbar.config(command=text.yview)
text.config(yscrollcommand=scrollbar.set)
root.mainloop()
How can I add the data from a text widget to another text widget?
For example, I'm trying to insert the data in text1 to text, but it is not working.

You are trying to insert a Text reference at the end of another Text widget (does not make much sense), but what you actually want to do is to copy the contents of a Text widget to another:
def button1():
text.insert(INSERT, text1.get("1.0", "end-1c"))
Not an intuitive way to do it in my opinion. "1.0" means line 1, column 0. Yes, the lines are 1-indexed and the columns are 0-indexed.
Note that you may not want to import the entire Tkinter package, using from Tkinter import *. It will likely lead to confusion down the road. I would recommend using:
import Tkinter
text = Tkinter.Text()
Another option is:
import Tkinter as tk
text = tk.Text()
You can choose a short name (like "tk") of your choice. Regardless, you should stick to one import mechanism for the library.

Related

How to hide scrollbar when Text widget is not scrollable in tkinter

I am writing a program in python in which I want the Text widget in tkinter to have a scrollbar .
this is a part of my code -
import tkinter as tk
import tkinter.font as tkfont
window = tk.Tk()
display_text = "START\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nEND"
font_1 = tkfont.Font(family='Helvetica', size=22, weight='bold')
my_label_1 = tk.Text(window, wrap=tk.WORD, bd=0, fg="white", bg="black", font=font_1, width=76, height=21,)
_scrollbar = tk.Scrollbar(window, command=my_label_1.yview)
my_label_1.configure(yscrollcommand=_scrollbar.set)
my_label_1.tag_configure("center", justify='center')
my_label_1.insert(1.0, display_text)
_scrollbar.pack(side=tk.RIGHT, ipadx=3, ipady=500, pady=(0, 48))
my_label_1.pack()
window.mainloop()
But I have 500 strings which I import from a csv file, when I put the strings in this code the strings go in disply_text variable, this works fine.
But for some of those strings the text widget is big enough and the scrollbar is not needed as the text widget is not scrollable for those. but the scrollbar still shows up it is disabled though but I don't want it to be there.
I know pack_forget() or grid_forget() can do this job, But Then what parameter should I put so I know that this iteration of text is not scrollable on the Text widget.
And my window is of fixed size i.e. window.resizable(False, False).

Python - Printing to GUI instead of terminal

Very new to Python here, and I'm trying to create a GUI app that returns a random recipe. Currently the print happens at the terminal, and I'd like it to print in the GUI instead.
from tkinter import *
import os
import random
root = tk.Tk()
def printRecipes():
recipes = [
"Tom Yum Soup",
"Carnitas",
"General Tso's Chicken"
]
print(random.choice(recipes))
canvas = tk.Canvas(root, height=600, width=700, bg="#A8D1BB")
canvas.pack()
magic = tk.Button(root, text="Print", padx=10, pady=5, fg="white", bg="black", command=printRecipes)
magic.pack()
root.mainloop()
This doesn't work, as most of you already know. I've read that I need to use a label or text for it, but the example I've found all involved static print statements like
label = Label(root,text="Recipe")
label.pack
To "print" a value to a GUI Window, a Label is used. .config() is a useful function. It is used to configure the provided widget.
Below magic.pack(), add this code. Notice that there is no text parameter. We will use that later.
label1=Label(root,pady=10,font=("arial",15))
label1.pack()
Next, in the function, where you had print(random.choice(recipes)), we will add:
label1.config(text=random.choice(recipes))
Notice that we used .config() and the text parameter. We configured the label, and added some text to it.
You need a tk.StringVar for this, i.e. a variable which you can change and the label can read from:
label_str = tk.StringVar(value="Some text")
label = tk.Label(root, textvariable=label_str)
Then, to update the value of this label and show it on the GUI:
label_str.set("New text")
label.update()

Prevent scrolledtext from taking up entire parent window disallowing other widgets from showing up

So I am actually writing a simple GUI program which makes use of ScrolledText widget from tkinter.scrolledtext module.
The problem is this ScrolledText widget seems to take up the complete space available in the parent window. It disallows me from putting in any other widget in the same parent window. I have tried using both grid and pack GeoManagers (i know place isn't very useful in all cases), but the other widgets won't show up (neither above the scrolledtext widget nor below it).
HERE IS THE CODE--
import tkinter as tk
import tkinter.scrolledtext as sct
win2 = tk.Tk()
win2.geometry('1150x680')
win2.wm_geometry('+80+20')
txtbox = sct.ScrolledText(win2, width=500, height=350, bg='#fff', fg='#00f')
txtbox.grid(row=0, column=0)
txt = '<ABOUT 60 Lines TEXT HERE>'
txtbox.insert(1.0, txt)
txtbox.configure(state=tk.DISABLED)
tk.Button(win2, text='Got It', command=win2.destroy).grid(row=1, column=0)
This code is actually a part of a static method (i don't think makes a difference). When this is run the only thing visible on the screen is the scrolledtext widget with those 60 lines (i have tried it with 2 lines as well - still doesn't work).
The same happens when using pack().
To my surprise the only thing i could find in documentation is this::
ScrolledText Documentation
I don't know what I am missing here so please suggest me a way around this.
Thanks You :)
Solution with grid
The problem is the configuration of the grid: by default, the grid cells expand to fit the content. In your case the text widget is so big that the button in the row below is out of the screen. To fix that, you need to configure the first row and column to stretch with the GUI:
win2.rowconfigure(0, weight=1)
win2.columnconfigure(0, weight=1)
and make the text widget fill the cell, using the sticky option:
txtbox.grid(row=0, column=0, sticky='ewns')
This way the text widget will adapt to the window size and not the other way around.
Full code:
import tkinter as tk
import tkinter.scrolledtext as sct
win2 = tk.Tk()
win2.geometry('1150x680')
win2.wm_geometry('+80+20')
win2.rowconfigure(0, weight=1)
win2.columnconfigure(0, weight=1)
txtbox = sct.ScrolledText(win2, width=500, height=350, bg='#fff', fg='#00f')
txtbox.grid(row=0, column=0, sticky='ewns')
txt = '<ABOUT 60 Lines TEXT HERE>'
txtbox.insert(1.0, txt)
txtbox.configure(state=tk.DISABLED)
tk.Button(win2, text='Got It', command=win2.destroy).grid(row=1, column=0)
Alternative method, using pack
You can use pack with the options fill='both' and expand=True to achieve the same result as with grid. In this case, the additional trick is to pack the button first to ensure that it has enough space to show in the window. Code:
import tkinter as tk
import tkinter.scrolledtext as sct
win2 = tk.Tk()
win2.geometry('1150x680')
win2.wm_geometry('+80+20')
tk.Button(win2, text='Got It', command=win2.destroy).pack(side='bottom')
txtbox = sct.ScrolledText(win2, width=500, height=350, bg='#fff', fg='#00f')
txtbox.pack(fill='both', expand=True)
txt = '<ABOUT 60 Lines TEXT HERE>'
txtbox.insert(1.0, txt)
txtbox.configure(state=tk.DISABLED)

How to Display Multiple Labels in One Line with Python Tkinter?

I have a Program that displays text on GUI Screen with Multiple Labels. But all the Labels are showing text in the new line and I want to show text in single line. Code is Below:
from tkinter import *
import tkinter as tk
win = Tk()
win.title("Label Screen")
win.geometry("800x600+50+50")
win.config(bg='white')
label1=Label(win, text="Label 1", font=("Calibri",24,"bold"), bg='white')
label1.pack(pady=15)
label2=Label(win, text="Label 2", font=("Calibri",24,"bold"), bg='white')
label2.pack(pady=15)
label3=Label(win, text="Label 3", font=("Calibri",24,"bold"), bg='white')
label3.pack(pady=15)
win.mainloop()
Output:
By default, the pack() method packs to the top, so you'll get a vertical stack of labels by default. You want to pack to the left to easily get all the labels on the same row. To do that, change:
labelX.pack(pady=15)
to
labelX.pack(side=tk.LEFT, pady=15)
Also, it's not ideal to import tkinter twice. Best to import it just once, as
import tkinter as tk
and then make sure to use tk. before all the methods, attributes, and classes.
Do this :
label1.pack(side=tk.LEFT,pady=15)
label2.pack(side=tk.LEFT,pady=15)
label3.pack(side=tk.LEFT,pady=15)
Further read : https://effbot.org/tkinterbook/pack.htm

python tkinter popup window with selectable text

I want to make popup window using Tkinter.
I can do it so:
import Tkinter
a="some data that use should be able to copy-paste"
tkMessageBox.showwarning("done","message")
But there is one problem that user need to be able to select, copy and paste shown text.
It's not possible to do in such way.
Are there any ways to do it with Tkinter? (or another tools that is supplied with python by default)
Thanks in advance for any tips
From here, it seems a workaround using Entry in Tkinter is doable. Here is the code:
import Tkinter as Tk
root = Tk.Tk()
ent = Tk.Entry(root, state='readonly')
var = Tk.StringVar()
var.set('Some text')
ent.config(textvariable=var, relief='flat')
ent.pack()
root.mainloop()
EDIT: To respond to your comment, I found a way to insert multi-line text, using the Text widget.
Here is a draft of a solution:
from Tkinter import *
root = Tk()
T = Text(root, height=2, width=30, bg='lightgrey', relief='flat')
T.insert(END, "Just a text Widget\nin two lines\n")
T.config(state=DISABLED) # forbid text edition
T.pack()
mainloop()
I'm (still) interested in any better solution :)
You can use buttons for copy and paste. First you need to select. In a text widget it is easily done by
selection=nameoftextwidget.get(SEL_FIRST,SEL_LAST)
Then you can use this for copying easily by the use of selection. If you want to copy/paste it in that same text widget, you can use:
nameoftextwidget.insert(END,"\n"+selection)

Categories

Resources