[PyQt] What am I doing wrong with QWidget?
Phil Thompson
phil at riverbankcomputing.com
Tue Sep 22 23:12:40 BST 2009
On Sat, 19 Sep 2009 23:09:52 +0200, David Boddie <david at boddie.org.uk>
wrote:
> On Sat Sep 19 19:27:06 BST 2009, Kurt Schwarz wrote:
>
>> I'm having problems displaying a widget as a child inside a window. The
>> code below should create a window that is 500 x 500 with a red box
inside
>> 400 x 400.
>>
>> If I replace self.ChildWidget = AppWidget( self ) with self.ChildWidget
=
>> QtGui.QWidget( self ) I get the desired result, what am I doing wrong
>> with
>> AppWidget( ) that would cause it not to display correctly?
>
> I don't think you're doing anything wrong. I quickly rewrote the example
in
> C++ and verified that it works.
>
>
> #include <QtGui>
>
> class AppWidget : public QWidget
> {
> public:
> AppWidget(QWidget *parent = 0) : QWidget(parent) {}
> };
>
> class AppWindow : public QMainWindow
> {
> public:
> AppWindow() : QMainWindow() {
> setGeometry( 30, 30, 500, 500 );
>
> ChildWidget = new AppWidget(this);
> ChildWidget->setGeometry( 10, 10, 400, 400 );
> ChildWidget->setStyleSheet( "background-color: #ff0000" );
> }
>
> private:
> QWidget *ChildWidget;
> };
>
> int main(int argc, char *argv[])
> {
> QApplication app(argc, argv);
> AppWindow MainWindow;
> MainWindow.show( );
> return app.exec( );
> }
>
>
> In your Python version, if you change the base class of AppWidget to
> QFrame,
> it works, so there's definitely something strange happening.
Except that the above isn't equivalent to the Python version...
I think this is a Qt bug...
What's happening is the WA_StyledBackground window attribute isn't being
set. In fact the workaround is to explicitly set it in
AppWidget.__init__()...
self.setAttribute(QtCore.Qt.WA_StyledBackground)
The attribute should be set by QStyleSheetStyle::polish() but that function
includes a test for QWidget and a limited number of QWidget sub-classes
(including QFrame). The problem is that the test for QWidget uses
QWidget's static meta-object. In PyQt that test fails because a new
QMetaObject has been created for AppWidget. The above code works, but only
because it doesn't include Q_OBJECT and hasn't been put through moc.
In Python, changing the super-class of AppWidget to QFrame works because
the test for QWidget sub-classes (like QFrame) is less strict - instead it
uses qobject_cast() which means that QFrame sub-classes (like AppWidget)
also pass the test.
In my view there is no need for the tests in the first place - everything
is a QWidget so just set the attribute unconditionaly. That may have
strange effects on some QWidget sub-classes (I assume the test is there for
a reason) but that is preferable to being prevented from doing things that
would work without a problem.
Phil
More information about the PyQt
mailing list