def activate(self,shell):
self.shell = shell
self.action = gtk.Action ('foo','bar','baz',None)
self.activate_id = self.action.connect ('activate', self.call_bk_fn,self.shell)
self.action_group = gtk.ActionGroup ('hot_key_action_group')
self.action_group.add_action_with_accel (self.action, "<control>E")
uim = shell.get_ui_manager ()
uim.insert_action_group (self.action_group, 0)
uim.ensure_update ()
def call_bk_fn(self,shell):
print('hello world')
i am using the above code in a plugin for rhythmbox ,and here i am trying to register the key ctr+e so that the call_bk_fn gets called whenever the key combination is pressed , but its not working why is that so ?
One thing that i did remark is that your callback should be like this:
def call_bk_fn(self, event, shell):
print('hello world')
hope this can help :), if you still have some problem i think you should give us more info about the errors that are raised .
Related
so ive got two scripts thats, where ive imported one into the other. script 1 is a class for the encryption function
class encryption():
def encryption(message):
#code here isnt relevant
def decryption(line_key):
#code isnt relevant
this code works by it self but when the other code from script two tries interacting with it it get the error :
TypeError: encryption() takes no arguments
The code for script two that interacts with script one is :
x1 = entry1.get()
label4 = tk.Label(root, text = encryption.encryption(x1), font = ('helvetica' , 10 , 'bold')
Im really not sure what im doing wrong here.
Oh you have just made a typo.
you should pass self to the definition of encryption and decryption functions in your class.
class encryption():
def encryption(self, message):
#code here isnt relevant
def decryption(self, line_key):
#code isnt relevant
Source code
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
app = Application(backend='uia').start("C:\\Program Files (x86)\\Advantech\\AdamApax.NET Utility\\Program\\AdamNET.exe")
win = app['Advantech Adam/Apax .NET Utility (Win32) Version 2.05.11 (B19)']
win.wait('ready')
win.menu_select("Setup->Refresh Serial and Ethernet")
win.top_window().print_control_identifiers(filename="file.txt")
# win.top_window().OKButton.click_input() ---------This is what I hope to do
else
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
Problem Statement
I had to run this application with elevation rights. The above is my code. The problem is I can't identify the window (view in output image) that pops up after selection from menu. I need to close the window. Please excuse the line
win.top_window().print_control_identifiers(filename="file.txt")
It was meant write the identifiers into a text file because the structure of this code does not display the outputs for me to view. However, since nothing is appended, I guess pywinauto couldn't identify the dialog.
For a clearer understanding, please view the image (input) of when it selects the menu.
Input
Now, it pops up with this dialog (output)
Output
I've also used spy to identify the caption and it gives:
(Handle: 004E07D4,
Caption: Information,
Class: #32770(Dialog),
Style: 94C801C5)
Other things I've tried:
Besides using win.topwindow() to identify the dialog, I've used
win[Information].OKButton.click_input()
win[Information].OK.click_input()
win[Information].OK.close()
win[Information].OK.kill(soft=false)
win.Information.OKButton.click_input()
win.Information.OK.click_input()
win.Information.OK.close()
win.Information.OK.kill(soft=false)
app[Information] ...... curious if I could discover the new window from original application
I've also send keys like enter, space, esc & alt-f4 to close the dialog with libraries like keyboard, pynput & ctypes. It still doesn't work.
Link to download the same application: http://downloadt.advantech.com/download/downloadsr.aspx?File_Id=1-1NHAMZX
Any help would be greatly appreciated !
I finally found a thread that demonstrated the way multi thread works to solve this issue. I tried it myself and it works. It's a little different as a few parts of the code have depreciated. Here is the link to the solution:
How to stop a warning dialog from halting execution of a Python program that's controlling it?
Here are the edits I made to solve the problem:
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
def __init__(self, window_name, quit_event):
threading.Thread.__init__(self)
self.quit_event = quit_event
self.window_name = window_name
def run(self):
while True:
try:
handles = windows.find_windows(title=self.window_name)
except windows.WindowNotFoundError:
pass
else:
for hwnd in handles:
app = Application()
app.connect(handle=hwnd)
popup = app[self.window_name]
popup.close()
if self.quit_event.is_set():
break
time.sleep(1)
quit_event = threading.Event()
mythread = ClearPopupThread('Information', quit_event)
mythread.start()
application = Application(backend="uia").start("C:\\Program Files (x86)\\Advantech\\AdamApax.NET Utility\\Program\\AdamNET.exe")
time.sleep(2)
win = application['Advantech Adam/Apax .NET Utility (Win32) Version 2.05.11 (B19)']
win.menu_select("Setup->Refresh Serial and Ethernet")
quit_event.set()
else:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
The best thing is this solution works for every other dialog that halts the main script from working & I could use them to do different actions like clicking buttons, inserting values, by adding more multi threads.
so i'm creating an application with python 3.7(windows) and tkinter model
and i wanted to control some of the options in my app using key events
( when the user press a specific key a specific action happen) sounds simple right !
so i tried to do that using a class contain variable and callback function
and the result was not as i expected ,
i was able to print the pressed key name directly inside the callback function
BUT !! what i wanted exactly is the to store that key name in a variable to use it outside the class
something like :
class keySystem:
pressedKey = None
def callback(event):
keySystem.pressedKey = repr(event.char)
myWindow.bind("<Key>", keySystem.callback )
print( "the user have Pressed : ", keySystem.pressedKey )
The Goal : store which key name have been pressed from the event in my "class variable" (pressedKey) to use it outside the class
# example of usage :
if keySystem.pressedKey == "g":
mySettings.open()
if keySystem.pressedKey == "Esc":
mySettings.Exit()
I am not sure if this is what you need, but you need to define it as a class variable and call it using class' object. The __init__ function helps in this case and do make sure to use the self keyword inside each function. I'll give a very simple example below:
class keySystem:
def __init__(self):
pressedKey = None
def callback(self, event):
self.pressedKey = event
object=keySystem()
object.callback('Enter')
print( "pressed : ", object.pressedKey)
Output is:
pressed : Enter
I have a feeling though that this isn't what you were looking for. Let me know if I interpreted it wrong.
Is there a way for a program to invoke another program in python?
Let me explain my problem:
I am building an application (program 1) , I am also writing a debugger to catch exceptions (program 2) in program 1 { a typical try : except: } block of code . Now I want to release program 2 so that for any application like prog 1 , prog 2 can handle exceptions ( making my work easier) . I just want prog 1 to use a simple piece of code like:
import prog2
My confusion stems from the fact as how can I do something like this , how can I invoke prog 2 in prog 1, ie it should function as all the code in prog 1 should run in the {try: (prog 1) , except:} prog 2 try block.
Any pointers on how I can do this or a direction to start would we very much appreciated.
Note: I am using python 2.7 and IDLE as my developer tool.
tried execfile() yet? Read up on it on how to execute another script from your script.
I think you need to think about classes instead of scripts.
What about this?
class MyClass:
def __init__(self, t):
self.property = t
self.catchBugs()
def catchBugs(self):
message = self.property
try:
assert message == 'hello'
except AssertionError:
print "String doesn't match expected input"
a = MyClass('hell') # prints 'String doesn't match expected input'
UPDATE
I guess you have something like this in your directory:
program1.py (main program)
program2.py (debugger)
__init__.py
Program1
from program2 import BugCatcher
class MainClass:
def __init__(self, a):
self.property = a
obj = MainClass('hell')
bugs = BugCatcher(obj)
Program2
class BugCatcher(object):
def __init__(self, obj):
self.obj = obj
self.catchBugs()
def catchBugs(self):
obj = self.obj
try:
assert obj.property == 'hello'
except AssertionError:
print 'Error'
Here we are passing the whole object of your program1 to the BugCatcher object of program2. Then we access some property of that object to verify that it's what we expect.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
I have a small python application, which uses pyttsx for some text to speech.
How it works:
simply say whatever is there in the clipboard.
The program works as expected inside eclipse. But if run on cmd.exe it only works partly if the text on the clipboard is too large(a few paras). Why ?
when run from cmd, it prints statements , but the actual 'talking' doesn't work(if the clipboard text is too large
Here is a of the program part which actually does the talking: As can be seen the 'talking' part is handled inside a thread.
def saythread(queue , text , pauselocation, startingPoint):
saythread.pauselocation = pauselocation
saythread.pause = 0
saythread.engine = pyttsx.init()
saythread.pausequeue1 = False
def onWord(name, location, length):
saythread.pausequeue1 = queue.get(False)
saythread.pause = location
saythread.pauselocation.append(location)
if saythread.pausequeue1 == True :
saythread.engine.stop()
def onFinishUtterance(name, completed):
if completed == True:
os._exit(0)
def engineRun():
if len(saythread.pauselocation) == 1:
rate = saythread.engine.getProperty('rate')
print rate
saythread.engine.setProperty('rate', rate-30)
textMod = text[startingPoint:]
saythread.engine.say(text[startingPoint:])
token = saythread.engine.connect("started-word" , onWord )
saythread.engine.connect("finished-utterance" , onFinishUtterance )
saythread.engine.startLoop(True)
engineRun()
if saythread.pausequeue1 == False:
os._exit(1)
def runNewThread(wordsToSay, startingPoint):
global queue, pauselocation
e1 = (queue, wordsToSay, pauselocation, startingPoint)
t1 = threading.Thread(target=saythread,args=e1)
t1.start()
#wordsToSay = CLIPBOARD CONTENTS
runNewThread(wordsToSay,0)
Thanks
Edit: I have checked than the python version used is the same 2.7 . The command used to run the program in cmd : python d:\python\play\speech\speechplay.py
Checked that the problem is not in the code that reads the text from the clipboard.
You should check if your eclipse setup specifies custom environment variables for the project which do not exist outside Eclipse. Especially:
PYTHONPATH (and also additional projects on which your program could depend in your setup)
PATH
Use
import os
print os.environ['PATH']
print os.environ['PYTHONPATH']
at the beginning of your program to compare both settings.
Misc stylistic advices:
don't use os._exit, prefer sys.exit (you should only use os._exit in a child process after a call to os.fork, which is not available on Windows)
I think a threading.Event would be more appropriate than a queue.Queue
I'd use a subclass approach for the thread with methods rather than a function with inner functions
For example:
import threading
import sys
import pyttsx
class SayThread(threading.Thread):
def __init__(self, queue, text, pauselocation, startingPoint, debug=False):
threading.Thread.__init__(self)
self.queue = queue
self.text = text
self.pauselocation = pauselocation
self.startingPoint = startingPoint
self.pause = 0
self.engine = pyttsx.init(debug=debug)
self.pausequeue1 = False
def run(self):
if len(self.pauselocation) == 1:
rate = self.engine.getProperty('rate')
print rate
self.engine.setProperty('rate', rate-30)
textMod = self.text[self.startingPoint:]
self.engine.say(self.text[self.startingPoint:])
self.engine.connect("started-word", self.onWord )
self.engine.connect("finished-utterance", self.onFinishUtterance )
self.engine.startLoop(True)
if self.pausequeue1 == False:
sys.exit(1)
def onWord(self, name, location, length):
self.pausequeue1 = self.queue.get(False)
self.pause = location
self.pauselocation.append(location)
if self.pausequeue1 == True :
self.engine.stop()
def onFinishUtterance(self, name, completed):
if completed == True:
sys.exit(0)
def runNewThread(wordsToSay, startingPoint):
global queue, pauselocation
t1 = SayThread(queue, wordsToSay,
pauselocation, startingPoint)
t1.start()
#wordsToSay = CLIPBOARD CONTENTS
runNewThread(wordsToSay,0)
In fact, eclipse itself uses a commandline command to start it's apps.
You should check what command eclipse is giving to start the program. It might be a bit verbose, but you can start from there and test what is necessary and what isn't.
You can find out the commandline eclipse uses by running the program and then selecting the output in the debug window. Right-click it, select properties and you're done.
If you don't have a debug window you can open it window/show view/(other possibly)/debug.
turns out pythonpath wasn't set properly on my system.
Edit: turns out pythonpath isn't the problem. I have no idea whats the problem. arghhhhhhhhhhhhhhhhhhhhhhhh