Main window doesnt closes after caling new script from it - python

I am learning python and for GUI model using wxpython, as I am new to programing get stuck every time.
My issue is I have a GUI (main window)with two buttons,when user clicks button1 it opens sub window (seperate python script), I want to close or destroy main window before opening sub window.
self.Destroy()
subprocess.call("python newframe.py",shell=True)
#It will not close main window
What will be the wrong i am trying to do , and please explain what is proper method.
Looking for suggestions thanks .
Sorry for my english .

subprocess.call() wait subprocess to exit. -> button callback will never return until subprogram exit. This keep main window to close. Use subprocess.Popen() which does not wait subprocess.
self.Destroy()
subprocess.Popen('python newframe.py', shell=True)

You shouldn't close the main frame or you'll actually exit the application. Instead you should Hide the main frame and just Show the sub-frame. Then when you close the sub-frame, you can re-show the main frame. I personally think using Pubsub is the easiest way to accomplish this. Here's a link to a tutorial that shows how to do it:
http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/
You could also pass a reference to the main frame when you instantiate the sub-frame or call something like GetTopWindow() or GetParent(), but I really recommend Pubsub for this.

Related

How to execute a command with a button and delete it before the command ends ? Python / Tkinter

I've got an interface where there is a 'Start' button. It runs a 'main' command where it starts a loop to run some measurements on a powermeter. I want to be able to click on an 'OK' button every time the measure is ready to be done. This button would replace the 'Start' button.
But when I try to destroy the button (buttonStart.destroy()) and then run the command main()
, the command executes but doesn't delete the button until the very end.
I've tried using threads from threading package, but it doesn't really work.
If there is a way to both destroy the button and run a command, I would be very interested !
Thanks a lot
The event loop must be given the opportunity to process events in order for the window to be removed from the screen.
There are a couple of ways to make that happen. The first is to call the update_idletasks method on any widget. That is usually enough to process the event related to the destruction of the widget, though it may be necessary to call update instead. Calling update should be avoided if at all possible. My rule of thumb is to start with update_idletasks. If that doesn't work, switch to update or switch to using after.
def my_custom_function():
startButton.destroy()
root.upddate_idletasks()
main()
The second method is to run your main function via after or after_idle. This will let tkinter naturally process all pending events before starting main. I would argue that this is the best approach. I recommend trying after_idle first, and if that doesn't work, switch to after with a small delay.
def my_custom_function():
startButton.destroy()
root.after_idle(main)

how to break out of mainloop() without closing the gui

I have a simple python GUI that fills in a grid based on the values in an array, and I want this simple GUI to sit on screen while other functions run. The time for these other functions is indeterminate, so I can't simply call them at some regular interval using after(time, function)
def go(self):
"""
Start the main GUI loop
:return:
"""
mainloop()
The mainloop starts in the go function, and I want to know if it is possible to either break out of mainloop without closing the window or to draw the GUI without calling mainloop at all?
I know I can do
after(time, function)
but I'm at a loss as to what to call to kill the mainloop while keeping the GUI on-screen.
Use the threading module to run your function alongside the mainloop:
from threading import Thread
def go(self):
t = Thread(target=function)
t.start() # start the thread in the background
mainloop()
Simply put: you can't, or at least it's not what you want to do. I would recommend restructuring you code to put it in the main loop (like making tkinter a class and calling the functions in your init function). If you post your whole code I can help you with it.
The mainloop starts in the go function, and I want to know if it is possible to either break out of mainloop without closing the window or to draw the GUI without calling mainloop at all?
It sounds like you have a very unique need. To give you a literal answer, yes, it's possible to break out of mainloop without closing the window. You can call quit on the root window to cause mainloop to exit. You can restart mainloop, or call the update method on the root window to process events.
This is not typically how a GUI should work, but if you're absolutely certain that you don't need the window to update while the program is running, you can certainly do that if you wish.

PyQt Label not changing text

I have this code running on a PyQt window on windows:
try:
self.actorUser.findIdfFiles(pathToFolder)
msg = "Processando arquivos..."
self.processingLabel.setText(msg)
self.actorUser.runSimulation(pathToFolder, pathToEpw)
Inside the "runSimulation" code I start a subprocess using the method "call". This blocks my GUI and at the title of the window appears "Python stopping responding", but if I wait a little bit the subprocess finishes normally, and the label is finally changed. But what I want is that the label have is text really changed before the subprocess started. What can I do??
Qt (and most UI frameworks) don't update the display as soon as values are set, only when they are told to repaint.
What you need to do is add a call
QtGui.QApplication.processEvents()
before your long-running subprocess, to make it process all pending events.
Joe P 's answer is quite right.
But this method is change to
QtCore.QCoreApplication.processEvents()
in pyqt5
link: https://doc.qt.io/qt-5/qcoreapplication.html#processEvents

Tkinter window only showing after the process

I wrote a script to download file. I tinker it using tkinter. My idea is to show a new window when download button is clicked and show the progress of the download in it. I create new window but problem is it will not show the window until the download is complete..
b2 = Button(text = "Image Download",font=("Raleway", 10),command = lambda: download('Image','.jpg'), width=20)
b2.pack()
when this execute the download() executes in download():
window = Toplevel(root)
window.geometry('600x350+305+220')
window.wm_title(TYPE + ' Download')
this is for creating new window. But it only shows when the download() finish executes
What should i do? Help me
You have not shown the code that downloads the data but it is clearly using a synchronous method. All windowing systems operate by processing events. When a window is created and event is generated to map it onto the screen and another to get it to draw on screen. If you do not allow the thread to process events then apparently nothing happens until you stop being busy.
To work around this you either need to use an asynchronous method of downloading the data or you can use a synchronous method but you must do this on another thread. The UI thread (the one you create your windows on) MUST keep processing events. This basically means never do anything that will take a long time. The Tkinter after() method is a common scheme to break up a long job into lots of small pieces that are posted as events to keep things working. In this case its probably simplest to create a worker thread to do the download and post progress updates to the UI thread regularly.

Python Tkinter Window Output and Shell Input

I am having a problem between the python shell in my IDE and the Tkinter window. What I am trying to do is have all of my user input in the shell, and then I would like to output the corresponding information in a Tkinter window.
However, when my window is made and pops up, I close it to continue my program in the shell, then I continue with input. However, when I try to reinitialize my window. It says that the window has been destroyed. I understand what this means so I tried having a Toplevel window where I output my info which can be closed, and hide my root window, but the shell will not continue until I close/destroy the root window as well.
Is there a way I can continue in the shell without destroying my root window? I am fairly new to this language so any help would be very much appreciated.
This is my general idea:
from Tkinter import *
#get all my info from the shell
root = Tk()
root.withdraw() #hide the root window
main = Toplevel()
#this is the window that I want to be able to close and open later
#get more info from the shell after main is closed
#now I want to open the updated main window
Thanks in advance! (And I am working on Windows if that matters)
I'm not sure if the way you are trying to do this is the most efficient way, but i would propose these changes so far:
from Tkinter import *
#get all my info from the shell
window = Tk()
window.iconify() #hide the root window
#get more info from the shell after main is closed
window.deiconify()
window.mainloop() # to handle events
i renamed your root-Window to make it more clear for you whats happening and removed the superflous (imho) additional Toplevel-window!
Also keep in mind, that you won't accomplish anything without the mainloop and the necessary event-handlers!
Simply put, this is not how Tkinter is designed to work. Tkinter was designed to have a single root window that is created once, and with a single eventloop that is running. Using it any other way is bound to lead to undesired behavior.
If you really need code to work this way, gather your input from your shell in one process, then use a separate process to display the tkinter window. You can either communicate from one the other using a socket, or you could pass the data from the parent to the child via arguments or environment variables or temporary files.

Categories

Resources