2011-08-29 71 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