This is my first attempt at using the Tkinter plugin, I know very little past what tutorials I could find. All the answers I've seen so far put a class inside the py file that your building, I however have a plethora of tests that are already compiled into a Test class that runs many separate tests. All the tests run and no errors are encountered before trying to add to the ui.
I would like to be able to run each suite by clicking a button. My problem seems that I'm missing a step some where but not getting any errors or action when I click the button, but an error after I click and close the ui window. I should point out that importing the settings file (which contains most of the webdriver imports) does not help either. I get the same error.
Traceback:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python37\lib\tkinter\__init__.py", line 1702, in __call__
return self.func(*args)
File "C:\Python37\lib\unittest\case.py", line 663, in __call__
return self.run(*args, **kwds)
File "C:\Python37\lib\unittest\case.py", line 590, in run
testMethod = getattr(self, self._testMethodName)
AttributeError: 'Test' object has no attribute 'runTest'
My ui code:
import sys, os, tkinter, TESTadmin
top = tkinter.Tk()
a = TESTadmin.Test()
B = tkinter.Button(top, text= "Test Window", command=a )
B.pack()
top.mainloop()
for clarity my main test file:
from helpers.settings import *
from pieces import adminLogin, adminLogout, docs
class Test(unittest.TestCase):
def setUp(self):
# Maximize Window (remove quotes to use)
'''sel.maximize_window()'''
self.browser = webdriver.Firefox()
self.browser.get("https://mywebsite.net")
# We instantiate and start the browser
def testCases(self):# Add Tests Below
#log in to admin side
login = adminLogin.AdminLogin.do(self)
#docs page
docpage = docs.Docs.do(self)
#log out
logout = adminLogout.Logout.do(self)
if G.log:
for k in G.log.items():
print(k)
### Uncomment to close browser after test ###
def tearDown(self):
self.browser.close()
if __name__ == "__main__":
unittest.main()
As it would turn out, the answer like I thought is simple.
this line :
def testCases(self):
needs to read:
def runTest(self):
after that change every thing works percectly.
My confusion is because originally when building these tests I was following the directions here -> https://selenium-python.readthedocs.io/
They show you to use the testCases() method, and this works! Just not for calling the class. I didn't know where to put the function let alone know that Webdriver had a built in function other than what i was using.
Related
I'm using BotCity for automation but the system doesn't work.
After listing the image and indicating the action on the UI tab, BotCity does not create the code on the 'CODE' tab, how can I solve this problem?
from botcity.core import DesktopBot
from botcity.maestro import *
class Bot(DesktopBot):
def action(self, execution=None):
self.browse("https://www.facebook.com/groups/xxxxxx")
#in this field, the code should be created after the image is selected, but that doesn't happen, even if I leave the course selected in this line
def not_found(self, label):
print(f"Element not found: {label}")
if __name__ == '__main__':
Bot.main()
I have 2 files. one is for the login GUI using tkinter and the other is for the login/verification process. In the screenshot the root file runs just fine. When I run the login file the gui box pops up, but when I close it I get an error ---->
'''File "c:/Users/j/Desktop/pyth/login.py", line 20, in <module>
Log.auth()
File "c:/Users/j/Desktop/pyth/login.py", line 10, in auth
if (self.user == Application.capture(self).verify and self.pw == Application.capture(self).verify2):
File "c:\Users\j\Desktop\pyth\root.py", line 24, in capture
self.verify=self.username.get()
AttributeError: 'Acess' object has no attribute 'username'''
I understand what the error means, but I'm not sure how to go about fixing it. Ultimately I'm trying to get the input from the login box once the "LOGIN" button is clicked and see if it matches the assigned user and pw which is what's going on in the login file.
What happens is that when you run login.py, the code you wrote in root.py is executed due to the from root import Application. This is why the GUI shows up.
Then when you close the GUI, the code Log = Acess(.., ...) then Log.auth() is executed and at line 10 of login.py you pass self to the capture method of Application.
And in the capture method, self.username is trying to access username of Acess which does not exists and thus crash the code
You could move the code in the root.py file and pass the application to the Acess class and store it in an attribute which will be used in the auth function instead of Application
root = tk.tk()
app = Application(master=root)
root.mainloop
Log = Acess("user", "pwd")
Log.auth()
I am trying to put together a GUI that would read from a continuously updated TXT file and updated every once in a while. So far I succeeded with the first part and I am failing to use 'root.after()' to loop the whole thing but it results in NameError:
import tkinter as tk
root = tk.Tk()
class App:
def __init__(self, root):
frame = tk.Frame(root)
frame.pack()
iAutoInEN = 0
iAvailableEN = 0
self.tkAutoInEN = tk.StringVar()
self.tkAutoInEN.set(iAutoInEN)
self.tbAutoInEN = tk.Label(root, textvariable=self.tkAutoInEN)
self.tbAutoInEN.pack(side=tk.LEFT)
self.button = tk.Button(frame, text="Start", fg="red",
command=self.get_text)
self.button.pack(side=tk.LEFT)
def get_text(self):
fText = open("report.txt") #open a text file in the same folder
sContents = fText.read() #read the contents
fText.close()
# omitted working code that parses the text to lines and lines
# to items and marks them with numbers based on which they are
# allocated to a variable
if iLineCounter == 1 and iItemCounter == 3:
iAutoInEN = int(sItem)
self.tkAutoInEN.set(iAutoInEN)
root.after(1000,root,get_text(self))
app = App(root)
root.mainloop()
try:
root.destroy() # optional; see description below
except:
pass
The first instance runs without any problems and updates the value from 0 to the number in the TXT file but is accompanied with an error
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\...\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/.../pythonlab/GUI3.py", line 117, in get_text
self.after(1000,root,get_text())
NameError: name 'get_text' is not defined
EDIT:
When changed to the recommended "self.after(1000,self.get_text)"
class App:
...
def get_text(self):
fText = open("report.txt") #open a text file in the same folder
sContents = fText.read() #read the contents
fText.close()
# omitted code
if iLineCounter == 1 and iItemCounter == 3:
iAutoInEN = int(sItem)
self.tkAutoInEN.set(iAutoInEN)
self.after(1000,self.get_text)
Error changes
Traceback (most recent call last):
File "C:/.../pythonlab/GUI3.py", line 6, in <module>
class App:
File "C:/.../pythonlab/GUI3.py", line 117, in App
self.after(1000, self.get_text)
NameError: name 'self' is not defined
Also please consider this is my very first programme (not only) in Python, so I would appreciate if you are a little bit more explicit with your answers (e.g. when pointing out an indentation error, please refer to an exact line of code).
Because get_text is a method of App class you should call it as self.get_text.
After is a tkinter method. In that case you should call it as root.after. And self refers to the class you are in. So because get_text is a method of current class you should call is with self which is like this in other programming languages like Java.
...
root.after(1000, self.get_text)
...
Firstly, like James commented, you should fix your indentation so that the functions are a part of the class.
Then, change this line
root.after(1000,root,get_text(self))
to this
root.after(1000, self.get_text)
Check out the answer to the following question, which uses the code I just gave you:
Tkinter, executing functions over time
I am making a GUI with tkinter that allows me to click a button that will run a port scan. I have a script for a port scan that functions correctly, I have managed to open the port scanner through the button on the GUI but then I receive an error that I otherwise don't receive when running the port scanner alone.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Steve\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1550, in __call__
return self.func(*args)
File "<string>", line 51, in Scan
NameError: name 'IP_Input' is not defined
My code:
class CallWrapper:
"""Internal class. Stores function to call when some user
defined Tcl function is called e.g. after an event occurred."""
def __init__(self, func, subst, widget):
"""Store FUNC, SUBST and WIDGET as members."""
self.func = func
self.subst = subst
self.widget = widget
def __call__(self, *args):
"""Apply first function SUBST to arguments, than FUNC."""
try:
if self.subst:
args = self.subst(*args)
return self.func(*args) # THIS IS THE ERROR #
except SystemExit:
raise
except:
self.widget._report_exception()
class XView:
"""Mix-in class for querying and changing the horizontal position
of a widget's window."""
def xview(self, *args):
"""Query and change the horizontal position of the view."""
res = self.tk.call(self._w, 'xview', *args)
THIS IS THE CODE FOLLOWING FOR THE LINE 51 ERROR
def Scan():
print ('Scan Called.') #Debugging
IP = str(IP_Input.get(0.0, tkinter.END)) #THIS IS ERROR LINE 51#
print ("IP #Debugging")
Start = int(PortS.get(0.0, tkinter.END))
End = int(PortE.get(0.0, tkinter.END))
TestSocket = socket.socket()
CurrentPort = Start
OpenPorts = 0
print ('Starting scan...')
HowFar = int(CurrentPort/End * 100)
ProgText = HowFar, r'%'
Label1.config(text=('Percentage Done:', ProgText))
The problem is with your exec statement. You're opening your other .py file named port_scanner.py and then calling exec(open("./port scanner.py)).
This just isn't going to work.
Why this doesn't work:
When you do exec(open("path to .py file").read()) exec is of course executing this code, but the problem is that the global variables in this file aren't within the scope.
So, to make this work (which I don't recommend) you'd have to use:
exec(open(path).read(), globals())
From the documentation
If the globals dictionary does not contain a value for the key builtins, a reference to the dictionary of the built-in module builtins is inserted under that key. That way you can control what builtins are available to the executed code by inserting your own builtins dictionary into globals before passing it to exec().
If you really want to call your file this way then you should just use os.system.
Alternative approach:
You really don't need to call your file this way. You now have two instances of Tk() running. If you need another window then a widget is provided for this purpose. It is the Toplevel widget. You can restructure your code to create a Toplevel instance containing the port scanner app on your button click. An example being, create your port scanner app with the Toplevel widget (in your other file if you wish) then import the "app" into your file and on the button click have it initialize the app.
Additional Notes:
You're calling a while loop and if this runs (for any noticeable amount of time) then this is going to block the GUI's main event loop and causing your GUI to "hang".
Your first guess should not be that a part of the widely tested and used python standard library is flawed. The problem is (99.9% of the time)
while True:
print("In your own code.")
I get an AttributeError I can't seem to work out.
I'm working with two classes.
The first class goes something like that.
class Partie:
def __init__(self):
# deleted lines
self.interface = Interface(jeu=self)
def evaluerProposition(self):
# computations
self.interface.afficherReponse()
Introducing second class (in a separate file).
class Interface:
def __init__(self, jeu):
self.jeu = jeu
self.root = tkinter.Tk()
# stuff
def onClick(self, event):
# talk
self.jeu.evaluerProposition()
def afficherReponse(self):
# stuff
I start the whole thing by
partie = Partie()
All manipulations on my widget work fine until some click event causes
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeInterface.py", line 197, in clic
self.jeu.evaluerProposition()
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeJeu.py", line 55, in evaluerProposition
self.interface.afficherReponse()
AttributeError: 'Partie' object has no attribute 'interface'
I typed in the interpretor
>>> dir(partie)
and got a long list in return with 'interface' among the attributes.
Also typed
>>> partie.interface
<classeInterface.Interface object at 0x02C39E50>
so the attribute seems to exist.
Following the advice in some former post, I checked the instance names do not coincide with module names.
I am confused.
Most likely, in some code that you're not showing us, you're doing something like this:
self.some_button = tkinter.Button(..., command=self.interface.onClick())
Note the trailing () on onClick(). This would cause the onClick method to be called at the time the button is created, which is probably before your constructor is done constructing the instance of the Partie class.