How to Launch a function using threads in Perl - multithreading

I have tried to call a function using threads using perl in my windows system.
But, during the execution, when i click the button to create a thread process, Microsoft error message is displayed as shown below,
"Perl Command Line Interpreter.
Please tell Microsoft about this problem."
Code Snippet i used in Perl:
use threads;
##### Creation of a dialog box using Tkx Module #####
$Run = $MainFrame -> new_ttk__button(
-text => TEXT,
-width => 15,
-command => sub
{
threads -> create({"stack_size" => 64*4096,
"exit" => "thread_only"},
\&CALLING_FUNCTION);
}
);

It looks like Tk having difficulties with threads: Perl Update UI on Long Thread
You need to create your thread before the Tk objects, maybe it is going to work this way.
However, using threads with Tkx may be dicey. I was getting segfaults
when I tried to join the thread rather than detach it, and I get a
segfault with the code below if I move my $t inside startWork(). This
discussion suggests that you may need to start the thread before
creating any Tk widgets for it to work reliably.
Your problem comes because you are letting Tk code get copied into
your thread, by starting it late in the script. When a thread gets
launched, a copy of the main thread is made, so if there are Tk
widgets already in existence, they get copied in. Even if you don't
use the Tk code in the thread, it can cause problems, and will be
unreliable. So...... create your thread first, before starting any Tk
widget code.

Related

Groovy lanaguge - How to destroy/switch to an application

I'm using the groovy language in robotic application (RPA Express). I can not figure out how to do two things in the groovy language.
I start an application with these command:
def proc = new ProcessBuilder( args )
Process process = proc.start()
My questions are:
How do I close this application? (I want to close the application at the end of the script)?
How do I switch to this application window? (I want to be sure the application window is always focused)?
Both depend on the OS.
You need to invoke a kill task command to kill the process by its pid (e.g. kill on Linux). As Joachim mentions in the comments, Process has destroy() and destroyForcibly().
You need to use the window manager API to focus the window of the given pid you want.

How can I use win32gui in order to have an app run in the background?

I was able to find a great piece of code from here on how to create a Tray app using the win32gui module.
However, that app runs based on a function called notify which only runs when the mouse is moving over the icon.
How can I make the app do something constantly in a loop, regardless of what the user does?
(In other words, I want to use win32gui in a non-event-based way.)
Instead of using win32gui.PumpMessages (which runs its own loop) in the code, replace it with the following loop:
while True:
your_function()
win32gui.PumpWaitingMessages()
This will allow you to run your own functions in the program loop.

How to, in Python, ignore certain/all keypresses while function executing in program on Macintosh

I would like to know, how would I, in Python, be able to ignore certain/all keypresses by the user while a certain function in the program is executing? Cross platform solutions are preferred, but if that is not possible, then I need to know how to do this on Macintosh. Any help is greatly appreciated! :)
EDIT: Right now, I am processing keypresses through the turtle module's onkey() function since I did create a program using turtle. I hope this helps avoid any confusion, and again, any help is greatly appreciated! :)
You might want to modify your question to show how you're currently processing key-presses. For example is this a command-line program and you're using curses?
You could use os.uname to return the os information or sys.platform, if that isn't available. The Python documentation for sys.platform indicates that 'darwin' is returned for OSX apple machines.
If the platform is darwin then you could, in your code, ignore whatever key-presses you want to.
Edit (Update due to changed question):
If you want to ignore key-presses when a certain function is being called you could either use a lock to stop the key-press function call and your particular function being executed together.
Here is an example of using a lock, this may not run, but it should give you a rough idea of what's required.
import _thread
a_lock = _thread.allocate_lock()
def certainFunction():
with a_lock:
print("Here's the code that you don't want to execute at the same time as onSpecificKeyCall()")
def onSpecificKeyCall():
with a_lock:
print("Here's the code that you don't want to execute at the same time as certainFunction()")
Or, depending on the circumstances, when the function which you don't want interrupting with a key press is called, you could call onkey() again, with the specific key to ignore, to call to a function that doesn't do anything. When your particular function has finished, you could call onkey() again to bind the key press to the function that processes the input.
I found similar problems, maybe it will help you with your problem:
globally capture, ignore and send keyevents with python xlib, recognize fake input
How do I 'lock the keyboard' to prevent any more keypresses being sent on X11/Linux/Gnome?
https://askubuntu.com/questions/160522/python-gtk-event-ignore

wxpython threading textctrl disappears until files are processed

Appropriate code provided below. I had this working once but have since messed up due to having to change some of the other code. Can't figure out what I've done. The encrypt function creates a thread and makes a call to function EncryptProc to process one or more files. Once each file is completed it should print the name to a textctrl. In the codes current state it waits until all threads/files are processed before printing. It then prints evrything in one go. During processing the textctrl also completely disappears. Any help would be much appreciated as its starting to drive me nuts, lol.
---EDIT---
CODE REMOVED
There should be no GUI access from within threads - in your case EncryptProc is writing to the text control directly - you need to either:
Use CallAfter in the thread to update the text control after the thread exits or
Raise custom event an event in the thread that carries the file name information
and have a hander in the main thread that updates the text control
on receiving the event.

Instantiating a new WX Python GUI from spawn thread

I have main thread that runs a WX Python GUI. The main GUI gives a user a graphical interface to select scripts (which are mapped to python functions) and a 'Start' button, which spawns a second thread (Thread #2) to execute the selected scripts. The problem I am having is I cannot get a new WX GUI (GUI2) to popup and give the user the ability to enter data.
# Function that gets invoked by Thread #2
def scriptFunction():
# Code to instantiate GUI2; GUI2 contains wx.TextCtrl fields and a 'Done' button;
# When 'Done' button is clicked, data entered in fields are process and second GUI is destroyed
gui2Frame = Gui2Frame(None, "Enter Data Gui")
gui2Frame.Show(True)
# This is where I need help. Cannot figure out how to pend for user input;
# In this example; my 'Done' button sets the Event flag
verifyEvent = threading.Event()
verifyEvent.wait(10)
# Process entered data time
processData()
Currently, this approach locks up the GUI2 for 10sec. Which makes sense, because the spawned thread is locked up. Implementing a while-loop with a time.sleep(), does the same. I looked into spawning a third thread, just to handle GUI2, but again, I get back into not knowing how to hold GUI2 active. Any suggestions? Also, please no recommendations about changing the multithreading architecture into one thread; Thank you.
You can't have two wxPython mainloops in one program. You really do have to use just the first wxPython program's main thread. If you want to spawn another application, then use subprocess. Something like this should work:
import subprocess
subprocess.Popen("python path/to/myscript.py")

Resources