I am trying to grab an input from my main.py file using tkinter and then use that input in runAnalytics.py
main.py
import runAnalytics
import tkinter
import os
import centerWindow
loadApplication = tkinter.Tk()
loadApplication.title("Stock Analytics")
loadApplication.geometry("1080x720")
label1 = tkinter.Label(loadApplication, text = "Ticker")
input1 = tkinter.Entry(loadApplication)
loadAnalytics = tkinter.Button(loadApplication, text = "Load Analytics", command = runAnalytics.run)
centerWindow.center(loadApplication)
loadAnalytics.pack()
label1.pack()
input1.pack()
loadApplication.mainloop()
runAnalytics.py
from yahoo_finance import Share
from main import input1
import tkinter
import os
import centerWindow
def run():
ticker = input1
loadAnalytics = tkinter.Tk()
loadAnalytics.title("$" + ticker + " Data")
loadAnalytics.geometry("1080x720")
print ("Price per share: " + ticker.get_price())
ticker.refresh()
print ("Price per share: " + ticker.get_price())
print("The dividend yield is: " + ticker.get_dividend_yield())
print("The 52 week low is: " + ticker.get_year_low())
print("The 52 week high is: " + ticker.get_year_high())
print("The volume is: " + ticker.get_volume())
print("The previous close was: " + ticker.get_prev_close())
print("The previous open was: " + ticker.get_open())
loadAnalytics.mainloop()
My error message reads as follows;
Traceback (most recent call last):
File "C:\Users\MyName\Documents\Python Projects\MarketData\main.py", line 1, in <module>
import runAnalytics
File "C:\Users\MyName\Documents\Python Projects\MarketData\runAnalytics.py", line 2, in <module>
from main import input1
File "C:\Users\MyName\Documents\Python Projects\MarketData\main.py", line 13, in <module>
loadAnalytics = tkinter.Button(loadApplication, text = "Load Analytics", command = runAnalytics.run)
AttributeError: module 'runAnalytics' has no attribute 'run'
You have a circular import:
import runAnalytics
# ..
from main import input1
By the time main is being imported again, runAnalytics has not yet had a chance to execute the def run():.. section.
Resolve this by removing the from main import input1 line, and pass that object in as an argument instead:
def run(input1):
passing this in from the main.py module when you call the function:
loadAnalytics = tkinter.Button(loadApplication, text = "Load Analytics", command = lambda: runAnalytics.run(input1))
Apart from the circular import, there is also the issue that whatever file you run as the main script in Python will be stored as the __main__ module. Importing that same script again will lead to a second module being created, now under the name main, and any objects created in that module are distinct from those in __main__.
Next, you'll want to remove the loadAnalytics.mainloop() call from run as you should not start a new mainloop from an already running loop. You probably also want to create a new TopLevel window instead of creating another Tk() root. You'd have to pass in loadApplication to run too if you go this way.
from runAnalytics import run
loadAnalytics = tkinter.Button(loadApplication, text="Load Analytics", command=run)
You don't want to start another mainloop of tk. Instead you should pass the root and create a toplevel window.
def run(root):
ticker = input1
parent = Toplevel(root)
parent.title("$" + ticker + " Data")
# the rest of your code
Try adding () to the end of runAnalytics.run. You are currently telling it to look for a run attribute which it doesn't have instead of a function
loadAnalytics = tkinter.Button(loadApplication, text = "Load Analytics", command = runAnalytics.run())
Related
I just started on Python, and still trying to learn it. I recently started learning Sikulix and its applications. Would highly appreciate if you could share your ideas...
Problem is that I have 3 py files. Say:
main.py
checkInventory.py
startMining.py
I only defined 1 function on checkInventory.py, startMining.py each, functions are also named after the file names (checkInventory(), startMining() respectively)
When I run the main.py it is calling checkInventory() using:
beginning of main.py...
from checkInventoryStatus import *
No problem on this. I can call checkInventoryStatus() function with no problem on main.py.
However, checkInventory() also runs startMining() at some point and it keeps giving this error:
NameError ( global name 'startMining' is not defined )
I am also importing all the content of startMining.py to checkInventory.py using:
beginning of checkInventory.py...
from startMining import *
I tried to import all elements of startMining.py to checkInventory.py but it is failing to call the function startMining() from checkInventory.py.
Main
from startMining import *
from watchMining import *
from checkInventoryStatus import *
def startApp():
KO = switchApp("KL")
checkInventoryStatus()
with open("C:\Users\PC\Desktop\skx\logs.txt", "w") as f:
f.write("App started!\n")
startApp()
checkInventoryStatus
from sikuli import *
from startMining import *
from watchMining import *
def checkInventoryStatus():
if(exists("1673723539914.png")):
if(exists(Pattern("1673723411692.png").exact())):
startMining()
startMining.py
from sikuli import *
from watchMining import *
from checkInventoryStatus import *
def startMining():
wait(0.6)
type(Key.ENTER + "/town" + Key.ENTER)
arrived = False
wait(0.3)
try:
click(Pattern("1673722724479.png").similar(0.58))
wait(1.5)
while(True):
if(exists(Pattern("1673729480660.png").exact())):
click(Pattern("1673729480660.png").exact())
mouseMove((Location(700, 500)))
X_Coordinate_Region = Region(105,75,30,14)
Y_Coordinate_Region = Region(139,77,25,11)
X_Coordinate = X_Coordinate_Region.text()
Y_Coordinate = Y_Coordinate_Region.text()
X_temp = X_Coordinate_Region.text()
Y_temp = Y_Coordinate_Region.text()
wait(0.45)
X_Coordinate_Region = Region(105,75,30,14)
Y_Coordinate_Region = Region(139,77,25,11)
X_Coordinate = X_Coordinate_Region.text()
Y_Coordinate = Y_Coordinate_Region.text()
if X_temp==X_Coordinate_Region.text() and Y_temp==Y_Coordinate_Region.text() and arrived==False:
startMining()
try:
if abs(int(X_Coordinate_Region.text())-1490)<30 and abs(int(Y_Coordinate_Region.text())-540)<30:
arrrived=True
type("s")
mouseMove(mouseMove(Location(0, 500)))
wait(0.95)
mouseMove((Location(700, 500)))
click(Pattern("1673398228807.png").similar(0.50))
while(True):
if(exists(Pattern("1673729480660.png").exact())):
click(Pattern("1673729480660.png").exact())
mouseMove((Location(700, 500)))
arrived=False
try:
if abs(int(X_Coordinate_Region.text())-1453)<30 and abs(int(Y_Coordinate_Region.text())-380)<30:
arrrived=True
type("s")
type(" ")
break
except:
continue
except:
continue
#f.write("\nX:" +X_Coordinate+" Y: "+Y_Coordinate+"\n")
with open("C:\Users\PC\Desktop\skx\logs.txt", "a") as f:
f.write("\nX:" +X_Coordinate+" Y: "+Y_Coordinate+"\n")
wait(0.5)
except:
mouseMove(mouseMove(Location(0, 500)))
wait(0.4)
mouseMove((Location(700, 500)))
startMining()
Here is the error message:
[error] script [ main ] stopped with error in line 13
[error] NameError ( global name 'startMining' is not defined )
[error] --- Traceback --- error source first
line: module ( function ) statement
9: checkInventoryStatus ( checkInventoryStatus ) startMining()
8: main ( startApp ) checkInventoryStatus()
13: main ( <module> ) startApp()
[error] --- Traceback --- end --------------
I believe it is due to "circular import" behavior between checkInventoryStatus.py and startMining.py.
You can structure your code in a way that eliminates calling modules in a circular motion. For example, you can move checkInventoryStatus() into startMining.py which will kill the dependency to checkInventoryStatus.py (assuming that all you code consists of only these three scripts.)
I'm writing a Tkinter with gspread app. I believe the connections to the spreadsheets are made properly because i can read data off it. I'm using python 2.7.15 and gspread 0.6.2. I get the error. If i leave out the 'RAW' argument at the end of the function call, I no longer get any errors, but nothing gets written to the spreadsheet.
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1550, in __call__
return self.func(*args)
File "app.py", line 22, in clicked
sheet.insert_row(insertRow,index,'RAW')
TypeError: insert_row() takes at most 3 arguments (4 given)
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from Tkinter import *
scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"]
creds = ServiceAccountCredentials.from_json_keyfile_name("client_secret.json", scope)
client = gspread.authorize(creds)
sheet = client.open("This").sheet1 # Open the spreadhseet
#data = sheet.get_all_records() # Get a list of all records
#row = sheet.row_values(3) # Get a specific row
#col = sheet.col_values(3) # Get a specific column
#cell = sheet.cell(1,2).value # Get the value of a specific cell
def clicked():
index = sheet.row_count
index+=1
insertRow = [nametxt.get(),placetxt.get(), phonetxt.get()]
sheet.insert_row(insertRow,index,'RAW')
window = Tk()
window.title("Registration application")
window.geometry('700x700')
namelbl = Label(window, text="Name",font=("Ubuntu",20))
placelbl = Label(window, text="Place", font=("Ubuntu",20))
phonelbl = Label(window,text="Phone No", font=("Ubuntu",20))
placetxt = Entry(window,width = 20)
nametxt = Entry(window,width=20)
phonetxt = Entry(window,width = 20)
namelbl.grid(column=1, row=1,)
nametxt.grid(column=2, row=1)
placelbl.grid(column=1, row=2)
placetxt.grid(column=2,row=2)
phonelbl.grid(column =1, row=3)
phonetxt.grid(column = 2,row=3)
button = Button(window, text="submit",command=clicked)
button.grid(column=2, row=5)
window.mainloop()
#sheet.update_cell(2,2, "CHANGED") # Update one cell
You're using an old version of gspread. In the version you're using the definition of insert_row looks like this:
def insert_row(self, values, index=1):
Notice how it takes only three arguments: self (automatically passed when called on an instance), along with values and index. It doesn't accept any other parameters. You need to remove the RAW argument for your code to work with this version of the library.
the line : with open('new%s.txt' % intg ,'a') as g : is giving error in below code.
Every time I call the function "Repeat", it should create file with name new1.txt, new2.txt and so on.
But it is giving error : "name 'intg' is not defined"
I want dynamic name for screenshot file and txt file, to prevent overwriting of file.
The code is for selecting data from a software, copying it, and pasting it in new file each time.
Please help:
import win32api
import win32com.client
import pyautogui
import pyperclip
shell = win32com.client.Dispatch("WScript.Shell")
win32api.Sleep(5000)
def repeat( intg ):
import pyautogui
pyautogui.moveTo(17, 213)
win32api.Sleep(2000)
pyautogui.screenshot('%s.png' % intg)
pyautogui.click()
win32api.Sleep(2000)
pyautogui.hotkey('ctrl', 'c')
s = pyperclip.paste()
win32api.Sleep(2000)
with open('new%s.txt' % intg ,'a') as g:
g.write(s)
print("done")
repeat( intg = 1 )
repeat( intg = 2 )
win32api.Sleep(5000)
print ("done")
you can concatenate integer and strings doing so:
with open('new' + str(intg) + '.txt','a') as g:
or doing so:
with open('new{0}.txt'.format(intg),'a') as g:
I'm receiving the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "D:\COMPUTER SCIENCE\Seating Plan\SeatingPlan TEST.py", line 205, in displayText
if roomChange.get().strip() == "":
NameError: global name 'roomChange' is not defined
When attempting to run the following code:
from tkinter import *
import tkinter.messagebox
def displayText():
""" Display the Entry text value. """
global roomChange
if roomChange.get().strip() == "":
tkinter.messagebox.showerror("Invalid Value", "Please enter a valid classroom name.")
else:
tkinter.messagebox.showinfo("Temporary Window", "Text value = " + roomChange.get().strip())
def roomChanger():
chrm = Tk()
chrm.title("Change Room")
chrm.wm_iconbitmap('./Includes/icon.ico')
chrm["padx"] = 40
chrm["pady"] = 20
# Create a text frame to hold the text Label and the Entry widget
textFrame = Frame(chrm)
#Create a Label in textFrame
roomChangeLabel = Label(textFrame)
roomChangeLabel["text"] = "Enter name of classroom: "
roomChangeLabel.pack(side=LEFT)
# Create an Entry Widget in textFrame
roomChange = Entry(textFrame)
roomChange["width"] = 50
roomChange.pack(side=LEFT)
textFrame.pack()
roomChangeButton = Button(chrm, text="Submit", command=displayText)
roomChangeButton.pack()
chrm.mainloop()
testButton = Button(window, text='Change Room', command=roomChanger)
testButton.place(x = 825, y = 360)
Can anyone suggest a solution to my problem?
Thanks
In roomChanger() you assign to roomChange:
roomChange = Entry(textFrame)
so you need to mark that name as a global inside that function too. Add a global roomChange statement in that function.
displayText() on the other hand, never tries to assign to roomChange and the global statement in that function can safely be removed.
I had the same problem.
Here was my solution:
from tkinter import *
from tkinter import messagebox
Some sort of namespace glitch. That second line shouldn't be necessary. Technically from a syntax perspective import * implies import messagebox too because it's part of it all.
Use those two lines, take away import tkinter.messagebox
This is a GUI I’ve been writing for a script I already have working. What I’m struggling with here is retrieving the information in the textboxes.
Under the definition generate I am able to pop a name off of listx but I am unable to grab the local variable entry from any of the instances of the new_title_box class.
from Tkinter import *
import ttk
boxvar=""
folder=""
listx=[]
count = 1
myrow = 1
class new_title_box:
def __init__(self,name):
global myrow, count, listx
self.entry = StringVar()
self.name = name
self.name = ttk.Entry(mainframe,width=45,textvariable=self.entry)
self.name.grid(column=1,row=myrow+1,sticky=(N,W))
listx.append(name)
print(listx) ## For debugging to insure that it is working correctly, if it gives output it, this part works
myrow = myrow + 1
count=count+1
def make_new(*args):
new_title_box('box'+str(count))
def generate(*args):
global listx, boxvar
while len(listx) > 0:
boxvar=listx.pop(0)
print(boxvar) ## For debugging to insure that it is working correctly, if it gives output it, this part works
folder = boxvar.entry.get() ## Not working here
print(folder) ## For debugging to insure that it is working correctly, if it gives output it, this part works
root = Tk()
root.title("File Maker")
mainframe = ttk.Frame(root, padding = "50 50 50 50")
mainframe.grid(column = 0,row = 0,sticky = (N, W, E, S))
mainframe.columnconfigure(0,weight=1)
mainframe.columnconfigure(0,weight=1)
add_entry = ttk.Button(mainframe,width=20, text = "add entry", command=make_new)
add_entry.grid(column=2,row=2,sticky=(N,W))
add_entry = ttk.Button(mainframe,width=20, text = "make files", command=generate)
add_entry.grid(column=2,row=3,sticky=(N,W))
root.mainloop()
Here's the traceback I'm getting:
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:\python\SampAqTkinter.py", line 28, in generate
folder = boxvar.entry ## Not working here
AttributeError: 'str' object has no attribute 'entry'
There are two things that need to be changed to fix the problem you describe:
In the new_title_box.__init__() method change: listx.append(name) to listx.append(self.name)
In the generate() function, change: folder = boxvar.entry.get() to folder = boxvar.get().
You are appending a string to listx, use self.name instead of the local string name