Python 3.6 - AttributeError: module 'tkinter' has no attribute 'filedialog' - python-3.x

My function was working perfectly fine few minutes ago. Did not modify the code, just installed PyAudio. I get the error as per subject. It doesn't matter if run it from command line or IDE, same error. Any ideas?
def DataFinder():
#imports and initialize
import pandas as pd
import tkinter as tk
finder = tk.Tk()
finder.withdraw()
__dataFlag = False
#ask user to select a file
__path = tk.filedialog.askopenfilename()
#check the extension to handle reader
#for csv files
if __path.endswith('.csv')==True:
df = pd.read_csv(__path,header=0)
return df
__dataFlag = True
#and for excel files
elif __path.endswith('.xls')==True:
df = pd.read_excel(__path,header=0)
return df
__dataFlag = True
#if a file is not a supported type display message and quit
else:
__dataFlag = False
#check if there is a data to be returned
if __dataFlag==True:
return df
else:
print('The file format is not supported in this version.')

Explicitly import of filedialog can solve the problem.
So, you just need to add this line to your codes:
import tkinter.filedialog
You can find more information at Why tkinter module raises attribute error when run via command line but not when run via IDLE?

the following code didn't work for me:
import tkinter as tk
import tkinter.filedialog
But the following did work:
import tkinter
import tkinter.filedialog
and also this:
import tkinter.filedialog
import tkinter as tk
Hope this helps
Note
As mentioned by Vaidøtas I., you can't import filedialog from tkinter. Because you did not import the original tkinter but an aliased version tk.

Related

Change WM_CLASS of Dialog (tkinter)

Is there a way to change WM_CLASS of showinfo (and other dialogs)? className, class_ parameters do the job for Tk, Toplevel.
import tkinter as tk
from tkinter.messagebox import showinfo
if __name__ == '__main__':
root = tk.Tk(className='ymail')
mail_client = tk.Toplevel(root, class_='ymail')
new_message = tk.Toplevel(root, class_='ymail')
showinfo(title="Cancel sending", parent=new_message, message="""
Send is cancelled due to empty message""")
root.mainloop()
For showinfo dialog
$ xprop WM_CLASS
gives
WM_CLASS(STRING) = "__tk__messagebox", "Dialog"
I think it is convenient to cycle tkinter windows with Alt-~ (Tilde), for which their WM_CLASS shall be the same.
I did the search ("tkinter change WM_CLASS showinfo"). Some of the hits are not applicable, some don't work (xdotool), and some I'd rather use as a last resort (converting C program to python).
Using
Debian 10
python 3.7.3
GNOME 3.30.1
EDIT
Added workaround (using xdotool)
import threading
import subprocess
import time
import tkinter as tk
from tkinter.messagebox import showinfo
def change_dialog_class(from_="Dialog", to_="ymail"):
cmd = f"xdotool search --class {from_} set_window --class {to_}"
time.sleep(1)
subprocess.run(cmd.split())
if __name__ == '__main__':
root = tk.Tk(className='ymail')
mail_client = tk.Toplevel(root, class_='ymail')
new_message = tk.Toplevel(root, class_='ymail')
tk.Frame.class_ = 'ymail'
threading.Thread(target=change_dialog_class, args=("Dialog", "ymail"),
daemon=True).start()
showinfo(title="Cancel sending", parent=new_message,
message="""Send is cancelled due to empty message""")
root.mainloop()
along with ymail.desktop it works
$ cat ~/.local/share/applications/ymail.desktop
[Desktop Entry]
Type=Application
Terminal=false
Name=ymail
Icon=python
StartupWMClass=ymail
yet, the python solution would be better
Since I'm not a XSystem user it took me some time to follow up. It
seems like that you are looking for wm_group and unfortunately it isnt
possible without subclassing it, which results in pretty much the same
as writing your own class with tk.Toplevel. Anyway I hope
toplevel.wm_group(root) ease things out and works for you.
After I noticed that the SimpleDialog may has some functionality that you want to keep and can be hard to code for yourself, I decided to write an answer that you may want to use. It also provides the class_ option in case wm_group dosent work for you.
Here is the code:
import tkinter as tk
import tkinter.simpledialog as simpledialog
class MessageBox(simpledialog.SimpleDialog):
def __init__(self, master,**kwargs):
simpledialog.SimpleDialog.__init__(self,master,**kwargs)
#root.tk.call('wm', 'group', self.root._w, master)
def done(self,num):
print(num)
self.root.destroy()
root = tk.Tk()
MessageBox(root,title='Cancel',text='Im telling you!',class_='ymail',
buttons=['Got it!','Nah'], default=None, cancel=None)
root.mainloop()
and here is the source:
https://github.com/python/cpython/blob/main/Lib/tkinter/simpledialog.py#L31

Tkinter AssertionError: Python3 Web App using selenium won't input search term in driver.title

I have been learning python for the past 10 months; I am also new to StackOverflow so hope you will forgive any errors in communicating here. My simple web application uses Selenium to automatically go to a specific website and enters a search term in the driver.title input box. Now all works but I get an AssertionError. I looked on StackOverflow and other websites but couldn't figure out how to solve this one. My goal was to teach myself how to use Selenium to automate. My app was built using Jupyter Notebook v6.0.1 which uses Python3.7.
I would be grateful for your help/tips. Many Thanks, Sean
Here is the error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Users/seankerr/opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "<ipython-input-9-c3e0a628cdec>", line 38, in hackathons
assert "hackathons" in driver.title
AssertionError
Here is the python code:
import selenium
import tkinter as tk
from tkinter import *
from tkinter import messagebox #SEAN NOTE: you don't need to import message box from
#tkinter separately because you have already imported '*' all tkinter tools/widgets
import os
import subprocess
import platform
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
def ask_quit():
if messagebox.askokcancel("Quit","Are you sure you want to quit the application and close the window?"):
root.destroy()
root = tk.Tk()
root.title("Hackathon Fetcher")
root.geometry('200x200+200+200')
root.protocol("WM_DELETE_WINDOW", ask_quit)
def raise_app(root: Tk):
root.attributes("-topmost", True)
root.title("Test Title")
if platform.system() == 'Darwin':
tmpl = 'tell application "System Events" to set frontmost of every process whose unix id is {} to true'
script = tmpl.format(os.getpid())
output = subprocess.check_call(['/usr/bin/osascript', '-e', script])
root.after(0, lambda: root.attributes("-topmost", False))
def hackathons():
driver = webdriver.Chrome("./chromedriver")
driver.get("https://challengerocket.com/hackathons-and-challenges.html")
assert "hackathons" in driver.title
elem = driver.find_element_by_name("searchitems")
elem.send_keys("python")
elem.send_keys(Keys.RETURN)
Button(root, text= 'Fetch Python Hackathons', command = hackathons).pack(padx = 20)
#Button(root, text= "Quit", command = ask_quit).pack(expand=1, fill=tk.Y)
root.mainloop()

How to run python function by clicking html button?

I am trying to make this web app to work but I am getting an error. these are the steps that web app is supposed to handle:
import a file
run the python script
export the results
when I run python script independently( without interfering with flask), it works fine( I use Jupyter notebook) on the other hand, when I run it with flask (from prompt) I get an error:
File "app.py", line 88, in <module>
for name, df in transformed_dict.items():
NameError: name 'transformed_dict' is not defined
Any idea of how can I make this web app to work?
This is my first time using flask and I will appreciate any suggestions or guidance.
python file & html file
from flask import Flask,render_template,request,send_file
from flask_sqlalchemy import SQLAlchemy
import os
import pandas as pd
from openpyxl import load_workbook
import sqlalchemy as db
def transform(df):
# Some data processing here
return df
app=Flask(__name__)
#app.route('/')
def index():
return render_template('firstpage.html')
#app.route('/upload',methods=['Get','POST'])
def upload():
file=request.files['inputfile']
xls=pd.ExcelFile(file)
name_dict = {}
snames = xls.sheet_names
for sn in snames:
name_dict[sn] = xls.parse(sn)
for key, value in name_dict.items():
transform(value)
transformed_dict={}
for key, value in name_dict.items():
transformed_dict[key]=transform(value)
#### wirte to excel example:
writer = pd.ExcelWriter("MyData.xlsx", engine='xlsxwriter')
for name, df in transformed_dict.items():
df.to_excel(writer, sheet_name=name)
writer.save()
if __name__=='__main__':
app.run(port=5000)
Your block:
#### wirte to excel example:
writer = pd.ExcelWriter("MyData.xlsx", engine='xlsxwriter')
for name, df in transformed_dict.items():
df.to_excel(writer, sheet_name=name)
writer.save()
should be part of your upload() function since that's where you define and fill transformed_dict. You just need to match the indentation there to the block above it.
The current error is coming up because it's trying to run that code as soon as you start your script, and transformed_dict doesn't exist at that point.

Error <Class> has not attribute <method> in Tkinter

I am trying to link a tkinter frame to another one, but I get this error
AttributeError: 'mainscreen' object has no attribute 'nextscreen'
my code is below :
What is the meaning of this error?
from tkinter import ttk
from tkinter import *
import tkinter
import imap
class mainscreen():
def __init__(self,tkgui):
global w,x
self.tkgui =tkgui
tkgui.configure(background='red')
Label(tkgui,text='please Enter your email',bg='red',fg='white').grid(row=0,column=2)
e=Entry(tkgui,width=20)
e.grid(row=1,column=2)
w=e.get()
print(w)
Label(tkgui,text='please Enter your Password',bg='red',fg='white').grid(row=2,column=2)
p=Entry(tkgui,width=20,show='*')
p.grid(row=3,column=2,sticky=w)
x=p.get()
Button(tkgui,text="Sign ON").grid(row=5,column=2)
Button.bind('<button>',self.nextscreen())
def nexscreen(self,event):
inboxscreen=imap.signin(w,x)
tkgui=tkinter.Tk()
app=mainscreen(tkgui)
tkgui.mainloop()
It looks as though you have a typo. In your code, the function is named nexscreen but you call it with nextscreen

python3.2 tkinter display an image from a URL

I'm trying to use tkinter on python 3.2 to display an image from the Internet.
I'm getting TypeError: 'HTTPResponse' object is not callable.I know that this means I'm referencing a variable or function incorrectly.
I have read urllib "module object is not callable" but I'm still not sure how to fix this problem. Your help is appreciated.
import tkinter as tk
from urllib.request import urlopen
from PIL import ImageTk, Image
#http://docs.activestate.com/activepython/3.1/diveintopython3/html/porting-code- to-python-3-with-2to3.html
import io
img_file = urlopen('https://www.google.com/images/srpr/logo4w.png')
im = io.FileIO(img_file())<<<<<<<<<<<<<this line is throwing the error
resized_image = Image.open(im)
im.show()
root = tk.Tk()
img = ImageTk.PhotoImage(resized_image)
panel = tk.Label(root, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
root.mainloop()
You can create a StringIO object instead:
from StringIO import StringIO
...
im = StringIO(img_file.read())
It behaves like a file, but it's not a file.

Resources