Displaying current output in wx.textctrl wigdet from python code entered in another wx.textctrl - python-2.7

I use two wx.TextCtrl widgets in my wxApp.
The first one is used to provide Python code by app user, e.g.:
from time import sleep
for i in range(4):
print i
sleep(4)
The second one is used to display the output.
To process user code I use EXEC.
But I have problems with displaying output dynamically.
Currently the output is displayed in second wx.TextCtrl widget but after whole code is processed (after 16 seconds).
I would like to display the user's code output every 4 seconds in above code.
How to do that?
I was trying to use threads but there are problems with using exec in case of threads.

time.sleep will block the GUI's main loop, which is why you don't see any output. You will have to put that into a separate thread if you want to go that route. Otherwise, you could use a wx.Timer.
Here's a tutorial: http://www.blog.pythonlibrary.org/2009/08/25/wxpython-using-wx-timers/
I don't think you should use Python's exec command though. That can lead to code injection issues. Instead, you should consider using the subprocess module.

Related

How do I do multiple things at once in Python (2.7.12) (Threading?)

I'm trying to figure out how to load a long python program and make a loading animation run at the same time. I've looked around and found threading, but I haven't been able to find out how to use threading to do this.
Edit: My code https://gyazo.com/adb1f0a77d58ba89c9b133972bc17d03
Your coding is blocked on this school computer, so I haven't seen the coding provided, but I'll still be able to help. You can make use of the built-in Python Thread module to do this.
First of all, you would need to put your loading animation in a function. Have this animation in a while loop that terminates when a variable, lets use loadingfinished, is True.
def loading_animation():
global loadingfinished # may or may not be needed
while not loadingfinished:
#insert code here
Once you create this function, you would set loadingfinished to zero.
Now, after making sure the module "thread" is imported, you would type
thread.start_new(loading_animation, ())
This starts loading_animation as a new thread, with no arguments. After this, you would just have your normal code, the stuff that you need to load.
Once you are done with the loading code, you simply set loadingfinished to True! This is what your code should look like:
import thread
def loading_animation():
global loadingfinished # may or may not be needed
while not loadingfinished:
#insert animation code here
loadingfinished = False
thread.start_new(loading_animation, ())
#insert loading code here
loadingfinished = True
#This by itself causes the separate thread to terminate.
#You may want to put a delay of a tenth of a second or so here,
#to make extra sure the other thread is terminated before you continue.
Multithreading is a great thing to learn, especially in Python, since it's a slow language. I usually like separating my blitting and calculations into different threads. This can almost double your program performance!
You can learn more about the thread module here:
https://docs.python.org/2/library/thread.html#module-thread
I have not been able to test this code, so tell me in the comments below if there are any errors.

Tkinter exe file - DOS screen flashes but GUI does not persist

I have created a GUI on Python 2.7.11 that consists of a main page along with page 1 and page 2 that are linked through buttons on main page. Converted main page to a python exe file using PyInstaller and there were no errors in the conversion. main page.exe appeared in the dist folder but on clicking it, a DOS screen flashed and the main page did not open nor persist on the screen.
Being a beginner, I am not sure about how to proceed further. Please help.
If you've got a line like root.mainloop() at the end (with root standing for your main Tk window) to make sure the event loop runs, then you'll need to debug your code. Try running a small segment of the code at a time to see if all goes well, and see where it is that all doesn't go well; then examine the offending part closely to find the error, maybe running some lines of code in the interpreter from the command line to see what (if any) error messages you get.
On the other hand, if you don't have a line like root.mainloop() at the end, that could produce the error you saw. Being a Python beginner myself, and having learned to program in Tcl where the Tk event loop runs automatically, I've seen that error a few times myself. :o(
There were multiple issues associated with converting the Python Script that links modules through button clicks. Keeping in mind these factors, it would be best to convert it to exe using Cx_Freeze. It is more user-friendly and was highly effective for the GUI when compared to PyInstaller and Py2Exe.

Is it possible to call a method or pass an argument during run time from a command line?

I am using Mac. I have a c++ application, e.g. called myapp. Usually I can invoke the application, by ./myapp.
myapp application is capable of processing an image and returns some text result. Actually myapp application always has to allocate lots of memory at the beginning, so it is a bit slow if I have to run it multiple times.
Now I would like to do this
myapp will work as a service which is always running. I will start myapp at the very beginning by ./myapp.
when i have an image to process, I just want to type something like ./myapp arg1 arg2, here I don't want to start a new process, I want to pass new arguments into the already running application and return results.
In order to make it, what should I do? I know myapp must contains a while loop which waits for requests. But how can I pass arguments during run time multitimes?
/*
It is something like e.g. ngix server. At the beginning you type ngix to start the service, and while it is running, you can still pass arguments by "ngix argument", this command will not create a new process.
*/
/*
Actually I have a C++ image processing application and a python http server. Now what I do is, when the python server receives an image from a client, I start a new process by ./myapp imagelocation. myapp returns the processing results to the commandline and python captures it by "os.popen("./myapp imagelocation,"r").read().strip()". but as I said, the C++ app takes too much time to initializes, so I want to initiaze it only once, and once I have an image, I just pass the image to the c++ app. Of course I know I can just let the C++ application to check if there is a new image saved, and call the method. But in this way, I cannot tell the python application the results */
Yes you can do what you want but you can't use the command line arguments. They are passed just once to your program, when it is started. To wait for a request you can check some other stream, for instance a file or a pipe periodically for new data.
looks like you can do it using pasteboard
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/SysServices/Articles/using.html#//apple_ref/doc/uid/20000854-97617
You need either to create new program like ./myappcommandsender
or just add "if statement# in your service startup routine.

Howto call external program and get it's output from another program

Howto do this in c++:
Suppose that program A is a command line tool with some inputs (for example file paths and a number), according to it's inputs, it may get some other parameters during runtime. (if(condithin) cin<<something) I'd like to call A from another program B and want to see complete output of A during it's running. A's inputs must be entered (if necessary). B is a gui tool written with Qt and A must be shown in a plain text area and it's inputs must be shown in same place (like a console client).
I just don't know where to start. Reading something about IPC didn't help. I know it's possible because I see Dolphin's console window and python interpreter in Eric IDE...
use QProcess::execute method to start running A. you can form the argument list from B to pass to A. Use QProcess::readAllStandardOutput () to read the output of the process and display in B.
Since you use Qt, using QProcess is probably the best way to do it.

Async Console Output

I have a problem with my application win32 console.
The console is used to give commands to my application. However, at the same time it is used to output log messages which mostly comes from asynchronous threads. This becomes a problem when the user tries to write some input and simultaneously an async log message is printed, thus thrashing the display of the users input.
I would like to have some advice in regards to how to handle such a situtation?
Is it possible for example to dedicate the last line in the console to input, similarly to how it looks in the in-game consoles for some games?
You can use SetConsoleMode to disable input echo and line editing mode. You can then echo back input whenever your program is ready to do so. Note that this means you will need to implement things like backspace manually. And don't forget to reset the mode back when you're done with the console!
This is possible using the Console API, but it involves quite a bit of work and all the threads that use the console will have to cooperate by calling your output method rather than directly calling the Console API functions or the runtime library output functions.
The basic idea is to have your common output function write to the console screen buffer, and scroll the buffer in code rather than letting the text flow onto the last line and scroll automatically. As I recall, you'll have to parse the output for newlines and other control characters, and handle them correctly.
You might be able to get away with using "cooked" console input on the last line, although in doing so you risk problems if the user enters more text than will fit on a single line. Also, the user hitting Enter at the end of the line might cause it to scroll up. Probably best in this situation to use raw console input.
You'll want to become very familiar with Windows consoles.
Any time you have asyncronous threads trying to update the same device at once, you are going to have issues like this unless something synchronizes them.
If you have access to everyone's source code, the thing to do would probably be to create some kind of sync object that every task must use to access the console (semaphore, etc).