wxPython. Windows vs. Linux

wxPython. Windows vs. Linux

Хоть мне и нравится библиотека wxPython для создания интерфейса питоновских программ, но есть в ней одна неприятная особенность. Дело в том, что часто поведение одного и того же кода в разных операционках у библотеки отличается. В таких случаях приходится плясать с бубном и что-то подправлять таким образом, чтобы, с одной стороны, поведение программы в одной ОС осталось таким каким же, как оно было задумано и как уже работает, а, с другой стороны, чтобы в других ОС работало точно так же.

Иногда эти шаманства связаны с махинациями сайзерами, а вот вчера я столкнулся с очень неприятным поведением класса wx.Image, от которого не ждал никакого подвоха.

Итак, предыстория. Сижу под Windows, делаю OutWiker (скоро выложу новую версию). Все крупные изменения уже сделаны, под Windows все нормально, пришло время проверить их под Linux. Запускаю VirtualBox с Ubuntu 10.04, запускаю там OutWiker и… все работает. Не веря своему счастью, запускаю юнит-тесты, надеясь, что, раз внешне все нормально, то запуск этих тестов станет простой формальностью.

Запускаю тесты и вижу, что 18 тестов провалились, причем провалились со странным исключением: деление на ноль. Все эти 18 тестов связаны с созданием превьюшек картинок, а деление на ноль произошло в том месте, где рассчитывается коэффициент масштабирования картинок. Деление на ноль там может произойти только в одном случае, если нулевые размеры картинки, которая загружалась с помощью класса wx.Image парой строчек выше. Добавляю вывод отладочной инфы и вижу, что действительно методы GetWidth() и GetHeight() возвращают нули, а метод IsOk() — False, что обозначает, что картинку либо не удалось прочитать, либо она прочитана с ошибками. Более подробную информацию о том, что же на самом деле произошло, взять неоткуда. Самое интересное, что полностью повторив поведение теста через интерфейс OutWiker’а, я не получил никакой ошибки, все работало как надо.

Надо сказать, что тестируемый класс никак не связан с интерфейсом, а wxPython используется там только для работы с картинками, не хотелось мне из-за такой простой операции использовать еще какую-то отдельную библиотеку вроде PIL.

Первой мыслью было, что неправильно задан путь до картинок, но этого быть не могло, потому что в самом начале метода, который создает превьюшку, в явном виде стоит проверка того, что открываемый файл существует, и эта проверка пройдена. Такую проверку пришлось сделать, потому что при попытке открыть с помощью wx.Image несуществующую картинку, wxPython настолько обнаглел, что вместо того, чтобы бросать исключение, выводил пользователю сообщение об этом.

Дальше начались шаманства. Я пробовал передавать в тесте и абсолютные, и относительные пути, проверял размеры файлов с картинками, переносил проект из папки, общей для Linux’а в VirtualBox и Windows, в линуксовую папку. Ничего не менялось.

Следующим уровнем шаманства должен был стать обходной путь, когда картинка читается с помощью wx.Bitmap, а потом уже bitmap передается в конструктор wx.Image. Честно говоря, я не верил в то, что это что-то даст. Делаю, как сказал, запускаю тест и… получаю исключение, что не создан ни один экземпляр класса wx.App. Как я уже говорил, провальные тесты никак не связаны с интерфейсом, который вообще трудно тестировать с помощью юнит-тестов.

Пытаясь понять, что же в этой ситуации можно сделать, решил попробовать первую пришедшую на ум идею — сделаю пустой класс, производный от wx.App и создам его экземпляр, но не буду запускать его MainLoop(). Вдруг этого будет достаточно.

Пишу вот такой класс:

class testApp(wx.App):
    def __init__(self, *args, **kwds):
        wx.App.__init__ (self, *args, **kwds)

Просто создаю его экземпляр в методе setUp() юнит-тестов, и все тесты сразу были пройдены. Под Windows этот код ни на что не повлиял, и тесты также успешно проходятся. Удаляю использование wx.Bitmap и возвращаю старый код сразу с wx.Image. Все работает.

Разработчиков wxPython материл я долго. Ну хорошо, фиг с тем, что под разными операционками один и тот же код ведет себя по-разному, но можно было бы в конструкторе wx.Image бросить исключение, которое бросает wx.Bitmap? Было бы сразу ясно, что ему не нравится и что делать.

Но для себя я понял, что wxPython надо использовать только там, где есть GUI, и теперь подумываю о том, чтобы переделать создание превьюшек с помощью PIL.

А ведь пока прогу я проверил только в Gnome, а есть еще KDE, для которого wxPython свой, как там еще себя поведет программа? Я уж не говорю про Mac OS.

PS. Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.

Пожалуйста, оцените запись

УжасноПлохоТак себеХорошоОтлично (Нет оценок)
Загрузка...

комментария 4

  1. Electriq:

    Похожие проблемы с GTK+ look-n-feel для графической библиотеки Swing (Java). И каждый раз обнаруживаю новые приколы. Среди них:
    — Не рисуются разделители в меню (баг давно известен всем, но где исправление?)
    — Если в JTable в ячейке должна отображаться Image, то в GTK+ происходят сплошные исключения, и окно не отображается целиком (баг тоже давно известен)
    — При некоторых темах оформления GTK (в файлах которых что-то некорректно написано, по всей видимости), попытка открытия внутреннего окна в JDesctopPain приводит к исключению. Вот тут не понял, в чем проблема.
    — Ну и разработчики просто перемудрили. Например, у JDesctopPain добавили нестандартную и недокументированную «панель задач». А я для других L&F сделал давно уже свою, удобную. Так на GTK их выходило две, пока я не перерыл весь Инет и не нашел, как эту штуку отключить.

    В итоге мне это надоело, и я больше не буду использовать GTK+ L&F, вместо него стандартный (убогий) Metal, которые хоть работает 🙂

  2. Jenyay:

    В гноме wxPython тоже использует GTK, интересно сколько у них общих глюков.

  3. Special Force:

    v 4em lu4she programmirovat, podskazhite? I use Boa Constructor.

  4. Jenyay:

    @Special Force

    Это уже кому что нравится. Я все делаю в Vim, до этого использовал SciTe.

Leave a comment

Subscribe without commenting