Sending keystrokes to QProcess
-
Hi,
I have been looking for a few hours regarding a way of sending keystrokes to a QProcess and haven't found any working solution (I use PyQt5). Even some old posts (5-6 years) were saying it's not possible or out of scope for QProcess. I was wondering if any of you had an idea to help me achieve that, even if it's not using QProcess, but it has to stay non-blocking. I have tried many proposed solutions using QProcess::write() and QProcess::writeData(). I process the output for a built-in terminal that the user interacts with between sequences, so it unfortunately can't be done externally.
Here is a basic example of how my code is setup:
self.process = QProcess() if firstTime: #Setup output slots - triggers custom actions based on results in the outpu self.process.readyReadStandardOutput.connect(self.readProcessOutput) self.process.readyReadStandardError.connect(self.readProcessError) self.process.start(command) if not self.process.waitForStarted(): return False firstTime = False else: # New code that runs everytime but the first, and triggers the programming tool's next batch self.process.write(b'\r') #As I understand, \r is the correct char for enter or return. Also tried \n, \r\n for the sake of it. Does not return an error, ut no result
Here is the context of use. I have a command line device programming tool that I control via the QT App. It has a batch mode that allows me to press Enter to program again, instead of having to relaunch the command itself. If I launch it every time, it does the initial setup and programming every time. If I use the batch mode, it will do the initial setup once and then just program the device. By using the batch mode, I save about 75% time compared to relaunching everytime, that is why it's critical for me.
Thanks in advance
-
If this is a Windows environment then "\r\n" is probably the right thing to send. If it is Linux/UNIX then "\n" might the right thing to send. You have to send it at the right time or the command line tool may not even be looking for it.
What is causing calls to the code you posted? Where do you look for the prompt (or whatever) issued by the command line tool before you "press" return?
-
Thanks for the reply. The command line tool I use displays a message before starting another sequence saying "Press enter to continue or q to quit" and that's when I press a button that triggers the provided code, so technically I send it at the right time because I decide manually when it's ready. I do the same thing when launching that command line in a terminal and everything is fine. I'm on OSX, so \n would be the right one, but no good result for now.
-
If the code is exactly as posted then the second time through you replace self.process with a default constructed QProcess. That default QProcess is then the one you QProcess::write() to. The original QProcess, which may or may not still be active, never sees the input.
Qt needs to return to its event loop in order to actually write the bytes. Can we assume this is happening?
There is the possibility that the command line tool is not reading from its standard input stream (the channel that it would receive what is sent by write()) but receiving key codes another way. In that case you are likely to need an operating system specific method to inject keystrokes (This would likely be fragile).
-
@ChrisW67 said in Sending keystrokes to QProcess:
There is the possibility that the command line tool is not reading from its standard input stream (the channel that it would receive what is sent by write()) but receiving key codes another way. In that case you are likely to need an operating system specific method to inject keystrokes (This would likely be fragile).
@MisterMilk24
This is possible. Or it is possible that the process only reacts to Enter as you describe when that comes from a terminal, not any other stdin.One thing you could try: Put your "response(s)" into a file. Try from a Command Prompt running
theprocess < inputfile
to see whether that "works" the same as if you type those response characters into its input from a terminal. It is true that this test does not allow a "delay", e.g. waiting for the process to print "Press enter to continue or q to quit" before entering the first "response" character, we don't know for sure what the consequence will be. But it's an interesting test. Certainly if you can make it work this way you should be able to via
QProcess
. If it does not behave as it would when stdin is from a terminal that is an indication that your hope to automate may not be possible.....