2017-10-18 6 views
0

openpyxl을 사용하여 데이터를 수집하고 스프레드 시트에 쓰는 스크립트를 만듭니다. 열려있는 동안 통합 문서를 저장하려고하면 permissionError가 발생하고 문서를 저장하지 않고 클립 보드에서 모든 내용을 제거합니다.PermissionError를 막기위한 Tkinter 창

스크립트를 실행하는 데 시간이 오래 걸리므로 누군가이 스크립트를 사용하는 사람이 통합 문서를 열어두면 두통이 생길 수 있습니다. 이를 방지하기 위해 사용자에게 permissionError 이벤트가 발생할 때까지 Excel 시트를 닫고 열 때까지 열린 상태로 유지할 수 있도록 tkinter 창을 구현하려고합니다.

나는 이것을 조금 복잡하게 만들고 있다고 생각하는데, 이것에 관해서는 이것이 최선의 방법이 아니라는 것을 알고있다. 이 작업을 수행하는 방법에 대한 조언을 주시면 감사하겠습니다.

import openpyxl as op 
import tkinter 

class warning: 
    def __init__(self, root): 
     self.root = root 
     self.root.title('WARNING') 
     self.text = tkinter.Label(root, text = 'Please close spreadsheet, then press "Ok" to proceed.') 
     self.text.grid(row = 1) 
     self.frame = tkinter.Frame(root) 
     self.button = tkinter.Button(self.frame, text = 'Ok', command = tryToSave(book, 'companies.xlsx')).grid(row = 2, column = 0) 
     self.frame.grid(row = 2) 

    def close(self): 
     self.root.destroy() 

def tryToSave(book, name): 
    message = tkinter.Tk() 
    functionality = warning(message) 
    try: 
     book.save(name) 
     functionality.close() 
    except PermissionError: 
     message.mainloop() 
     tryToSave(book, name) 



book = op.load_workbook('C://Users/Alec/envs/RoboEmily/companies.xlsx') 
tryToSave(book, 'C://Users/Alec/envs/RoboEmily/companies.xlsx') 

답변

0

나는 이것을 overthinking했다라고 생각한다. 클래스를 생성하는 것은 과도한 잔인한 것처럼 보입니다. 필자는 원본 코드를 더 간단한 함수로 다시 작성했습니다.

import openpyxl as op 
import tkinter  

def tryToSave(book, name): 
    while 1: 
     try: 
      book.save(name) 
      break 
     except PermissionError: 
      root = tkinter.Tk() 
      message = tkinter.Label(root, text = 'Please close spreadsheet and click "ok"') 
      message.grid(row = 1) 

      ok = tkinter.Button(root, text = 'Ok', command = root.destroy).grid(row = 2) 
      message.mainloop() 

book = op.load_workbook('C://Users/Alec/envs/RoboEmily/companies.xlsx') 
tryToSave(book, 'C://Users/Alec/envs/RoboEmily/companies.xlsx') 

스프레드 시트를 닫 사용자를 지시하는 Tkinter의 윈도우를 생성하고 스프레드 시트가 닫혀 사용자가 '확인'버튼을 클릭 할 때까지 지속됩니다. 시트를 닫기 전에 버튼을 클릭하면 창이 파괴되고 즉시 다시 작성됩니다.

0

그래서 내가 생각할 수있는 유일한 방법은 닫힌 파일이 출력 작업의 내용입니다 여부를 확인하는 "자동" 방법을 가지고 : 나는 지금 그것을 가지고 여기에 코드입니다 관리자가 파일을 열 었는지 여부를 알아보기 위해 파싱을 시도하지만이 방법은 무시 무시하고 비효율적 인 것으로 생각됩니다.

더 좋은 해결책 (주관적으로 말하면)은 tkinter의 Toplevel 위젯을 사용하고 사용자가 처음에 실패한 경우 Toplevel에서 "저장"기능을 다시 실행 시키도록하는 것이 좋습니다. 이것은 저장 버튼으로 윈도우를 생성

from tkinter import * 

class App: 
    def __init__(self, root): 
     self.root = root 

     #Below we declare the "message window" 
     self.top = Toplevel(self.root) #this creates the window 
     self.top.withdraw() #this hides the window 
     self.toplabel = Label(self.top, text="File is already open, please close first") #label for the window 
     self.topsave = Button(self.top, text="Save", command=self.save) #button for the window 

     #packing widgets for the toplevel 
     self.toplabel.pack() 
     self.topsave.pack() 

     self.button = Button(self.root, text="Save", command=self.save) 
     self.button.pack() 

    def save(self): 
     try: 
      with open("file.csv", "w") as f: #we open the file pythonically 
       f.write("Lorem ipsum") #we attempt to write to the file 
       self.top.withdraw() #we attempt to hide the top level window 
     except PermissionError: 
      self.top.deiconify() #if we get a PermissionError exception, we try and unhide the window 

root = Tk() 
App(root) 
root.mainloop() 

:

난 당신이 아래에 볼 수 있습니다 예를 만들었습니다. 이 버튼을 누르면 파일을 열고 저장하려고 시도합니다. 저장이 실패하면 이전에 생성 한 창을 숨기기 해제하고 저장 버튼도 있습니다. 이 저장 버튼을 누르면 동일한 기능 (파일 열기, 저장 시도, 창 숨김 해제)이 실행됩니다. 함수가 다시 실패하면 사용자에 대해 눈에 보이는 변화가 없습니다. 함수가 성공하면 파일이 저장되고 Toplevel 창이 다시 숨겨집니다.