I am a newbie to tkinter and have know idea what I am doing sometimes:D . I created a python script to get Corona Virus Stats from a GitHub post link The script has over 20 files in it so I thought I should just create one file to run all the other files. So what other better way to do it than creating a UI. And that's what I did I used tkinter to run all the files. If they clicked on x button then I would run abc. And I ended up running these files by importing them in a certain order(Don't know If that was the best way). So here is where I ran into an error. I don't exactly know if this error is because of how I imported my files or my tkinter code is just wrong. I just couldn't seem to click on a button twice. I would run my program and click on a button, it would run properly and then the next time I clicked on that same button It would just not work. There was no error and no output. Nothing would happen. Here is my code:
#Import tkinter
import tkinter as tk
from tkinter import *
from tkinter import simpledialog
tk = tk.Tk()
Max = 190
def RunDeaths():
#If they click on RunDeaths I will run this function
#Check if they have already entered a path
try:
open('/Users/test/Documents/python/Py_Programs/Hackathon/DeathStats/Info.txt','r')
from DeathStats import RunAll
except:
YourPath = simpledialog.askstring('Countries','''Please Enter Your Path To HACKATHON Folder:
Example:
\"/Users/Name/Documents/python/\"
Note: Leave out the HACKATHON folder and you must put a slash at the end''',parent=tk)
#Write this path to a file call Info.txt
file = open('/Users/test/Documents/python/Py_Programs/Hackathon/DeathStats/Info.txt','w')
file.write(str(YourPath)+'\n')
file.write(str(Max))
file.close()
#Run all the files that gather the data for Corona Virus Deaths
from DeathStats import RunAll
def RunRecoveredCases():
#If they click on RecoveredCases Run this
#Check If they had already entered a path
try:
open('/Users/test/Documents/python/Py_Programs/Hackathon/RecoveredCases/Info.txt','r')
from RecoveredCases import RunAll
except:
YourPath = simpledialog.askstring('Countries','''Please Enter Your Path To HACKATHON Folder:
Example:
\"/Users/Name/Documents/python/\"
Note: Leave out the HACKATHON folder and you must put a slash at the end''',parent=tk)
file = open('/Users/test/Documents/python/Py_Programs/Hackathon/RecoveredCases/Info.txt','w')
#Write there path to a file
file.write(str(YourPath)+'\n')
file.write(str(Max))
file.close()
#Run all the files that gather all the Recovered Cases
from RecoveredCases import RunAll
#* * Here is where I think I went wrong But Im not sure
Deaths = Button(tk,height = 20, width = 30, text='Run Deaths',command = RunDeaths,highlightbackground='#000000')
Recovered = Button(tk,height = 20, width = 30, text='Run Recovered Cases',command = RunRecoveredCases,highlightbackground='#000000')
Deaths.pack()
Recovered.pack()
tk.mainloop()
So my question and problem is: Why can I not click on a button more than twice?
This has happened to me before and I could not fix it. Any help would be appreciated.(If you would like to run my program because my explanation was just not good enough here is a git hub repo GitHub)
Thank You
It appears that you are assuming that from RecoveredCases import RunAll will run the code in RecoveredCases.py each time it is imported. That is a false assumption. Python caches code that is imported.
The proper way to use code in a separate file is to put the code in a function or class, import the function or class exactly once, and then call the function or instantiate the class whenever you want to run the code.
Related
I am attempting to write a Python script that captures a screenshot everytime the left mouse button is pressed. I am using this guide as a reference: https://pytutorial.com/python-capture-screenshot-mouse-clicked
My problem is coming from the file path. I am wanting the screenshots to be saved in the "Screenshoots" folder, but am instead getting the error, "OSError: [Errno 22] Invalid argument: 'C:/Users/tjdob/codebase/Screenshoots//26-10-2022_22:12:52.jpg'"
My base directory is C:\Users\tjdob\codebase
Here is the code I am attempting to run:
from pymouse import PyMouseEvent
import pyautogui
import os
class ScreenshotsTaker(PyMouseEvent):
def __init__(self, path):
self.path = path # path to save Screenshot
PyMouseEvent.__init__(self)
def click(self, x, y, button, press):
# if button number 1
if button == 1:
# if button number 1 is pressed (clicked)
if press:
# Take ScreenShot
myScreenshot = pyautogui.screenshot()
# Save ScreenShot file
now = datetime.now()
# Date Time Now
dt_string = now.strftime("%d-%m-%Y_%H:%M:%S")
# Save ScreenShot
myScreenshot.save(os.path.join(self.path,dt_string + ".jpg"))
# Output:
print("ScreenShot is taken")
C = ScreenshotsTaker(path="C:/Users/tjdob/codebase/Screenshoots//")
C.run()
I am sure it is a simple fix. Any direction would be appreciated
I have tried changing the filepath, and switching backslashes with forward slashe.
The problem is with the filename you're creating using strftime():
26-10-2022_22:12:52.jpg
Windows filenames can't have a : in them, because : in a file path is the separator between a drive letter (e.g. C:) and a path. There is an exception to this to use a : as part of a feature called Alternative Data Streams, but that's not what you're trying to do here.
Because it's not a valid filepath, you get the Invalid argument error.
You'll have to format the timestamp portion of the filename differently - possible alternative format options are:
%H-%M-%S -> 22-12-52
%H.%M-%S -> 22.12.52
%H%M%S -> 221252
I wrote a py file called simplifier. Usually when you double click the py file, Windows should give you both a console and the program. Just like the picture below.
However, I clicked my py file and the console showed up and disappeared in a flash and the program did not show up at all. Usually this means there should be some bugs in my code. So I opened the py file in IDLE and ran it, expecting the shell to give me an error. However, it did not report anything. I don't know how to locate the error. The file used to work well and it just started to behave like that. I tested putting "input('')" only in a py file and it worked as expected. And some of my programs also work well, but the rest doesn't.
Could the bug come from my imported modules? I import some module written by myself (ez and eztk). I checked those functions. They are ok.
Here is the code of simplifier.
from tkinter import *
from tkinter import messagebox
from eztk import *
import ez
root=Tk()
root['bg']='MintCream'
t1=Text(root)
def newline():
t=gettxt(t1)
new=''
for i,ch in enumerate(t):
if ch=='\n' and t[i+1:i+3]!='- ':
new+=' '
else:
new+=ch
inst2(new)
w0=Label(root,text='Input:↑')
w1=Button(root,text="\\n",command=newline)
def brackets():
t=gettxt(t1)
new=''
stop=0
d={'[':']','(':')','{':'}',0:None}
for ch in t:
if ch in d:
stop=ch
elif ch==d[stop]:
stop=0
elif not stop:
new+=ch
inst2(new)
w2=Button(root,text='([{}])',command=brackets)
def linecount(event):
count=lambda t:t.count('\n')+(t[-1]!='\n') if t else 0
up=count(gettxt(t1))
down=count(gettxt(t2))
w3['text']=f'LineCount:↑{up}↓{down}'
root.bind('<KeyPress>', linecount)
w3=Label(root,text='LineCount')
def clear():
deltxt(t1)
deltxt(t2)
w4=Button(root,text='Clear',command=clear)
t2=Text(root)
ws=[w0,w1,w2,w3,w4]
t1.grid(row=0,column=0,columnspan=len(ws))
for i,w in enumerate(ws):
w.configure(relief=FLAT,bg='SeaGreen1')
w.grid(row=1,column=i,sticky=NS)
t2.grid(row=2,column=0,columnspan=len(ws))
def inst2(text):
deltxt(t2)
instxt(t2,text)
linecount('<KeyPress>')
try: ez.cpc(text)
except UnicodeError: messagebox.showerror('Error','You need to copy it to your clipboard manually.')
root.mainloop()
These are the functions used in the imported modules:
def copyToClipboard(text):
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
## abbreviation
cpc=copyToClipboard
def gettxt(text):
return text.get(1.0,'end').strip()
def deltxt(text):
text.delete(1.0,'end')
def instxt(textwidget,text):
textwidget.insert(1.0,text)
--- Update ---
I just tried copy the 4 functions to the simplifier.py instead of importing them, it worked. However, I also tried importing either of them and both cases failed. And there is still no error after I ran them in the python shell. Actually the bottom 3 functions are the only code in my eztk module. And it still doesn't work as expected when I import eztk alone, which means there shouldn't be any problems with importing.
I tried to set up a highscore tracker for an app by using a JSON file and the json storage language in Kivy.
I imported JSONstore and in my main game class I did
class Game(FloatLayout):
highscorejson = JsonStore('highscore.json')
highscore = NumericProperty(highscorejson.get('highscore')['best'])
and after I init the class, I have an end game function that ends the game and checks to see if the new score beats the old highscore.
def end_game(self):
if self.score > self.highscore:
self.highscorejson.put('highscore', best = self.score)
self.highscore = self.highscorejson.get('highscore')['best']
This runs perfectly when I run it through Kivy, but when I run it through XCode using my iphone as a test device, it crashes when you score above the highscore and the game ends. The error message is as below.
File "/usr/local/lib/python2.7/site-packages/kivy/storage/__init__.py", line 174, in put
File "/usr/local/lib/python2.7/site-packages/kivy/storage/jsonstore.py", line 39, in store_sync
IOError: [Errno 1] Operation not permitted: 'highscore.json'
2014-06-24 21:59:34.385 cookie[2320:60b] Application quit abnormally!
2014-06-24 21:59:34.457 cookie[2320:60b] Leaving
Full Error:
http://pastebin.com/Zy0DtysW
I was stuck on this problem too. So, finally, I was able to solve this problem. The next code helped me a lot.
from os.path import join
class MyApp(App):
def build(self):
data_dir = getattr(self, 'user_data_dir')
store = JsonStore(join(data_dir, 'storage_file.json'))
As I understand, user_data_dir stores an unique for each app and OS path, where current app's code is stored.
You're probably trying to save the file in an invalid location. Try including a full path to the file you want to write out - you can use kivy_home_dir to help with this.
from kivy import kivy_home_dir
from os.path import join
highscore = JsonStore(join(kivy_home_dir, 'highscore.json'))
I have a working Python+Tkinter program working which is a dictionary creator. However, when I convert soucecode into app, program itself doesn't create the file it is supposed to create. I am quite new to programming, and I would appreciate if you could help me. So far I have tried py2app and platypus both give the same result.
Here is the code:
#!/usr/bin/env python
from Tkinter import *
import tkMessageBox
import itertools
import string
def done():
l=list()
if check_a.get() == True:
l.append(string.lowercase)
if check_A.get() == True:
l.append(string.uppercase)
if check_0.get() == True:
l.append(string.digits)
l=''.join(l)
n=entryvar.get()
with open("b.txt","a+") as f:
for i in itertools.product(l,repeat=n):
f.write(''.join(list(i)))
f.write('\n')
f.close()
generater=Tk()
generater.title("Generater")
generater.geometry("450x300+200+200")
mainlabel=Label(generater).pack()
entryvar=IntVar()
entry=Entry(generater, textvariable=entryvar).pack()
check_a=BooleanVar()
check_A=BooleanVar()
check_0=BooleanVar()
checkBox_a=Checkbutton(generater, variable=check_a, text="a-z").pack()
checkBox_A=Checkbutton(generater, variable=check_A, text="A-Z").pack()
checkBox_0=Checkbutton(generater, variable=check_0, text="0-9").pack()
DoneButton=Button(generater, text="Done", command=done).pack()
generater.mainloop()
When you start an application created by py2app the current working directory is changed to the 'Contents/Resources' folder inside the application bundle. Because your script creates a file relative to the current working directory it ends up inside the application.
(For examples a myapp.app/Contents/Resources/b.txt)
what I am trying to do is change the desktop wallpaper in windows.
To do that, I use the following code:
import ctypes
import Image
pathToBmp = "PATH TO BMP FILE"
SPI_SETDESKWALLPAPER = 20
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, pathToBmp , 0)
this works when I run the .py file, this works when I convert it using py2exe and run the exe under the current user, but when I run the exe as SYSTEM, the current user background does not change.
This ofcourse was to be expected. But I don't know how to solve it.
By the way, it does not matter if any of your solutions changes the current user background or all the users' backgrounds.
Thank you for your time.
How about creating a value key in the registry at:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
This will change the background when ever the user login.
To try it, write this script, name it for example SetDesktopBackground.py, any where you like:
#!python
from ctypes import *
from os import path
SPI_SETDESKWALLPAPER = 0x14
SPIF_UPDATEINIFILE = 0x1
lpszImage = path.join(path.dirname(path.realpath(__file__)), 'your_image.jpg')
SystemParametersInfo = windll.user32.SystemParametersInfoA
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, lpszImage, SPIF_UPDATEINIFILE)
Dont forgot to put some image, your_image.jpg, in the same directory. Then open the registery editor:
Start > Search > type regedit.exe
Then go to the path:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Right click and choose New > String Value and type any name you like for this value.
Right click on this new value and choose Modify, in the Data Value field write:
"C:\Python26\pythonw.exe" "C:\Path\To\SetDesktopBackground.py"
To test it, logout and login again. The background should change when ever this user login.
That was the manual way to do it, you can use _winreg in your application to create the value during the installation:
#!python
from _winreg import *
from sys import executable
from os import path
subkey = 'Software\\Microsoft\\Windows\\CurrentVersion\\Run'
script = 'C:\\Path\\To\\SetDesktopBackground.py'
pythonw = path.join(path.dirname(executable), 'pythonw.exe')
hKey = OpenKey(HKEY_CURRENT_USER, subkey, 0, KEY_SET_VALUE)
SetValueEx(hKey, 'MyApp', 0, REG_SZ, '"{0}" "{1}"'.format(pythonw, script))
CloseKey(hKey)