Всплывающее предупреждение, если каталог содержит файл перед его выбором [Python, traitsui]
Я использую модули Enthought Traitsui и Traits для создания простого графического интерфейса.
Код, который у меня есть, показан ниже. Я ищу способ выдать предупреждение, если "базовый каталог" нового экземпляра Study_info содержит файл с именем "conf.txt", прежде чем выбрать его. Затем я создаю новый экземпляр Study, если каталог study_info.base не содержит файл "conf.txt" или если пользователь соглашается продолжить работу, когда всплывает предупреждение.
В настоящее время я проверяю, существует ли файл в папке после нажатия кнопки "ОК" в окне "Новое учебное окно". Я задавался вопросом, есть ли способ сделать всплывающее предупреждение раньше (сразу после нажатия "Ок" в окне просмотра каталога), чтобы, если пользователь нажимает "Отмена", он / она может непосредственно нажимать "Обзор" снова, чтобы выбрать другую папку (не возвращаясь в окно "Главное окно"). Теперь пользователь должен нажать "Новое исследование", чтобы выбрать другую папку.
from traitsui.api import *
from traits.api import *
import os
class Study_info(HasTraits):
base_directory = Directory(exists=True)
new_study_view = View('base_directory',title="New study window", buttons=['OK','Cancel'],kind='modal')
warning_msg = '\nWarning: Folder already contains configuration file.\n\nProceed ?\n'
warning = View(Item('warning_msg',show_label=False,style='readonly'),title='Warning',kind='modal',buttons = ['OK','Cancel'])
class Study(HasTraits):
def __init__(self, study_info):
self.base_directory = study_info.base_directory
# plus some other processing stuff
view = View(Item('base_directory',style='readonly'))
class study_handler(Handler):
def new_study(self, ui_info):
new_study_info = Study_info()
ns_res = new_study_info.configure_traits(view='new_study_view')
if ns_res and os.path.exists(new_study_info.base_directory):
new_study = Study(new_study_info)
if os.path.exists(os.path.join(new_study.base_directory,'conf.txt')):
warn_res = new_study_info.configure_traits(view='warning')
if warn_res:
ui_info.ui.context["object"].study = new_study
else:
ui_info.ui.context["object"].study = new_study
class GUI(HasTraits):
study = Instance(HasTraits)
new_study = Action(name="New Study",action="new_study")
view = View(Item('study',style='custom',show_label=False),buttons = [new_study], handler = study_handler(),title="Main window",resizable=True)
g = GUI()
g.configure_traits()
Есть идеи? Есть ли способ перезаписать любые проверки, что каталог является каталогом, который существует, чтобы он также проверял, существует ли файл внутри папки? Как связать это, чтобы открыть окно предупреждения?
Спасибо заранее!
2 ответа
В этом коде:
warn_res = new_study_info.configure_traits(view='warning')
if warn_res:
ui_info.ui.context["object"].study = new_study
кажется, что вы предполагаете что-то вроде того, что configure_traits
вернет true, если пользователь нажмет OK и false в противном случае. Это совсем не то, что configure_traits
делает. (Я думаю, что это может быть на самом деле отчасти верно, но возвращаемое значение configure_traits
не указано ни в одной документации, которую я могу найти).
Точнее, configure_traits
создает представление, соответствующее его объекту модели (контекста), и отображает это представление на экране, а затем запускает цикл обработки событий, который перехватывает основной поток (так что управление не возвращается до выхода из диалога).
Чтобы делать то, что вы пытаетесь сделать, вы не должны пытаться полагаться на configure_traits
или его возвращаемое значение для выполнения потока управления. Вместо этого вы должны использовать богатую систему обработки событий. Вот простой пример, предназначенный скорее для иллюстрации обработки событий и конкретных операций обработчика, которые могут быть необходимы для того, что вы хотите сделать, чем для непосредственного решения запрошенной вами задачи (есть несколько отличий, главным образом потому, что я не хотел напишите больше текста и добавьте третий, несколько лишний диалог, как в вашем примере):
class WarningWindow(Handler):
finished=Bool
notify=Event
def init_info(self,info):
self.finished=False
#this is a method defined on the handler that executes when the window closes
#
#is_ok is True if the user closed the window ok and False if the user closed
#the window some other way such as clicking cancel or via the window manager
def closed(self,info,is_ok):
self.finished=is_ok
self.notify=True
view=View(Label('WARNING: YOU WILL BE EATEN BY A GRUE'),buttons=OKCancelButtons)
class StudyMenu(Handler):
warning_window=Instance(WarningWindow)
dir=Directory
make_study_button=Button('Make new study')
info=Instance(UIInfo)
def make_study(self):
print "now make the study"
def _make_study_button_fired(self):
if os.path.exists(os.path.join(self.dir,'conf.txt')):
warning_window.edit_traits() #note, not configure_traits
@on_trait_change('warning_window:notify')
def warning_window_listen(self):
if self.warning_window.finished:
#user is OK to overwrite the conf file
self.make_study()
else:
#user does not want to overwrite
self.info.ui.dispose() #this discards the window
#which is the main window in this example
print "everything is terrible!"
sys.exit(666)
#this is a handler method that executes when the window opens. its primary
#purpose here is to store the window's UIInfo object in the model object.
def init_info(self,info):
self.info=info
StudyMenu().configure_traits()
Если вам нужно проверить, является ли конкретный каталог пустым или нет, вы можете использовать метод os.listdir(). Вот быстрый пример. У меня есть пустая папка с именем как test
в c:\
диск Я могу использовать следующий код, чтобы проверить, если он пуст или нет.
import os
dir='c:\\test'
if not os.listdir(dir):
print "Empty Dir."
Вы можете изменить значение dir
проверить любой другой каталог!
Если вы хотите проверить, содержит ли каталог определенный файл, вы можете использовать следующий код. Он работает так же, как и в предыдущем коде, он сначала проверяет, пустой каталог или нет. Если он не пустой, он получает список всех файлов в нем. Затем он проверяет, есть ли файл с именем, которое вы укажете в скрипте. Например: в моем случае у меня есть файл с именем test.txt
в каталоге c:\test
, Вот полный код:
import os
dir = "C:\\test"
fileName = "test.txt"
if not os.listdir(dir):
print "Empty directory."
else:
filesList = os.listdir(dir)
for i in range(0,len(filesList)):
if filesList[i]=="test.txt":
print "Yes, there is a file with name %s in %s"%(fileName,dir)
else:
pass
Вывод в моем случае был:
Yes, there is a file with name test.txt in C:\test
Пожалуйста, обратите внимание, что этот скрипт просто проверяет наличие файла в данном каталоге, если каталог содержит какие-либо подкаталоги, этот скрипт не будет их проверять. Это то, что вы можете попробовать самостоятельно.;)