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()














From:
Anonymous( )Anonymous This account has disabled anonymous posting.
OpenID( )OpenID You can comment on this post while signed in with an account from many other sites, once you have confirmed your email address. Sign in using OpenID.
User
Account name:
Password:
If you don't have an account you can create one now.
Subject:
HTML doesn't work in the subject.

Message:

 
Notice: This account is set to log the IP addresses of everyone who comments.
Links will be displayed as unclickable URLs to help prevent spam.

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:40 am
Powered by Dreamwidth Studios