I am looking for a solution to add a function to a program using Python. I want to copy and paste selected data (selected with the mouse).
Example:
Copy "Hello" using CTRL-C from the sentence "Hello everybody" when I select Hello.
Copy a part of array selected using CTRL-C
My main problem is how to use the selected data. But now I just can copy string defined in the code (here "tt"):
clipboard.OpenClipboard()
clipboard.EmptyClipboard()
clipboard.SetClipboardText('tt')
clipboard.CloseClipboard()
I tried several codes found on the internet and in this website but none of them fixed my problem.
You don't need to call clipboard.SetClipboardText(). When a program supports the clipboard, then Ctrl+C will copy the currently selected text into the clipboard. There is nothing you need to do to make this happen.
If your question is "How can I trigger Ctrl+C from outside of a program to copy the currently selected text into the clipboard", then the answer is: Usually, you can't. For security reasons, most programs don't respond to artificial key events which other programs send them.
The second error is something else entirely. Your class CopyEvent doesn't have a property list, so Python can't invoke methods in it.
The final code if someone is interested:
from eventbase import EventBase
import win32clipboard as clipboard
import os
import wx
class CopyEvent(EventBase):
TYPE = wx.NewEventType()
ID = wx.NewId()
BINDER = wx.PyEventBinder(TYPE, 1)
SHORTCUT_MODIFIER = wx.ACCEL_CTRL
SHORTCUT_KEY = ord('C')
def __init__(self, variable=None):
EventBase.__init__(self)
self._variable = variable
def execute(self, viewmodel, parent):
clipboard.OpenClipboard()
clipboard.EmptyClipboard()
text = self._convert_variable_to_text(self._variable)
clipboard.SetClipboardText(text)
clipboard.CloseClipboard()
self.logger.info("Copying variable to clipboard")
def _convert_variable_to_text(self, variable) :
lines = []
lines.append("\t".join(variable.column_names))
for row_nbr in variable.row_numbers:
lines.append("\t".join([repr(i) for i in variable.get_row_as_tuple(row_nbr)]))
return os.linesep.join(lines)
Related
I built a password-generator with python. It runs fine in the IDLE but whenever I convert the .py file to an .exe, it closes immediately on a machine with no python installed.
So I wanted to build it a GUI, to prevent the closing.
I want to display the generated password, which is saved in a variable, in a Text-Edit widget.
This is a part of the method which stores it.
# Conversion of list to string
stringpw = ""
for i in lst:
stringpw = stringpw + str(i)
# change positions
def change_text(stringpw):
total= []
for wort in stringpw.split():
w = list(wort)
random.shuffle(w)
total.append("".join(w))
return " ".join(insgesamt)
finalPassword = change_text(stringpw)
return finalPassword
I translated it to english, because it's coded in another language, just in case there are mistakes in the code. However the original code runs fine without any problem.
My problem is, that it doesn't show the finalPassword in the Text-Edit widget, when I run this (the output field exists and the self.ui referring to it is instantiated earlier):
self.ui.output.setPlainText(finalPassword)
Is there a possibility to display this variable? Cause normally you can only show a string in the brackets.
Did you use QPlainTextEdit to print the password or lineEdit?
if QPlainTextEdit then you should use appendPlainText insted of setPlainText
I built simple text editor with some accessibility feature for screen reading software.
I'm using Python for .NET (pythonnet) to show a form containing a rich text box.
When user press tab after a period it pop-ups a context menu with completions for selected element.
Ok, it works fine with Python objects, but it doesn't work with .net live objects, there is no solution to this problem.
Now, I want build a TreeView object with all names and definitions of module I'm editing.
So, for example I type:
import sys
import os
lst = list()
etc...
If I use jedi.names of my source, I can retrieve os, sys and lst.
For each name, I want retrieve sub definitions, such as functions for sys and os module, and methods for lst.
I can't find a way to do this with jedi:
names = jedi.names(MySource)
names[0].defined_names() # works for sys
names[1].defined_names() # works for os
names[2].defined_names() # doesn't work for lst instance of list().
Any suggestions?
I tried to use more and more editors, but accessibility support is very very bad...
This looks like a bug, where jedi.evaluate.representation.Instance.__getattr__() mistakenly blocks evaluation of .names_dict. I added a pull request to the jedi repository to fix this. In the mean time, you can either add 'names_dict' to the whitelist in Instance.__getattr__() in your copy of jedi/evaluate/representation.py, or use the code below to patch this method automatically for the current session.
import jedi
def patch_jedi():
__old__getattr__ = jedi.evaluate.representation.Instance.__getattr__
def __patched__getattr__(self, name):
if name == 'names_dict':
# do a simplified version of __old__getattr__, bypassing the name check
return getattr(self.base, name)
else:
# use standard behavior
return __old__getattr__(self, name)
# test whether jedi has been updated to avoid the Instance.defined_names() bug
try:
jedi.names("lst = list()")[0].defined_names()
except AttributeError as e:
if e.args[0].startswith("Instance ") and e.args[0].endswith("Don't touch this (names_dict)!"):
# patch jedi to avoid this error
print "patching jedi"
jedi.evaluate.representation.Instance.__getattr__ = __patched__getattr__
else:
# something else strange is going on
raise
patch_jedi()
print jedi.names("lst = list()")[0].defined_names()
# or: print jedi.Script("lst = list()").goto_definitions()[0].defined_names()
I should note that I'm not familiar with jedi, so I don't know whether defined_names() is supposed to work for definitions that create instances. The code above won't fix references like jedi.names("lst = []")[0].defined_names(), and there's no obvious patch to do that. So there may be something deeper going on that I don't know about. Hopefully the developer will help set this straight in response to that pull request.
Question
Is there any way to automate a tkFileDialog selection to run it through unittest? The following is the only use of tkinter in my application:
root = Tkinter.Tk()
types = [('Comma Separated Values', '.csv'), ('All Files', '*')]
filename = tkFileDialog.askopenfilename(parent=root,
filetypes=types)
root.destroy()
Edit: I didn't mention that this part of the code was trapped in a method call from a class outside my control.
Background
I've built a local app that creates an http server on localhost and runs its GUI with HTML/CSS/JS in a web browser. Because of browser restrictions, I can't use the built-in file dialog and so have to send this request through Python. I want this to run on a OSX with the built-in Python 2.5. I'm not very familiar with Tcl/Tk.
Attempt #1
If I could get to the underlying widgets, I could generate the clicks like in this question. However, looking at the dialog source, it appears to me that the Tcl call in lines 48-50 is blocking. Is this a correct assumption?
Attempt #2
I thought there might be a way using Tcl commands directly through root.tk.call. Since I'm on Python2, I think the underlying Tcl is a single call to tk_getOpenFile. Would I have to ensure the Tcl interpreter is threaded? Is there any Tcl/Tk command that can help me out here?
Attempt #3
I could implement the file selection from scratch using os.listdir etc. (Probably in a separate HTML page communicating back and forth with the server). It would be more than a little painful and hopefully avoidable.
Solution
Based on A. Rodas's answer below, I came up with the following:
import tkFileDialog
old_dialog = tkFileDialog.askopenfilename
try:
tkFileDialog.askopenfilename = lambda *args, **kw: filename
# First test dialog cancelled
filename = ''
method_that_calls_tk()
# run some assertions
# Next test a valid file name with valid contents
filename = self.VALID_FILENAME
method_that_calls_tk()
# run some assertions
# Now test a valid file name with invalid contents
filename = self.INVALID_CONTENTS_FILENAME
method_that_calls_tk()
# run some assertions
# Now test an invalid file name
filename = self.INVALID_FILENAME
method_that_calls_tk()
# run some assertions
finally:
tkFileDialog.askopenfilename = old_dialog
Unit testing of Tkinter code is not an easy issue. For instance, the IDLE does not have a proper test suite, even though it is part of the standard library. Since you mention that this is going to be the only use of Tkinter in your application, I'd suggest to make unit tests for the outcome of this code: the value of filename.
For instance, you can have a test for a .csv file, and another one for an incorrect file extension. Since tkFileDialog returns an empty string if it is closed by the user, add also a test where filename = ''.
import unittest
class TestFileDialog(unittest.TestCase):
def test_dialog_closed(self):
filename = ''
# ...
def test_incorrect_extension(self):
filename = '/path/to/another/filetype'
# ...
def test_csv_extension(self):
filename = '/path/to/correct/file.csv'
# ...
You could just patch the calls to tkinter:
patch tk.Tk() because most CI's will error because they don't have displays.
Also patch the file dialog so you can simulate return values and that it is being called with what you expect.
#patch('your_module.tk.Tk')
def test_your_stuff(self, Tk)
with #patch('your_module.tkFileDialog.askopenfilename') as file_dialog:
expected = 'expected return value'
assert expected = your_function_calling_file_dialog()
file_dialog.assert_called_once_with(whatever, you, expect, it, to, be, called, with)
I am trying to write a procedure that will automate the procedure of making a tkinter window, so I am trying to use the open() function to open a txt file (probably should be a .py shouldn't it?) that a procedure that makes the window, the code I am trying to have it write is:
def a_procedure():
window = Tk()
#rest of code necessary to make a Tkinter window
but the problem is, when I use
open()
textfile.write("def a_procedure()"/
"window = Tk()")
what I get in the text file is: def a_procedure(): window = TK() #rest of text
Is there (a)A way to write multiple lines with
open()
or (b)A better way to write a procedure with a procedure
Your example doesn't show how you're going to vary the generated function (since if they're all the same you don't need to generate them). So I'll show a different example where a function can return a new function.
def make_function(first_multiplicand):
def multiply(second_multiplicand):
return first_multiplicand * second_multiplicand
return multiply
Then you can make functions that multiply by different amounts:
doubler = make_function(2)
tripler = make_function(3)
print doubler(7), tripler(7)
This way you don't have to write out a .py file and then import it (which has potential problems if you can't write out files anywhere helpful, as well as requiring you to create Python source code by string formatting, which is pretty ugly).
It's also worth looking at functools, particularly functools.partial; you could rewrite the above using it as follows:
import functools
def make_function(first_multiplicand):
def multiply(first, second):
return first * second
return functools.partial(multiply, first_multiplicand)
You can use multi-line strings:
textfile.write("""
def a_procedure():
window = Tk()
""")
Just make sure to keep stuff indented properly.
Why do you need to generate Python from a Python script?
Try: "def a_procedure():\n\twindow = Tk()"
One of the nice things about Textmate was the ability to pipe the contents of an entire scope into a command, like so:
You could then specify the scope to be used, such as meta.class.python or whatever.
I'm trying to write a small plugin that will pipe the entire current scope in as the input for the plugin (for example (not exactly what I'm trying to do, but close), a function that lets you comment out an entire Python class without selecting it all)
Using the current selection(s) as input is quite easy:
import sublime, sublime_plugin
import re
class DoStuffWithSelection(sublime_plugin.TextCommand):
def run(self, edit):
for region in self.view.sel():
if not region.empty():
changed = region # Do something to the selection
self.view.replace(edit, region, changed) # Replace the selection
I've scoured the Sublime Text plugin API for some way to do something like for region in self.view.scope(), but without success.
Is there a way, then, to use the contents of the current scope under the cursor as input for a plugin function? Or, even better, a way to use the entire scope if there isn't a selection, but use the selection if there is one.
Thanks!
If you want to get text that you select, the following code snippet is an example.
if not region.empty():
selectText = self.view.substr(region)
...
If you want to get text where the cursor is located, the following code snippet is an example.
if region.empty():
lineRegion = self.view.line(region)
lineText = self.view.substr(lineRegion)
...
To get more information, see http://net.tutsplus.com/tutorials/python-tutorials/how-to-create-a-sublime-text-2-plugin/ and http://www.sublimetext.com/docs/api-reference.