For a few weeks I've been busy creating a program for the Dutch railroads.
Using Tkinter and Python I've managed to monitor all trains driving and all trainfailures.
At the moment I'm having a problem monitoring the trainfailures. I made a button that says: 'Laad storing' (or: Load all failures). This button then uses an API to create a Listbox.
After that I would like to search the Listbox for certain values (Like 'Station Amsterdam, or Station Utrecht). I would like to have this certain value highlighted. (So and CTRL+F sort of function).
Anyone who could help me?
Here is my code creating the listbox:
def bevestigen_storingen():
actuele_storingen = 'http://webservices.ns.nl/ns-api-storingen?station=&actual=true&unplanned=true'
response_storing = requests.get(actuele_storingen, auth=login_api)
storingXML = xmltodict.parse(response_storing.text)
listbox_storing.delete(0, 'end')
storingenInvoer_autocomplete.configure(highlightbackground='#00339E', highlightthickness=0)
try:
for vertrek in storingXML['Storingen']['Gepland']['Storing']:
traject = vertrek['Traject']
bericht = vertrek['Bericht']
bb = re.sub("<p>|</p>|<b>|</b>|<br/>|<br/>u", "", bericht)
aa = re.split("Wanneer: |Oorzaak: |Advies: |Extra reistijd: ", bb)
listbox_storing.insert(END, "Traject: {}".format(traject))
listbox_storing.insert(END, "Wanneer: {}".format(aa[1]))
listbox_storing.insert(END, "Oorzaak: {}".format(aa[2]))
listbox_storing.insert(END, "Advies: {}".format(aa[3]))
listbox_storing.insert(END, "Extra reistijd: {}".format(aa[4]), "\n")
except:
storingenInvoer_autocomplete.configure(highlightbackground='#00339E', highlightthickness=3, highlightcolor="red")
The listbox is a widget that contains a list of strings, so I'd search it the way I'd search a list of strings. The methods are a bit different but that should not be a problem.
I'm not clear wether you want to highlight single words or the whole line. As far as I've been able to understand you can only select one or several entire lines.
Have a look at The Tkinter Listbox Widget
Related
Is it utterly impossible to receive a list from user input in Tkinter? Something along the lines of an HTML textarea box - where a user can (1) copy and paste a list of things into a text box, and then (2) tkinter translates the input list into a list of strings, then (3) can assign them to a value and do fun python stuff etc
I have reasonable faith I can accomplish parts (2) and (3), but I'm stuck on (1).
I have explored Entry, which basically accomplishes that but awkwardly and with poor visibility onto the pasted items in the tiny Entry box. I have explored Listbox, which doesn't allow user input in the way of generating a new list from nothing?
The running example is: if I want to input some groceries into a variable, I can copy-paste a text list and paste as one item (rather than separately) --
eg: ["apples", "oranges", "raspberries"] clicks submit VS ["apples"] clicks submit ["oranges"] clicks submit ["raspberries"] clicks submit
-- Anyone have any recommendations for that elusive textarea-like input box for tkinter? Do I just wrestle with the Entry tiny box?
You want a tkinter.Text
import tkinter as tk
# proof of concept
root = tk.Tk()
textarea = tk.Text(root)
textarea.pack()
root.mainloop()
You can retrieve the text with textarea.get in the normal way
result = textarea.get(1.0, 'end') # get everything
result = textarea.get(1.0, 'end-1c') # get exactly what the user entered
# (minus the trailing newline)
When I enter nothing in the text and click enter, it counts the length of the text as 1, which means there is something there. (Presumably a space), and entering an actual space in the text box increases the count by 1. I want to know how to check if the textbox is empty or not. If nobody enters anything in the textbox I want a way to see that.
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
def submitted(*args): #Progressbar is set to be fully completed and states information recorded
print(len(t.get("1.0", END)))
if len(t.get("1.0", END))==1:
messagebox.showinfo("Error", "No information entered in description.")
#Sets title and creates gui
root=Tk()
#Creates text widget
t = Text(root, width=20, height=10)
t.grid(column=0,row=1)
#Submitting calls submitted function to set progressbar to 100 and statemessage box has been completed
subbttn= ttk.Button(root, text="Submit", command=submitted)
subbttn.grid(column=1, row=1, sticky=(S, W, E))
If you print out the content of the empty text box, you will see that there is a "\n", newline character. This is what is causing you to see that there is a length of 1 for an empty text box.
If you wanted to see if it was empty, you could check if there is just one new line. Or, like you are already doing, check if len(t.get("1.0", END) is one.
if t.get("1.0", END)=="\n":
instead of:
if len(t.get("1.0", END))==1:
I am working on a python program and none of the above solutions works for me except this one: len(t.get("1.0", END))>=1. It spots the existence or not of one or more characters in the text box.
I'm new at Tkinter, and python. I've been experimenting with a notepad script I've made. I'm working on a find / replace command. But I've had no luck. Here is what I've tried so far:
def replace():
def replaceall():
findtext = str(find.get(1.0, END))
replacetext = str(replace.get(1.0, END))
alltext = str(text.get(1.0, END))
alltext1 = all.replace(findtext, replacetext)
text.delete(1.0, END)
text.insert('1.0', alltext1)
replacebox =Tk()
replacebox.geometry("230x150")
replacebox.title("Replace..")
find = Text(replacebox, height=2, width=20).pack()
replace = Text(replacebox, height=2, width=20).pack()
replaceallbutton = Button(replacebox, text="Replace..", command=replaceall)
replaceallbutton.pack()
(this is just the function I am defining for the replace command)
The 'text' variable is on the large canvas which contains the menu's and the main text widget.
Any help is appreciated
So far I've been creating this notepad in 2.7.8, so the Tkinter import is 'Tkinter.'
What I'm shooting for is having the first box have the text to find and the second box have the text to be replaced. Upon pressing the replace button, the function replaceall() should begin.
Are there any obvious mistakes in my function, or is it just deeply flawed? Any help is appreciated.
The most obvious mistake is that you are creating a second instance of Tk. If you need a popup window you should create an instance of Toplevel. You should always have exactly one instance of Tk running.
The second problem is related to the fact you are using a Text widget for the find and replace inputs. When you do a get with a second index of END, the string you get back will always have a newline whether the user entered one or not. If you want exactly and only what the user typed, use "end-1c" (end minus one character).
Finally, there's no reason to get all the text, replace the string, and then re-insert all the text. That will work only as long as you have no formatting or embedded widgets or images in the text widget. The text widget has a search command which can search for a pattern (either string or regular expression), and you can use the returned information to replace the found text with the replacement text.
I am using tkinter with python to produce a quote gui. I have 3 entry widgets (code, price and quantity) and a "Add Line" button. When the button is pressed, I want it to take the text from each of the entry widgets and update it in the scrollable "text" widget that is located in the same window (so the user can review each line in the overall quote before submitting the final product). Any ideas?
For info, once the text widget is full of all the lines that the user wants to include in the quote, pressing another button (eg Submit) will write all of the lines into a preformatted Word document. I have his part sorted, but cannot find how to do the first part above. Any ideas.
To get the values from an Entry widget, use the get method. To insert values into a text widget use the insert method. These are both documented, and there are examples all over the internet.
def add_line():
code = codeEntry.get()
price = priceEntry.get()
quantity = quantityEntry.get()
quote.insert("end","code: %s price: %s quantity: %s\n" % (code,price,quantity))
I am reading a yml form file and getting its contents as columns in urwid.
I have to display these columns onto the console.
If I use a plain listbox and listwalker then I am able to get the columns displayed on the screen.
However I need to group some of the columns as a block and show it in a linebox widget.
How can I do so ?
Each of my column widget has two columns, the first one being text widget and second one being edit widget.
This is what I tried :
tried to created a pile of columns by appending to a pile named as blockPile (declared as blockPile = urwid.Pile([ ]) ) as in below :
blockPile.contents.append(columnEntry, options='pack')
but got this error
TypeError: append() got an unexpected keyword argument 'options'
then removed the options and used this :
blockPile.contents.append(columnEntry)
but got following error
urwid.container.PileError: added content invalid: <Columns selectable box/flow widget>
Next I used listbox
blockContent = urwid.SimpleListWalker([])
blockListbox = urwid.ListBox(blockContent)
and used append to fit my columns inside listBox
blockContent.append(columnEntry)
Finally to put the listbox in a box adapter
box = urwid.BoxAdapter(blockContent, height = 20)
and then return it in a linebox
return urwid.LineBox(box, title='|** Block **|')
but now I get following error
AttributeError: 'SimpleListWalker' object has no attribute 'selectable'
Everything works fine if I use only a listbox and a listwalker and don't fit the listbox inside anything else.
But I want the list box of columns to be put in a linebox. How can I do so ?
It's been a long time since I've played with urwid, but I think in urwid, in order to get a set of elements behave like a listWalker, you have to set an selectable attribute.
In this old code: https://github.com/Nic0/tyrs/blob/master/src/tyrs/widget.py#L95
I had to set the attribute selectable to True in my object containing a bunch of stuff, which give a twitter's status.
def selectable (self):
return True
Anyway, you might want to the code to give you an idea.
Hope it helps.