LINUX.ORG.RU

PyQt4: QtGui.QWidget.(re)setLayout


0

1

Добрый вечер. Вошел тут в состояние ступора, будучи не в силах заставить PyQt при нажатии на кнопку натягивать на виджет другой layout. Кода много, привожу лишь кусок:

self.Main_LeftWidget = QtGui.QWidget()
self.Main_RightWidget = QtGui.QWidget()

self.X_LeftLayout = QtGui.QGridLayout()
self.X_RightLayout = QtGui.QGridLayout()
### здесь код для наполнения layout'ов X

self.Y_LeftLayout = QtGui.QGridLayout()
self.Y_RightLayout = QtGui.QGridLayout()
### здесь код для наполнения layout'ов Y

# далее сигналы двух QAction связываются каждый со своим слотом
def slot_X:
  self.Main_LeftWidget.setLayout(self.X_LeftLayout)
  self.Main_RightWidget.setLayout(self.X_RightLayout)

def slot_Y:
  self.Main_LeftWidget.setLayout(self.Y_LeftLayout)
  self.Main_RightWidget.setLayout(self.Y_RightLayout)

Первое нажатие срабатывает нормально, в дальнейшем выдается ошибка:

Attempting to set QLayout "" on QWidget "", which already has a layout

Как бороться? И можно ли вообще? Спасибо большое!



Последнее исправление: ghostmansd (всего исправлений: 1)

в самом Qt многократный QWidget::setLayout() отрабатывает прекрасно

shty ★★★★★
()
Ответ на: комментарий от shty

Не работает, начиная с

from qt import *
Заменил на:
from PyQt4.QtGui import *
Выдает ошибку:
AttributeError: 'MainWindow' object has no attribute 'setCaption'

Дальше расковыривать лень, да и не совсем это то. Здесь удаляется виджет из шкуры, а мне надо шкуру натянуть на виджет.

ghostmansd
() автор топика
Ответ на: комментарий от shty

В импорте заменил PyQt4 на PySide, итог повеселил:

ImportError: /usr/lib/python2.7/site-packages/PySide/QtCore.so: undefined symbol: _ZNK7QObject17senderSignalIndexEv
Похоже, он когда-то криво встал. :-)

ghostmansd
() автор топика
Ответ на: комментарий от ghostmansd

from PyQt4.QtGui import *

кстати так делать плохо, никогда не импорть звёздочку

не совсем это то

ну, может просто тебе надо не то что ты задумал :) ну да ладно

а если взять и просто два раза подряд, безо всяких кнопок setLayout два раза вызвать с разными layout'ами - тоже отваливается?

shty ★★★★★
()

а, всё просто - маны надо читать, хотя бы когда не работает :)

QWidget.setLayout (self, QLayout)

The QLayout argument has it's ownership transferred to Qt.

Sets the layout manager for this widget to layout.

If there already is a layout manager installed on this widget, QWidget won't let you install another. You must first delete the existing layout manager (returned by layout()) before you can call setLayout() with the new layout.

shty ★★★★★
()
Ответ на: комментарий от shty

Поставил не в слотах, а просто дважды подряд:

self.Main_LeftWidget.setLayout(self.X_LeftLayout)
self.Main_LeftWidget.setLayout(self.Y_LeftLayout)
Ошибка все та же.

Интересно, что при попытке сделать так:

self.Main_LeftWidget.setLayout(self.X_LeftLayout)
self.Main_LeftWidget.setLayout(self.X_LeftLayout)
Никаких ошибок нет. Ну, точнее, интерпретатор о них не говорит. :-)

ghostmansd
() автор топика
Ответ на: комментарий от shty

Не выходило никак; пошел другим путем - в каждый контейнер запихнул виджет, а при нажатии установить ему в качестве родителя None и создать заново. :-)

ghostmansd
() автор топика

Не стоит использовать setLayout для этих целей. Виджету можно присвоить только один лайоут.
Решение проблемы - присваиваем видежету лайоут-контейнер, ссылку на него запоминаем. После этого уже в этот лайоуте добавляем/удаляем основной лайоут. Для лайоута-контейнера рекомендую выполнить
setMargin(0)
setSpacing(0)

trex6 ★★★★★
()
Ответ на: комментарий от trex6

Уже пошел другим путем - создал подклассы QWidget, туда напихал всяких ништяков, при нажатии кнопки выполняю self.setCentralWidget(widget). :-) Но спасибо, учту!

ghostmansd
() автор топика
Ответ на: комментарий от ghostmansd

А еще обнаружил, что лучше всего для этих целей подходит QStackedWidget.

ghostmansd
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.