I made GUI for my program. When I launch app, then it appears empty black screen.
This isn't completed program, but I expect a working application.
Python code: http://pastebin.com/RbMKAd9t
Kivy interface: http://pastebin.com/12eHp0y4
I infer that your kv file is called interface.kv, and you load it only with Builder.load_string. In this case the problem is that Builder.load_string doesn't return anything because there is no root widget definition (i.e. without the <>) in the file.
Add a root widget definition, or change the build method to return Main().
Related
My project has multiple tkinter functions that create windows and different buttons have different buttons that connect to the main program. One issue I have is that when I call a tkinter gui function the images are not displayed.
def get_userInfo(user,pass):
login_state = db.login_verification(user,pass) # Returns either True / False
if login_state == True:
full_name = db.retrive(user,pass,id) # Get's Full name from database.
gui.user_page(first_name) # This only displays the window with no images / text.
gui.user_page("john") # This works perfectly tho
When I call a function within a function the images from the assets path do not load.
Whereas if I just do gui.user_page from outside the function it works without any issues.
I think if I were to use more classes in my gui.py file it should probably fix the issue.
I have a main program which does some cool stuff and I am currently setting up a 'settings editor' to let the user change some GUI related stuff and default values. It reads values from a text file, which is read in correctly and saves them to a dictionary self.propertiesDict. Some of the options are on/off switches, so I use checkbuttons for them. What is puzzling me is following behavior: the code works perfectly fine, when I execute the settingsEditor.py (the script creating the settings window) directly. All the checkbuttons are set to active / True. However, when I include my settingsEditor in my main program and call it, it creates fine but all the checkbuttons show the wrong value: False. I read a lot of topics here to find an answer, but I think I avoided the most common errors:
I use the tk variables
tk variables are created and set prior to the buttons
variables are not only in local scope (prefixed self.)
As you can see, I tried with an IntVar and a BooleanVar, but neither is working correctly. Something else is strange, when I use ttk.checkbuttons, I get the issue described here. I use Visual Studio for debugging and I can't see any difference in the process when going trough line by line, except for the wrong display result. I am happy for any suggestion. Sorry for not providing a full MWE, I will do, if nobody can help me from this here.
settingsEditor.py
import tkinter as tk
from tkinter import ttk
...
class mySettingsEditor:
def __init__(self):
...
def createGUI(self):
# Show main options on startup on/off
self.showOptionsVar = tk.IntVar()
self.showOptionsVar.set(str2int(self.propertiesDict['showMainOptionsExpanded']))
print(self.showOptionsVar.get())
self.checkBtn1 = tk.Checkbutton(Frame, text='Main Options Section', variable=self.showOptionsVar)
self.checkBtn1.grid(column=0,row=2)
# Show main STL section on startup on/off
self.showMainSTLVar = tk.BooleanVar()
self.showMainSTLVar.set(str2bool(self.propertiesDict['showMainSTLSectionExpanded']))
print(self.showMainSTLVar.get())
self.checkBtn2 = tk.Checkbutton(Frame, text='Main STL Section', variable=self.showMainSTLVar)
self.checkBtn2.grid(column=0,row=3)
main.py
from settingsEditor import mySettingsEditor
...
settEditor = mySettingsEditor()
This is how it looks in the GUI when executed separately (terminal with print output to the left):
Thats the result when I add it in main.py. The boxes are unchecked, but .get() tells me the values are correctly assigned to the tk variables.
As suggested by jasonharper, switching to Toplevel() for the child windows fixed the issue. Thanks alot!
Now i understand the concept of instance variables and classes, I've never had a problem with them before and I use them frequently. However when I make my MainWindow class, everything is peachy until i try accessing instance variables.
http://pastebin.com/tDs5EJhi is the full code, but at this point it's just placing labels and frames and whatnot, no actual logic is going on. The window looks fine and nothing bad happens.
My question comes to be when I try changing things inside of the window externally. I figured I could just make an instance of the class and change variables from there (namely instancevariable.ImageCanvas.itemconfig()) like i can normally, but Tkinter isn't being nice about it and I think it's a result of Tkinter's mainloop().
Here's the tidbit of my class MainWindow() that i'm having trouble with (ln 207)
...
self.C4 = Tk.PhotoImage(file="temp.png")
self.card4 = self.CardCanvas.create_image(120,46,image=self.C4, state=Tk.NORMAL)
#self.CardCanvas.itemconfig(4, state=Tk.HIDDEN) # < It works here
...
self.root.mainloop()
window = MainWindow()
window.CardCanvas.itemconfig(4, state=Tk.HIDDEN) # < It doesn't work here
That's how i learned how to edit instance variables. When the window pops up, the itemconfig command doesn't actually apply like it would were it inside the class (or maybe it did and the window just didn't update?) and after closing the window I get this error:
_tkinter.TclError: invalid command name
which I assume is just because it's trying to apply a method to variables that don't exist anymore, now that the window has closed.
So I guess here's my big question - I have a MainWindow class, and from what I can tell, nothing can be changed from outside of the class because the Tk.mainloop() is running and won't stop to let other code after it run, like the itemconfig. How do I go about changing those variables? Code after the instance variable declaration doesn't seem to run until the MainWindow() is closed.
You are correct that code after mainloop doesn't run. It does, but only after the GUI has been destroyed. Tkinter is designed for the call to mainloop be the last (or very nearly last) line of executable code. Once it is called, all other work must be done as reaction to events. That is the essence of GUI programming.
The answer to "how do I go about changing the variables" is simple: do it before you call mainloop, or do it in reaction to an event. For example, do it in a callback to a button, do it in a function bound to an event, or to a time-based event via after, and so on.
I have created a main GUI and coded in a single file called one.py. There is a need to call a custom GUI/widget in from the main script. The second custom GUI/widget is created with qt designer and the working script is called second.py.
It works fine when I execute second.py. The second GUI must be triggered when a variable from one.py changes. The GUI pops up fine as expected when variable is change in one.py. However, along with the second GUI, the next widget from one.py also shows as well. The example script of one.py looks like this:
if variable:
self.child_win = PersistenceGui(self)
self.child_win.show()
QtGui.QMessageBox.information("Some info to the users.")
In the above case, the child window and info box are shown together. But I want Info box to be shown only after closing the child window/GUI box. Where am I making a mistake?
Make PersistenceGui a subclass of QDialog, and then show it like this:
self.child_win.exec_()
This will block until the user closes the dialog, and then the message-box will be shown.
EDIT:
If you want to know if the user cancelled the dialog, then try this:
if self.child_win.exec_() == QtGui.QDialog.Accepted:
QtGui.QMessageBox.information("Some info to the users.")
else:
# ask if user wants to close main window, or whatever...
I have written an application in python 2.7 and tkinter. I created a tool bar with several buttons that open up respective top windows that display various options. I used ttk.Checkbutton with the 'toolbutton' style as an indicator to show whether the option windows are open or closed.
The problem is that the option windows will go to the back if another window is selected. Currently, if one selects the toolbutton again, the option window will close. However, I only want to close the window if it is on top. If the option window is not on top, I want the window to moved to the front.
Some of the code I have working:
class MainWindow:
def __init__(self,application):
self.mainframe=tk.Frame(application)
application.geometry("900x600+30+30")
self.otherOptionsSelect=tk.IntVar()
self.otherOptions_Button=ttk.Checkbutton(application,style='Toolbutton',variable=self.otherOptionsSelect,
onvalue=1, offvalue=0,image=self.optionsIcon, command=self.otherOptions)
def otherOptions(self):
if self.otherOptionsSelect.get()==0:
self.otherOptions.destroy()
return
self.otherOptions=tk.Toplevel()
self.otherOptions.title("IsoSurface Options")
self.otherOptions.geometry("200x165+"+str(int(application.winfo_x())+555)+"+"+str(int(application.winfo_y())+230))
self.otherOptApply_button=ttk.Button(self.otherOptions,text="Apply",command=self.showFrame)
self.otherOptApply_button.place(x=20,y=80,width=50,height=30)
self.otherOptClose_button=ttk.Button(self.otherOptions,text="Close",command=self.otherOptionsClose)
self.otherOptClose_button.place(x=80,y=80,width=50,height=30)
def otherOptionsClose(self):
self.otherOptionsSelect.set(0)
self.otherOptions.destroy()
Here is a picture of the entire application I have written:
In the above image, each window has their respective ttk.checkbutton. At the moment, toggling the checkbutton either opens or closes the window. However, what I really want it to do is close the window if the window is in front of the application, or bring the window to the front if it is behind the application.
Hopefully this clears some things up.
Thanks in advance!
It is in fact possible to check stacking order of windows. Using Tkinter, you have to do some funny tcl evals to get at the information. I found the answer at TkDoc in the section on Windows and Dialogs, scroll down until you get to "Stacking Order". The code baffled me until I started playing around with it interactively. My test code was:
import Tkinter as tk
root = tk.Tk()
root.title('root')
one = tk.Toplevel(root)
one.title('one')
two = tk.Toplevel(root)
two.title('two')
I then manipulated the windows so that two was on top, one under that and root below them all. In that configuration, the following weirdness can tell you relative layering of windows:
root.tk.eval('wm stackorder '+str(two)+' isabove '+str(root))
returns 1, meaning "Yes, window two is above window root." While the following:
root.tk.eval('wm stackorder '+str(root)+' isabove '+str(two))
returns 0, meaning "No, window root is not above window two." You can also use the command:
root.tk.eval('wm stackorder '+str(root))
Which gives back the full window stacking order in the form of a weird string something like this:
'. .68400520L .68401032L'
Which starts to make sense when you run the commands:
str(root)
str(one)
str(two)
and figure out that root has the internal name '.', one is '.68400520L' and two is '.68401032L'. You read the output of root.tk.eval('wm stackorder '+str(root)) backwards so it's saying two is on top, one is under that and root is below both.