2011-08-29 43 views
1

我在qt設計器中創建了一個小部件,並使用pyuic將ui文件轉換爲名爲Ui_wid_canvas的python類。這應該作爲特殊的帆布:PyQt Child Widget沒有收到paintEvent

# file mgcanvas.py 
from PyQt4 import QtCore, QtGui 

class Ui_wid_canvas(object): 
    def setupUi(self, wid_canvas): 
     wid_canvas.setObjectName("wid_canvas") 
     wid_canvas.resize(400, 300) 
     self.horizontalLayout = QtGui.QHBoxLayout(wid_canvas) 
     self.horizontalLayout.setObjectName("horizontalLayout") 
     self.pushButton = QtGui.QPushButton(wid_canvas) 
     self.pushButton.setObjectName("pushButton") 
     self.horizontalLayout.addWidget(self.pushButton) 

     self.retranslateUi(wid_canvas) 
     QtCore.QMetaObject.connectSlotsByName(wid_canvas) 

    def retranslateUi(self, wid_canvas): 
     wid_canvas.setWindowTitle(QtGui.QApplication.translate("wid_canvas", "Form", None, QtGui.QApplication.UnicodeUTF8)) 
     self.pushButton.setText(QtGui.QApplication.translate("wid_canvas", "PushButton", None, QtGui.QApplication.UnicodeUTF8)) 

從Ui_wid_canvas我派生類MyCanvas來實現的paintEvent功能和一些實用功能,如哞()。在paintevent中,它所要做的就是畫出兩條直言。如果我將以下課程用作我的應用程序,那麼所有的東西都像魅力一樣。

# file mycanvas.py 
from PyQt4 import QtCore, QtGui 
import mgcanvas 


class MyCanvas(mgcanvas.Ui_wid_canvas, QtGui.QWidget): 
    def __init__(self): 
     super(mgcanvas.Ui_wid_canvas, self).__init__() 
     self.setupUi(self) 

    def paintEvent(self, qpaintevent): 
     print "PaintEvent canvas" 
     painter = QtGui.QPainter(self) 
     painter.setBrush(QtGui.QColor(255,0,0,80)) 
     painter.setPen(QtGui.QColor(00,00,00,255)) 

     painter.drawRect(10,10,100,100) 
     r = QtCore.QRectF(110,110,100,100) 
     painter.drawRect(r) 
     painter.drawText(r,"Hello", QtGui.QTextOption(QtCore.Qt.AlignCenter)) 



    def moo(self): 
     print "This is canvas mooing" 

現在,當我創建一個應用程序的測試實例MyCanvas(見下文),用於測試的paintEvent被調用,但MyCanvcas的的paintEvent不會被調用時,rects未按並沒有輸出「的paintEvent帆布」在控制檯上。如果我在Test.paintevent()中調用self.widget.update()self.widget.redraw(),paintevent不會被捕獲。如果我手動調用self.widget.paintevent(),則調用該功能,但畫家未激活。另一方面,按鈕顯示出來,我認爲小部件是正確包含的,但不是繪製事件被子小部件調用。

# file test.py; executed with `python test.py` 
    from PyQt4 import QtCore, QtGui 
    import mycanvas 

    class Test(object): 
     def setupUi(self, Gui): 
      self.counter = 0 
      Gui.setObjectName("TestObject") 
      Gui.resize(500,500) 
      self.layout = QtGui.QVBoxLayout() 
      self.widget = mycanvas.MyCanvas() 
      self.widget.setupUi(self) 
      self.widget.setObjectName("wid_canvas") 
      self.layout.addWidget(self.widget) 

      self.retranslateUi(Gui) 
      QtCore.QMetaObject.connectSlotsByName(Gui) 

     def retranslateUi(self, Gui): 
      Gui.setWindowTitle(QtGui.QApplication.translate("TestObject", "Title", None, QtGui.QApplication.UnicodeUTF8)) 


     def paintEvent(self, qpaintevent): 
      print "---> Enter" 
      self.counter += 1 
      print "counter", self.counter 
      self.widget.repaint() 
      self.widget.moo() 
      print "<-- Leave" 

    class MyTest(Test, QtGui.QWidget): 
     def __init__(self): 
      super(Test, self).__init__() 
      self.setupUi(self) 

    if __name__ == '__main__': 
     import sys 
     app = QtGui.QApplication(sys.argv) 
     ui = MyTest() 
     ui.show() 

     sys.exit(app.exec_()) 

設置Qt.WA_PaintOutsidePaintEvent是不是一種選擇,因爲它不會在Mac和Windows的工作,但我想留下來與平臺無關。

請原諒我張貼這麼多的代碼,但我想這會讓事情變得更容易。我儘量保持最低限度。有人能告訴我如何讓自己的Widget MyCanvas繪畫本身,​​並將此繪畫部件包含在另一個部件MyTest中,它將作爲應用程序工作嗎?

+0

「MyCanvas」類的代碼在哪裏? – alexisdm

+0

對不起,粘貼錯誤的代碼。固定。 – cledith

回答

1

在你的類測試,你沒有佈局連接到參數Gui,通過將其作爲參數傳遞給QVBoxLayout,你叫self.widget.setupUiMyCanvas雖然它已經被MyCanvas構造函數調用。

class Test(object): 
    def setupUi(self, Gui): 
     self.counter = 0 
     Gui.setObjectName("TestObject") 
     Gui.resize(500,500) 
     self.layout = QtGui.QVBoxLayout(Gui) 
     self.widget = mycanvas.MyCanvas() 
     self.widget.setObjectName("wid_canvas") 
     self.layout.addWidget(self.widget) 

     self.retranslateUi(Gui) 
     QtCore.QMetaObject.connectSlotsByName(Gui) 
+0

是的,謝謝。那樣做了! – cledith