viem77: (9May)
[personal profile] viem77
...ибо время для них настало...
В последнее время я с прыганья по технологиям капитально переполз на устоявшуюся связку Python/PyQt4/Elixir. И, знаете, не жалею. И вот в процессе копания выявляются иногда проблемы, освещенные в сети не полностью, очень примерно или вообще никак. Об решении одной из них я сегодня и напишу.

В частности, есть у меня в одном проекте один такой виджет типа QGroupBox, который регулярно меняет свое содержимое. Ну то есть полностью убивает находящиеся в нем виджеты и делает новые. А в Qt управление расположением виджетов построено, как известно, на Layout'ах. И задать виджету Layout можно только убив предыдущий. А питон с PyQt4 тонкости этого момента несколько умалчивает. Сообщает только, что методом takeAt() можно выдернуть с лэйаута имеющийся там виджет.
Но тут, что у меня, что у граждан в сети, возникает проблема, мы такие гнусные извращенцы, что у нас внутри этого лэйаута могут быть еще лэйауты, а не только виджеты. Звучали, конечно, предложения обратиться к SIP и прибить нужный лэйаут физически. Да есть проблема. Таким вот прибиванием мы выдернем табуретку из-под пикутешной работы с объектами, и он вывалится с сегфолтом.
Тут граждане вспомнили про deferredDelete(), которое как раз эту проблему и решает. Но уперлись в следующую: после него надо дать очереди событий прокрутиться, дабы этот самый деферредделет был выполнен. А то не сможем мы никак назначит лейаут, ибо старый еще физически существует.

Дело кончилось тем, что все найденные в сети рецепты я благополучно переварил, и родил из них один, несколько параноидальный, но зато рекурсивный и заведомо чистящий все, что нам нужно. И очередь событий, не отходя от кассы, при этом дергающий в нужную сторону. Собственно, одна функция чистит, другая удаляет. Проверено - работает.

def deleteLayout(layout):
  clearLayout(layout)
  QCoreApplication.sendPostedEvents(layout, QEvent.DeferredDelete)

def clearLayout(layout):
  while layout.count() > 0:
    item = layout.takeAt(0)
    if isinstance(item.layout(), QLayout):
      clearLayout(item.layout())
      item.layout().deleteLater()
    elif isinstance(item.widget(), QWidget):
      item.widget().deleteLater()
  layout.deleteLater()














Date: 2010-12-02 11:45 am (UTC)
From: [identity profile] quallian-leion.livejournal.com
а что ты на этой связке пишешь?

Date: 2010-12-03 03:33 am (UTC)
From: [identity profile] viem77.livejournal.com
В основном разные десктопные portable приложения.

February 2013

S M T W T F S
     12
3456789
1011121314 1516
17181920212223
2425262728  

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 26th, 2017 12:44 am
Powered by Dreamwidth Studios