Filedialog creating blank lines when opening file explorer - python-3.x

I noticed using filedialog.askdirectory() creates two blank lines when it opens file explorer (see picture below). I've been looking into this for weeks and I can't figure out why this is happening. Is there a way to prevent these blank lines from being created?
#!/usr/bin/python3
import tkinter
from tkinter import filedialog
export_file_path = ""
#Export path for output file
def export_path():
global export_file_path
print("Before askdirectory() is called")
is_empty = filedialog.askdirectory()
print("After askdirectory() is called")
if is_empty != '':
export_file_path = is_empty.replace('/', '\\')
export_path()
print(export_file_path)
input('PAUSE')

Related

Watchdog in Python to look for filesystem changes not working (freezing)

I'm working on a Python script to monitor a folder to check whether a new *.JPG file is added to that folder and then do some tasks. The code is working, but after some time after being started, it seems to be freezing and stops working even a new file is added to the folder.
Here is the code:
# -*- encoding: iso-8859-1 -*-
import time
import os
import flickrapi
import shutil
from PIL import Image
from PIL.ExifTags import TAGS
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
if __name__ == "__main__":
patterns = ["*.jpg"]
ignore_patterns = None
ignore_directories = False
case_sensitive = False
my_event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive)
def get_exif(img):
''' Extract Exif data from image '''
def copyright(img):
# get the path of img and create an output filename
tail = os.path.split(img)[1]
filename = 'wtmk_' + tail[:-3] + 'png'
#open the base image and get it's dimensions
while True:
try:
# read file
base_image = Image.open(img)
bw, bh = base_image.size
bw2 = bw // 2
break
except IOError:
time.sleep(5)
''' Add watermark to image '''
return waterMarkedImage
def on_created(event):
# Add the watermark
file = copyright(event.src_path)
# extract EXIF data
exifdata = get_exif(event.src_path)
''' Send the image to FLICKR '''
# Create and start the observer
my_event_handler.on_created = on_created
path = "c:\\temp"
go_recursively = False
my_observer = Observer()
my_observer.schedule(my_event_handler, path, recursive=go_recursively)
my_observer.start()
try:
while True:
time.sleep(5)
except KeyboardInterrupt:
my_observer.stop()
my_observer.join()
I'm running the above code using Python 3.8 on a Windows 10 machine. Any help would be awesome!
Marcio
It's probably an issue with your cmd.exe
To fix the script freezing open your cmd, click on your cmd icon in the top left, then go to Defaults and uncheck the QuickEdit Mode.
Then restart cmd and start your script. Hope that helps!

Error : Continue "Outside of Loop" in python

#Mark the continue statement. I want to bring the control to the beginning of the if-elif condition. so that if user chooses excel after choosing csv , without closing exiting from the window. The label gets updated accordingly on the "root" window. #
# importing tkinter and tkinter.ttk and all their functions and classes
import tkinter
import tkinter.ttk
import os
import sys
import time
# importing askopenfile function from class filedialog
from tkinter.filedialog import askopenfile
root = tkinter.Tk()
root.geometry('400x200')
root.title("CR7 - GSM BSC - Automation Tool ")
label = tkinter.Label(root, text ="Please Select the CR7 Input file for Generating Scripts").pack#(side="top", pady=10)
# This function will be used to open file in read mode and only excel & csv can be opened
def open_file():
file = askopenfile(mode='r', filetypes=[('CSV Files', '*.csv'),('Excel 2003', '*.xls'),('Excel 2007', '*.xlsx')])
filepathstring = str(file)
if filepathstring.find("xls") > 1 or filepathstring.find("xlsx") > 1 and filepathstring.find("csv") <1 :
label1 = tkinter.Label(root, text="Selected file is 'Excel' File & will be converted to 'CSV' file ").pack(side="top",pady=40)
continue
elif filepathstring.find("xls") < 1 or filepathstring.find("xlsx") < 1 and filepathstring.find("csv") > 1 :
label2 = tkinter.Label(root, text="Selected file is 'csv' File ").pack(side="top", pady=20)
continue
btn = tkinter.Button(root, command=lambda: open_file(), text='Open').pack(side="top", pady=10)
root.mainloop()
If I understand you correctly you want to update the first label. Your issue is that you are packing the widgets before creating the reference variable. The python run time environment first creates the widgets; executes the .pack() method; then assigns the variable the results of the .pack() method which is None. Once you have a working reference you can use the .configure() method to change the text value. I didn't run the code, so if there are any issues pleas leave a comment, so I can correct.
# importing tkinter and tkinter.ttk and all their functions and classes
import tkinter
import tkinter.ttk
import os
import sys
import time
# importing askopenfile function from class filedialog
from tkinter.filedialog import askopenfile
root = tkinter.Tk()
root.geometry('400x200')
root.title("CR7 - GSM BSC - Automation Tool ")
label = tkinter.Label(root, text ="Please Select the CR7 Input file for Generating Scripts")
label.pack(side="top", pady=10) # Packing the label before you create a reference creates a reference to the return value of .pack() method which is None
btn = tkinter.Button(root, command=open_file, text='Open') # you don't need to use lambda unless passing a variable
btn.pack(side="top", pady=10)
# This function will be used to open file in read mode and only excel & csv can be opened
def open_file():
file = askopenfile(mode='r', filetypes=[('CSV Files', '*.csv'),('Excel 2003', '*.xls'),('Excel 2007', '*.xlsx')])
filepathstring = str(file)
if filepathstring.find("xls") > 1 or filepathstring.find("xlsx") > 1 and filepathstring.find("csv") <1 :
label.configure(text="Selected file is 'Excel' File & will be converted to 'CSV' file ")
elif filepathstring.find("xls") < 1 or filepathstring.find("xlsx") < 1 and filepathstring.find("csv") > 1 :
label.configure(text="Selected file is 'csv' File ")
root.mainloop()

How to read a csv file after browsing it in PyQt5 [duplicate]

I have a block of code that opens a QFileDialog using Python3 and PyQt5:
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QFileDialog
import sys
class MCVE(QWidget):
def __init__(self):
super().__init__()
self.initialize()
def initialize(self):
self.setWindowTitle('MCVE')
self.setGeometry(50, 50, 400, 200)
btn = QPushButton('Example', self)
btn.clicked.connect(self.clicked)
self.show()
def clicked(self):
filename = QFileDialog.getOpenFileName(
self, "Open Template", "c:\\",
"Templates (*.xml);;All Files (*.*)")
print(filename)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MCVE()
sys.exit(app.exec_())
In Python 2 using PyQt4 the print(filename) statement, after pressing the cancel button, outputs as an empty string. When I run the same code in Python 3 using PyQt5 I get:
('', '')
NOTE: The quotes are Single Quotes
Can someone explain what is going on? I couldn't find anything under the documentation between PyQt4 and PyQt5. I know that strings changed between Python 2 and Python 3, but I'm not sure those changes would cause an issue like this. Thanks!
The getOpenFileName function in PyQt4 returns a string that is the name of the selected file, and if none is selected then it returns an empty string.
filename = QFileDialog.getOpenFileName(self, "Open Template", "c:\\", "Templates (*.xml);;All Files (*.*)")
However in PyQt5 this returns a tuple of 2 elements where the first one is a string that has the same behavior as in PyQt4, and the second element is the filter used.
filename, filters = QFileDialog.getOpenFileName(self, "Open Template", "c:\\", "Templates (*.xml);;All Files (*.*)")
Note: The majority of documentation of PyQt5 is in Qt5, since in general the names of the methods, the inputs and the result are similar.

Python watchdog module duplicate events (edit: was not an watchdog issue)

I am creating a python script that will identify changes to a log file and print some data from the new logs.
I use watchdog to create an event handler and everything seems to work fine except from that, I get duplicate events every time I modify the file. I checked creation and delete, they both work as expected and trigger one time.
I have read the similar question which explains having a created and a modified event when I save a file but this is not my case. I just get two modification events.
Here is my code:
import os, sys, time
import subprocess
import threading
import win32print
from tkinter import filedialog
from tkinter import *
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class Handler(FileSystemEventHandler):
# docstring for FileSystemEventHandler
def __init__(self, observer, filename, dirname):
# super(Handler, FileSystemEventHandler).__init__(self,)
self.observer = observer
self.filename = filename
self.dirname = dirname
print("Handler filename = " , self.filename)
print("Handler dirname = " , self.dirname)
def on_modified(self, event):
if self.filename == event.src_path:
print("The file was modified")
print (event.src_path)
# go get the last line and print the data
# try:
# hJob = win32print.StartDocPrinter (hPrinter, 1, ("test of raw data", None, "RAW"))
# try:
# win32print.StartPagePrinter (hPrinter)
# win32print.WritePrinter (hPrinter, raw_data)
# win32print.EndPagePrinter (hPrinter)
# finally:
# win32print.EndDocPrinter (hPrinter)
# finally:
# win32print.ClosePrinter (hPrinter)
def on_created(self, event):
print("A file was created (", event.src_path, ")")
def on_deleted(self, event):
print("A file was deleted (", event.src_path, ")")
if __name__ == "__main__":
Flags=2
Name=None
Level=1
printers = win32print.EnumPrinters(Flags, Name, Level)
print("\nChoose a printer to use:")
i=1
for p in printers:
print(i,')' , p[2])
i = i+1
if sys.version_info >= (3,):
raw_data = bytes ("This is a test", "utf-8")
else:
raw_data = "This is a test"
printer = int(input())
printer_name = printers[printer-1][2] #win32print.GetDefaultPrinter ()
print("You chose ", printer_name, "\nI will now print from the specified file with this printer")
hPrinter = win32print.OpenPrinter (printer_name)
# root = Tk()
# root.filename = filedialog.askopenfilename(initialdir = "/Desktop",title = "Select file",filetypes = (("log files","*.log"),("all files","*.*")))
file_path = "some_file_path" # root.filename
file_directory = os.path.dirname(file_path)
# print (file_path)
print (file_directory)
observer = Observer()
event_handler = Handler(observer, file_path, file_directory)
observer.schedule(event_handler, path=file_directory, recursive=False)
observer.start()
observer.join()
any ideas would be appreciated
EDIT:
After some debugging I found out that Windows10 is changing the file modification time twice every time I save it.
The proof of concept code is this:
prev_modification_time = os.path.getmtime(file_path)
while True:
current_mod_time = os.path.getmtime(file_path)
if prev_modification_time != current_mod_time :
print ("the file was modified, last modification time is: ", current_mod_time)
prev_modification_time = current_mod_time
pass
Final edit:
After testing my code on linux (Debian Stretch to be exact) it worked like a charm. So this combined with the previous edit probably shows that watchdog works fine and it is windows10 that has some issue. Should I post it on a different question or here?

How can I save output tho the same file that I have got the data from, in Python 3

I am trying to open a file, remove some characters (defined in dic) and then save it to the same the file.
I can print the output and it looks fine, but I cannot save it into the same file that the original text is being loaded from.
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showerror
import sys
import fileinput
dic = {'/':' ', '{3}':''};
def replace_all(text, dic):
for i, j in dic.items():
text = text.replace(i, j)
return text
class MyFrame(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("Example")
self.master.rowconfigure(5, weight=1)
self.master.columnconfigure(5, weight=1)
self.grid(sticky=W+E+N+S)
self.button = Button(self, text="Browse", command=self.load_file, width=10)
self.button.grid(row=1, column=0, sticky=W)
def load_file(self):
fname = askopenfilename(filetypes=(("Napisy", "*.txt"),
("All files", "*.*") ))
if fname:
try:
with open (fname, 'r+') as myfile: #here
data = myfile.read() #here
data2 = replace_all(data, dic) #here
print(data2) #here
data.write(data2) #and here should it happen
except:
showerror("Open Source File", "Failed to read file\n'%s'" % fname)
return
if __name__ == "__main__":
MyFrame().mainloop()
I have tried several commands but either I am receiving python errors or it is simply not working.
This is often implemented by writing to a temp file and then moving it to the original file's name.
Strings do not have a .write method. The following should work (I tried it): replace
data.write(data2) #and here should it happen
with
myfile.seek(0)
myfile.truncate()
myfile.write(data2)
The truncate() call is needed if data2 is shorter than data as otherwise, the tail end of data will be left in the file.

Resources