Read one line at a time from tkinter textbox - python

I can read one line at a time, from an input box, and display it in a new box, but I need to advance to the next line of code.
Here are the text boxes in the GUI
self.sourcecode = Text(master, height=8, width=30)
self.sourcecode.grid(row=1, column=1, sticky=W)
self.nextline = Button(master, text="Next Line", fg="orange", command=lambda:[self.nextLine(self.intcount), self.lexicalResult()])
self.nextline.grid(row=12, column=1, sticky=E)
self.lexicalresult = Text(master, height=8, width=30)
self.lexicalresult.grid(row=1, column=3, sticky=W)
These are my functions to copy from one box, to the other (output would insert() into the lexicalResult() function)
def nextLine (self, intcount):
print("Reading from source")
self.linenumber.delete('1.0', END)
self.intcount = self.intcount + 1
self.linenumber.insert('0.0', self.intcount)
self.retrieve_input()
def retrieve_input(self):
lines = self.sourcecode.get('1.0', '2.0') #I need to take this and move to the next line but i am new to python and don't know what functions there are or their arguments
self.lexicalresult.insert('1.0', lines)
def lexicalResult (self):
print("Printing to result")

You can read a single line of text by using the "lineend" modifier on an index. For example, to get all of line 1 you could use something like this:
text.get("1.0", "1.0 lineend")
That will get everything on the line except the trailing newline. If you want the trailing newline, get just one character more:
text.get("1.0", "1.0 lineend+1c")
To delete an entire line you could use the very same indexes and pass them to the delete method.
As a more general purpose rule, given any index, to compute the beginning of the next line you can use something like this:
next_line = text.index("{} lineend+1c".format(index))
The index method converts an index into it's canonical form. The "lineend" modifier changes the index to the end of the line, and +1c moves it one character further.

Related

searching in strings from tk-inter text fails

Why does the search fail when taking a string from a tk-inter text box?
The search works fine if I define the keyword as a string.
Minimal example:
import tkinter as tk
root = tk.Tk()
string="banana\napplepie\napple\n"
def searchcall():
textboxcontent=textExample.get("1.0","end")
keyword=filterbox.get("1.0","end")
keyword="apple" # search works as expected
print("keyword",keyword)
print("is keyword in textbox",keyword in textboxcontent)
for elem in textboxcontent.split():
print("seaching for",keyword,"in",elem,keyword in elem)
textExample=tk.Text(root, height=10)
textExample.insert(1.0,string)
textExample.pack()
filterbox=tk.Text(root, height=1)
filterbox.insert(1.0,"apple")
filterbox.pack()
btnRead=tk.Button(root, height=1, width=11, text="search",
command=searchcall)
btnRead.pack()
root.mainloop()
The problem is that tk inter appends a line break "\n" at the end when you read the contents of a widget.
Remove the "\n" at the end of the strings. For example, with strip
keyword=filterbox.get("1.0","end").strip()
you can also choose to read everything but the last character like this (source):
keyword=filterbox.get("1.0",'end-1c')

How do I check if a StringVar in an Input is empty

Trying to make a button to create a file name with an input of a text variable, I'm trying to make an input that would be the "default" if the actual text box is empty, my code is as follows
def makefile():
try: prefix_text.get()
except NameError: prefix_text = None
if prefix_text is None:
prefix_text=StringVar()
prefix_text.set("Kido")
ply = open(prefix_text.get()+"_Player_.uc", "w")
ply.close()
window=Tk()
l1=Label(window, text="Prefix")
l1.grid(row=0, column=0)
prefix_text=StringVar()
e1=Entry(window, textvariable=prefix_text, width=42)
e1.grid(row=0, column=1)
b1=Button(window, text="Create File", width=12, command=makefile)
b1.grid(row=1, column=1)
window.mainloop()
MakeFile is supposed to test if the input is empty before making the file and if it is empty just set the name to be Kido, however this somehow will always cause the name to be Kido instead of the input
I've tried various things to no avail and nothing I can seem to find gives me good input on how to check if that variable is null, any help would be much appreciated!
To check if the entry is empty just check the linked variable prefix_text. Also be sure to use prefix_text.get() instead of just prefix_text.
def makefile():
global prefix_text
try: prefix_text.get()
except NameError: prefix_text = None
if not prefix_text.get().strip(): # if blank entry
prefix_text.set("Kido") # set entry
ply = open(prefix_text.get()+"_Player_.uc", "w")
ply.close()

How to store the input from the text box in python?

I want to make a program that show me the divisors of the number introduced in a text box using python tkinter GUI and store the results into a plain text file.
I don't how to get the value from the text box. I understood that is something linked with get() , I read something but I still don't get it.
Here is the code:
from tkinter import *
def create_file():
file_object = open("C:/Users/valis/Desktop/Divisors.txt","w+")
def evaluate():
show_after= Label(text= "Check your Desktop !")
show_after.pack(pady=2, anchor=SW)
create_file()
#Windows size and Title
window = Tk()
window.title("Show Divisors")
window.geometry("300x100")
message = Label(window, text="Enter a number : ")
message.pack(pady=2, anchor=NW)
textbox_input = Text(window,height=1, width=11)
textbox_input.pack(padx= 2,pady= 2, anchor=NW)
window.mainloop()
The code isn't complete, so what should I do ?
As you said, you will use the get() function but with some additional attributes.
If we have a text box textbox_input, then you can return its input using this line:
test_input = textbox_input.get("1.0",END)
The first part, "1.0" means that the input should be read from line one, character zero (ie: the very first character). END is an imported constant which is set to the string "end". The END part means to read until the end of the text box is reached.
Reference: This answer.

How does adding tags change a text file - Tkinter?

I am a beginner in Tkinter and I am currently trying to create an interface, which runs a program which checks for the 'correctness' of formal specifications. What this program does is checks whether a written specification meets certain criteria - checks whether all terms used are declared, etc.
Anyway, I am trying to add a search button, which changes the color of a key words, when they are found in the text - I use tags and it works ok. The problem is, after I have used my search function (i.e. have added tags and then removed them, when clicking on save) the program which checks for the 'correctness' of the specification doesn't run properly, even on files which have been checked and shown correct. I get the following error:
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1193, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
TclError: invalid command name ".43965456"
I have no idea what this might mean. I was just wondering whether adding tags changes a text file in some way (apart from changing the color of key words), which might mess up with the program, which checks for 'correctness'.
Here is my Search function:
def searchWindowButton(self,event):
self.top = Toplevel()
self.top.title("Search")
Label(self.top,text='Text to find:').pack(side=LEFT)
self.edit = Entry(self.top)
self.edit.pack(side=LEFT, fill=BOTH, expand=1)
self.edit.focus_set()
button = Button(self.top, text="Search", command = self.on_button)
button.pack(side=LEFT)
def find(self):
self.txt.tag_remove('found', '1.0', END)
s = self.edit.get()
if s:
idx = '1.0'
while 1:
idx = self.txt.search(s, idx, nocase=1, stopindex=END)
if not idx: break
lastidx = '%s+%dc' % (idx, len(s))
self.txt.tag_add('found', idx, lastidx)
idx = lastidx
self.txt.tag_config('found', background='green', foreground='black')
self.edit.focus_set()
def on_button(self):
self.find()
self.top.destroy()
And this is my Save function:
def saveMenu(self):
try:
self.txt.tag_remove("found", "1.0", 'end')
fileName=self.fl
fl = open(fileName, 'w')
textoutput = self.txt.get(0.0, END)
fl.write(textoutput)
except:
self.save_asMenu()
I was just wondering whether adding tags changes a text file in some
way (apart from changing the color of key words)
No, adding tags has absolutely zero effect on a text file.
TclError: invalid command name ".43965456" means that a widget with the internal id of .43965456 has been destroyed prior to you calling whatever function triggers the error.

Python Tkinter Help Menu

I have a paragraph of help information that I would like to display in a window with an "ok" button at the bottom. My issue is formatting...I want to be able to simply set the paragraph equal to a variable and then send that variable to a message box widget. By default, it formats laterally and in a very ugly manner. Any advice?
def aboutF():
win = Toplevel()
win.title("About")
about = "Top/bottom 3 - Reports only the top/bottom 3 rows for a param you will later specify.\
Set noise threshold - Filters results with deltas below the specified noise threshold in ps.\
Sort output - Sorts by test,pre,post,unit,delta,abs(delta).\
Top 2 IDD2P/IDD6 registers - Reports only the top 2 IDD2P/IDD6 registers.\
Only critical registers - Reports only critical registers.\
Use tilda output format - Converts the output file from csv to tilda.\
Use html output format - Converts the output file from csv to html."
Label(win, text=about, width=100, height=10).pack()
Button(win, text='OK', command=win.destroy).pack()
Use a text widget with word wrapping, and either define your string more accurately or do a little post-processing to remove all that extra whitespace. Using the code from this answer makes it easy to use multiple colors, fonts, etc.
For example:
import Tkinter as tk
import re
class CustomText(tk.Text):
'''A text widget with a new method, HighlightPattern
example:
text = CustomText()
text.tag_configure("red",foreground="#ff0000")
text.HighlightPattern("this should be red", "red")
The HighlightPattern method is a simplified python
version of the tcl code at http://wiki.tcl.tk/3246
'''
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
def HighlightPattern(self, pattern, tag, start="1.0", end="end", regexp=True):
'''Apply the given tag to all text that matches the given pattern'''
start = self.index(start)
end = self.index(end)
self.mark_set("matchStart",start)
self.mark_set("matchEnd",end)
self.mark_set("searchLimit", end)
count = tk.IntVar()
while True:
index = self.search(pattern, "matchEnd","searchLimit",count=count, regexp=regexp)
if index == "": break
self.mark_set("matchStart", index)
self.mark_set("matchEnd", "%s+%sc" % (index,count.get()))
self.tag_add(tag, "matchStart","matchEnd")
def aboutF():
win = tk.Toplevel()
win.title("About")
about = '''Top/bottom 3 - Reports only the top/bottom 3 rows for a param you will later specify.
Set noise threshold - Filters results with deltas below the specified noise threshold in ps.
Sort output - Sorts by test,pre,post,unit,delta,abs(delta).
Top 2 IDD2P/IDD6 registers - Reports only the top 2 IDD2P/IDD6 registers.
Only critical registers - Reports only critical registers.
Use tilda output format - Converts the output file from csv to tilda.
Use html output format - Converts the output file from csv to html.'''
about = re.sub("\n\s*", "\n", about) # remove leading whitespace from each line
t=CustomText(win, wrap="word", width=100, height=10, borderwidth=0)
t.tag_configure("blue", foreground="blue")
t.pack(sid="top",fill="both",expand=True)
t.insert("1.0", about)
t.HighlightPattern("^.*? - ", "blue")
tk.Button(win, text='OK', command=win.destroy).pack()
root=tk.Tk()
aboutF()
root.mainloop()

Categories