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()"
Related
I have a python script (we'll say "script.py") that I want to grab values from using a separate GUI python script ("GUI.py"). When I run my GUI.py script, I want to have these text fields in the GUI sent over to script.py after clicking a button in the GUI. I am thinking that my best solution might be to have the GUI.py create another script ("lib.py") that holds all these values and it just writes to it. It then runs the "script.py" script. So all in all the GUI.py will have a function that when called will look something like this:
def on_button(self):
username = self.usernameInput.get()
file = open(“lib.py”,”w”)
file.write(“username = ” + username)
os.system("script.py")
I think this will work, but I am just wondering, does this seem like a practical solution? Let me know what you guys think.
No, I don't think this is the practical solution.
Do you consider instead making the python script you want to run into a module or package that you can call directly inside your GUI? I think that is the cleanest approach. For using your scripts as modules, see the docs or for 2.7.
Basically a module is a python file, script.py, and as long as it is in the python path (say, your current directory), you can import it:
from script import action
So you could try:
def on_button(self):
username = self.usernameInput.get()
result = action(username) # and any other args you want to pass
print(result)
That is, if the script in question uses a if __name__ == "__main__": statement (or can otherwise be run from the command line), try putting the operations in some def action(args): function and importing it into your GUI.
There where many instances where I have to write large line of code over and over again in multiple programs. So I was wondering if I could write just one program, save it and then call it in different programs like a function or a module.
An elementary example: I write a program to check if a number is palindromic or not. Then I want to write a program to check if a number is palindromic and a prime, could I just call the first program and do the rest of the code to check if it is prime or not?
It is about writing reusable code. I can suggest you to write reusable code in specific function in separate python file and import that file and function too.
For example you need function called sum in other function called "bodmas" then write function called sum in one python file say suppose "allimports.py":
def sum(a,b):
return a+b
Now suppose your "bodmas" named function is some other python file then just import all the required functions and use is normally by calling it.
from allimports import sum
def bodmas:
print(sum(1,1))
One important thing is be specific while import your module as it will effect performance of your code when length of your code is long.
Suppose you want to use all functions then you can use two option like :
import allimports
print(allimports.sum(1,1))
other option is
from allimports import *
print(sum(1,1))
and for specific imports is as follows:
from allimports import sum
print(sum(1,1))
Yes. Let's say you're writing code in a file called palindrome.py. Then in another file, or in the python shell you want to use that code. You would type
import palindrome
either at the top of the file or just into the shell as a command. Then you can access functions you've written in palindrome.py with statements like
palindrome.is_palindrome('abba')
It's important to note that to do this propery, the code in palindrome.py must be in functions. If you're not sure how to do that, I recommend the official Python tutorial: https://docs.python.org/3/tutorial/index.html
it's easy to write a function in python.
first define a function is_palindromic,
def is_palindromic(num):
#some code here
return True
then define a function is_prime,
def is_prime(num):
#some code here
return True
at last, suppose you have a number 123321, you can call above function,
num = 123321
if is_palindromic(num):
if is_prime(num):
print 'this number is a prime!'
ps, maybe you could try to use some editors like vscode or sublime.
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)
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)
This is quite likely something simple that I have an issue with, but I do not have another machine to figure out if it's my laptop's python version right now.
When I run my program, I recieve the following error: "Type Error: function open() requires no arguments (2 given)"
The code snippet in question:
import tkinter as tk
from tkinter import filedialog as fdg
def update_queue():
conf_file = open("config.txt", "a")
fd = fdg.LoadFileDialog(master)
file = fd.go(pattern="*.jpg")
conf_file.write(file)
conf_file.close()
I'm not yet too good with Python, and would appreciate any pointers ("Your code looks twistier than last night's burnt spaghetti" counts as well) as to why the open() function fails.
Also of note, if I call open outside of a defined function, it opens the file, and can complete all actions done on it, but if I close the file, I cannot re open the file from within a function. I attempted to use the os file functions, but recieved the error "LoadFileDialog does not work with buffer-defined file functions." Understandable.
If I use conf_file.flush(), assuming I opened it outside of a function, will it flush whatever I write/append, so that I can read from the file again later?
EDIT: What I mean, is, will this work all the time, or would this be considered a hack?
is that the whole code? make sure you did not import another open function somewhere. or redefined it.
Assuming that open() was declared later on and you just didn't include it in the code, you probably declared it as
def open():
#code here
If this is the case, you just didn't add in the arguments when declaring the function and it should be:
def open(x, y):
#code here
where x and y could be anything you like.
Please come back and post the rest of your code (i highly doubt this is all of it) to get better answers. What is truly going on is at most a speculation on out part.