Цикл над виджетами в PyQt Layout - PullRequest
8 голосов
/ 01 марта 2011

Мой вопрос несколько связан с Получить виджеты макета в PyQT , но это не дубликат. Вместо того, чтобы искать стратегическое представление о том, как это сделать, я пытаюсь понять, каким будет самый идиоматичный и простой способ сделать это. Поскольку PyQt является довольно точной привязкой API Qt C ++, он представляет собой простой способ получить виджеты в макете. Вот такая идиома, которую я использовал:

for i in range(layout.count()):
  item = layout.itemAt(i)
  if type(item) == QtGui.QLayoutItem:
    doSomeStuff(item.layout())
  if type(item) == QtGui.QWidgetItem:
doSomething(item.widget())

Я не самый опытный парень из Python, но это выглядит несколько не в духе. Моя интуиция подсказывает мне, что в идеальном мире код Python должен выглядеть примерно так:

for w in layout.widgets():
  doSomething(w)

Я не прав? Я скучаю по превосходной идиоме? Это лучший способ перебирать виджеты в PyQt? Я склонен думать в C ++, поэтому я иногда упускаю «очевидные» возможности языка Python, которые делают вещи лучше. Часть того, что я делаю, - это рекурсивный переход в виджеты с макетами с виджетами с макетами (и т. Д.) Для автоматического подключения к пользовательскому интерфейсу, созданному в Designer во время выполнения. Добавьте в QTabWidgets обработку динамических свойств, установленных в конструкторе, и мой код в основном работает, но он кажется ужасно неуклюжим.

Ответы [ 4 ]

14 голосов
/ 23 марта 2013

Это очень поздний ответ, но я подумал, что он может быть полезен для будущего возражения.Я тоже искал ответ на этот вопрос.Но я хотел определить типы виджетов, чтобы справиться с ними соответствующим образом.Вот пример кода того, что я нашел:

for widget in centralwidget.children():
    if isinstance(widget, QLineEdit):
        print "linedit: %s  - %s" %(widget.objectName(),widget.text())

    if isinstance(widget, QCheckBox):
        print "checkBox: %s  - %s" %(widget.objectName(),widget.checkState())

Надеюсь, это когда-нибудь пригодится кому-нибудь.:)

6 голосов
/ 04 марта 2011

Вы можете поместить виджеты в генератор следующим образом:

items = (layout.itemAt(i) for i in range(layout.count())) 
for w in items:
   doSomething(w)

Если вы в конечном итоге используете это много, вы можете вставить этот код в функцию генератора:

def layout_widgets(layout):
   return (layout.itemAt(i) for i in range(layout.count()))


for w in layout_widgets(layout):
   doSomething(w)
5 голосов
/ 22 ноября 2014

Просто комментарий,

items = (layout.itemAt(i) for i in range(layout.count())) 
for w in items:
   doSomething(w)

Я попробовал первый ответ, но обнаружил, что он возвращает тип WidgetItem, поэтому на самом деле я сделал ревизию:

widgets = (layout.itemAt(i).widget() for i in range(layout.count())) 
for widget in widgets:
   if isinstance(widget, QLineEdit):
        print "linedit: %s  - %s" %(widget.objectName(), widget.text())
   if isinstance(widget, QCheckBox):
        print "checkBox: %s  - %s" %(widget.objectName(), widget.checkState())
0 голосов
/ 04 марта 2011

Полагаю, у вас уже есть простейшее решение этой проблемы. PyQt (и PySide) - это всего лишь обертки вокруг C ++ API. Они добавляют больше поддержки Pythonic в нескольких областях - сигналы / слоты, базовые типы, такие как QString и т. Д., Но по большей части все остается точно так же, как в C ++ API.

Конечно, это не должно мешать вам создавать свою собственную более питонскую библиотеку ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...