2013-10-08 6 views
2

Я пытаюсь создать интерфейс с помощью пользовательских виджетов и столкнулся с следующей проблемой.Как добавить виджеты динамически после создания родителя

У меня есть виджет Rectangle, который я хочу использовать в качестве интерактивного элемента в моем интерфейсе. Чтобы определить прямоугольник, мне просто нужно предоставить ему родительский элемент, поэтому он знает, в какое окно влезть, и положение [x,y, width, height], определяющее его положение и размер. (Я знаю, что некоторые из вас скажут: «Вы должны использовать макеты, а не абсолютное позиционирование», но я на 100% уверен, что мне нужно абсолютное позиционирование для этого конкретного приложения).

from PySide.QtCore import * 
from PySide.QtGui import * 
import sys 

class Rectangle(QWidget): 

    def __init__(self, parent, *args): 
     super(self.__class__,self).__init__(parent) 

     print parent, args 
     #expect args[0] is a list in the form [x,y,width,height] 
     self.setGeometry(*args[0]) 

    def enterEvent(self, e): 
     print 'Enter' 

    def leaveEvent(self, e): 
     print 'Leave' 

    def paintEvent(self, e): 

     print 'Painted: ',self.pos 
     painter = QPainter(self) 
     painter.setPen(Qt.NoPen) 
     painter.setBrush(QColor(200,100,100)) 
     painter.drawRect(0,0,self.width()-1, self.height()-1) 
     painter.end() 

У меня также есть Window виджет, который является полотно, на котором моя визуализация должна быть нарисована. В определении Window__init__() я создаю прямоугольник A в 20,40.

class Window(QWidget): 

    def __init__(self): 
     super(self.__class__, self).__init__() 


     self.widgets = [Rectangle(self,[20,40,100,80])] 
     self.setMouseTracking(True) 
     self.setGeometry(300,300,800,600) 
     self.setWindowTitle('Window') 
     self.show() 

    def addWidget(self,Widget, *args): 
     self.widgets += [Widget(self, *args)] 
     self.update() 

    def mousePressEvent(self, e): 
     for widget in self.widgets: 
      print widget.geometry() 

Поскольку я строю визуализации, я хочу создать Window, а затем добавить виджеты к нему послесловие, поэтому я создаю экземпляр mWindow, который должен уже иметь прямоугольнику определен. Затем я использую метод addWidget() моего окна, чтобы добавить второй прямоугольник в 200 200 - назовите его прямоугольником B.

if __name__ == "__main__": 
    app= QApplication(sys.argv) 

    mWindow = Window() 
    mWindow.addWidget(Rectangle, [200,200,200,80]) 
    sys.exit(app.exec_()) 

Проблема у меня есть, что только прямоугольник A фактически получает нарисованный.

Я знаю, что оба прямоугольника А и ** прямоугольник B становятся инстанцирован и оба имеют myWindow как их родительских виджетов, из-за выхода print parent в конструкторе Rectangle.

Однако при изменении размера окна, чтобы заставить его перерисовать себя, метод paintEvent() вызывается только на прямоугольнику, не прямоугольник B. Что мне не хватает?

ответ

2

Вы просто забыли показать прямоугольник. В addWidget, добавьте это перед self.update():

self.widgets[-1].show() 

Причина, почему вам не нужно show для первого объекта прямоугольника, потому что это создается в конструкторе окна. Тогда, сам Qt уверен, что объекты правильно отображаются (что вводит в заблуждение, я согласен ...).

+0

Ах, это исправлено. Чтобы понять это более подробно, как '.show()' вызывает виджеты при создании их внутри конструктора родительского виджета? Если я создаю третий прямоугольник после вызова 'self.show()' в моем родительском виджетах, он не появится, поэтому мне кажется, что когда вы вызываете '.show()' на родителя, он вызывается на ребенка. Однако, если я ставлю 'self.show()' вызов в 'addWidget()' вместо 'self.widgets [-1] .show()' ничего не происходит. – AnjoMan

Смежные вопросы