Всплывающее предупреждение, если каталог содержит файл перед его выбором [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

Пожалуйста, обратите внимание, что этот скрипт просто проверяет наличие файла в данном каталоге, если каталог содержит какие-либо подкаталоги, этот скрипт не будет их проверять. Это то, что вы можете попробовать самостоятельно.;)

Другие вопросы по тегам