I am trying to create a program in tkinter that allows people to rename a log file to whatever is typed into a text entry box. However this is not going to plan.
EDITED Thanks to Bryan Oakley.
I have slaved the rename function to a button however my new issue is that the values for contents are a weird set of numbers. These appear to be randomly generated every time I run the rename function.
These numbers look like
44499952get
44452520get
46401376get
46400496get
44688048get
44697440get
Can anyone please help or explain what these numbers mean?
Look at this code:
newname_ent = Entry(self,width = 50,)
contents = newname_ent.get()
It seems highly unlikely that the user will be able to type in something in the millisecond or so between creating the widget and getting the value.
You need to create a button or set an event binding that will call a function after the user has the chance to enter some information. That function is where you will put the code to do the rename.
Related
I am trying to implement a little application that logs in a user and the user after log in can add/update/delete contents to/of a textfile. Here's a rough sketch of the code I have so far:
class admin():
def __init__(self):
self.app = Tk()
.
self.name=StringVar()
update = Button(self.app,....,command=self.update)
.
.
.
def update():
#Function to take different entries using Entry widget of tkinter in another window
anotherapp = Tk()
nameentry = Entry(anotherapp,textvariable = self.name)
submitbutton = Button(anotherapp,....,command=submit)
.
.
def submit():
#Opens a file and adds entries to a textfile.
namevar = self.name.get()
# code to append to file
To explain the above, I have a class admin. Creating an instance of this class would open a window with buttons that say create, update, delete and so on. On clicking one of the buttons, the respective functions (defined in the same class) would be called (I use lambda: in case the function has arguments, but so far, it doesn't).
So in the code I've mentioned, say I click on the Update button, it should call the update function which opens another window and takes the text that has to be updated in the text file (via the Entry widget). So according to the code it'll update the value of name. On clicking submit, the function submit uses .get() to get the string value of name, and appends it to the text file.
The code executes with no error but it DOES NOT read the input from the user. Blank lines get appended to my textfile when I click on the submit button.
Now I don't understand why this isn't working. The name variable is defined in init and can be updated by the functions of the same class. I have tried a lot of things to make this work, including adding parameters in the button commands, defining name elsewhere, etc. Even though I've solved the error, I get the same result: the file gets appended with blank lines. I've also tried to make name a class variable but that doesn't work since it is declared using StringVar() which needs it to be part of a tkinter window. I think I've also tried nesting submit function inside the update function, but I don't know why that didn't work out or if I hadn't implemented it correctly.
I don't know if it has to do with the working of tkinter's StringVar() and .get() function.
I can't think of any other way to implement the situation I have at hand. I am open to taking suggestions on changing the structure of the code, as long as it is not something major major and manages to achieve the functionality that I've described.
I am sorry if I've missed something basic, cause I've only started trying out OOP in python recently. And thanks in advance for any help.
I am trying to recreate the notepad. I have added a lot of shortcut keys with a combination of two keys. I am trying to make a three combination shortcut, which will be Ctrl+Shift+s. But when I used <Control-Shift-Key-s> it's not working. I had even tried app.bind<Control-Shift-KeyPress-s> which I found at the Control+Shift+Tab key binding in stack overflow. When I used Tab instead of s that worked, when I use s nothing happens. I want to create a key binding of Control+Shift+s. How Can I Do That?This Is My Code:
from tkinter import *
app = Tk()
def SaveAs(event):
#Some code to save as new file.
print('Pressed Ctrl+Shift+s.')
app.bind_all('<Control-Shift-Key-s>', SaveAs)
Make sure that you are not mixing up uppercase and lowercase, because in Tkinter, "<Control-S>" means CTRL-SHIFT-S and "<Control-s>" means CTRL-S.
So, this line:
app.bind_all('<Control-Shift-Key-s>', SaveAs)
must be
app.bind_all('<Control-S>', SaveAs)
In short, i try to type letters (in input components like "Entry", "Text") that are allowed by Windows language-keyboard (i'm using "Latvan(QWERTY)" keyboard) and i can't write long letters like 'ā', 'č', 'ģ' and others.
For example, when i try to write 'ā', the result is 'â'.
The interesting part - when i focus on specific GUI input fiend and change Windows keyboard-language (with "Alt+Shift" shortcut or manually) twice (for example, from "Latvan(QWERTY)" to "Russian" and back to "Latvan(QWERTY)") - then i can write all letters i needed.
What i want is to set all input fields keyboard-language so i could write all letters i want without doing things mentioned above every time i launch my GUI program.
If you need more info or there is already place where this question is answered, please leave a comment and i will act accordingly.
Edit 1:
I am using PyCharm to write my Python Tkinter code. I tried to assign necessary keyboard to my program's generated GUI form according to this guide but it didn't work (i guess that because i used it on temporary created GUI forms).
I was able to solve my problem by using pynput.
Here is simplified version of my final code:
from tkinter import *
from pynput.keyboard import Key, Controller
def change_keyboard_lang(event):
keyboard = Controller()
for i in range(2):
keyboard.press(Key.alt)
keyboard.press(Key.shift_l)
keyboard.release(Key.shift_l)
keyboard.release(Key.alt)
root = Tk()
word_input = Entry(root)
word_input.focus_set()
word_input.bind("<FocusIn>", change_keyboard_lang)
word_input.pack()
root.mainloop()
In short, if cursor is focused on Entry field "word_input", system calls function "change_keyboard_lang" that changes input language from original to other and back to original - and now i can write necessary letters.
It's not the best solution since i need to bind event to every input field in my GUI form but it gets the job done. If you have a better solution please post it here.
I have a QListWidget that has 10 QListWidgetItems. When each of those QListWidgetItems is created I do something like this:
item = QtGui.QListWidgetItem("Text to Show")
item.setData(36, "A specific value that is used later")
self.ui.my_list.addItem(item)
Now, later in the application, after a user clicks a button, I want to update the text "A specific value that is used later", for the item that is selected. I have attempted to do this
ndx = self.ui.my_list.currentRow()
self.ui.my_list.item(ndx).setData(36, "Updated!")
The problem is, this doesn't work. It doesn't throw any errors, but the data is just gone. In my button press signal I have this code to see the value before and after the reassignment:
ndx = self.ui.my_list.currentRow()
print "Before:", self.ui.my_list.item(ndx).data(36).toPyObject()
self.ui.my_list.item(ndx).setData(36, "Updated!")
print "After:", self.ui.my_list.item(ndx).data(36).toPyObject()
This outputs:
Before: A specific value that is used later
After:
How can I properly change the data so that it is saved back to the QListWidgetItem?
You may want to check that the role value your using is a valid user role, otherwise it may be altered internally. I write in c++, but I use the QListWidget and QListWidgetItem(s) frequently, and this was a problem I encountered early on. I imagen that the functionality is similar regardless of the language. According to the documentation here, the first user role that can be used is 0x0010. So to tie it to your example, you might try the following:
item.setData(0x0010, "A specific value that is used later")
For additional item roles you would use 0x0011, 0x0012, 0x0013, etc.
I have just now begun with GUI programming in Python 2.7 with Tkinter.
I want to have a button Browse, which when clicked opens the Windows File Explorer and returns the path of file selected to a variable. I wish to use that path later.
I am following the code given here. It outputs a window displaying 5 buttons, but the buttons do nothing. On clicking the first button, it doesn't open the selected file.
Likewise, on clicking the second button, the askopenfilename(self) function is called and it should return a filename. Like I mentioned, I need that filename later.
How to I get the value returned by the function into some variable for future use?
There is no point in using return inside a callback to a button. It won't return to anywhere. The way to make a callback save data is to store it in a global variable, or an instance variable if you use classes.
def fetchpath():
global filename
filename = tkFileDialog.askopenfilename(initialdir = 'E:')
FWIW (and unrelated to the question): you're making a very common mistake. In python, when you do foo=bar().baz(), foo takes the value in baz(). Thus, when you do this:
button = Button(...).pack()
button will take the value of pack() which always returns None. You should separate widget creation from widget layout if you expect to save an actual reference to the widget being created. Even if you're not, it's a good practice to separate the two.