PDA

View Full Version : Where's the Widget Window?



qtoptus
23rd March 2013, 22:23
I'm using Qt 5.0 which I compiled for VS2008.

When I use this inside the constructor of an object derived from QWidget or even inside the paint event it returns NULL

QWindow *window = windowHandle();

Where's the window? When is it created?

Added after 1 42 minutes:

Ok I just found in the documentation this function is in progress...but they don't provide any work around...so

amleto
23rd March 2013, 22:45
so unless we know what you are trying to do, we can't suggest any work around, can we?

ChrisW67
23rd March 2013, 22:50
That function does not create or display anything: it returns a handle to a related object.

If you are after the native window handle for an API call then you probably want winId(). I do not expect that winId() returns a valid handle until after the QWidget is shown, i.e. not in the constructor, and not unles the widget is a top level widget.

qtoptus
23rd March 2013, 23:04
I'm creating an OpenGL QWidget, and I need the QWindow object so that I can setFormat of the window, using the new Qt5 OpenGL classes.

windowHandle() is supposed to return the QWindow object associated with the widget. I don't understand where's the problem it's incomplete.

wysota
24th March 2013, 00:07
Use QGLWidget::context() and QGLContext::setFormat().

ChrisW67
24th March 2013, 00:14
The docs do not say the function is not working, just that the platform abstraction code underlying the QWindow is a work in progress and subject to change. Given that a QWindow represents the underlying OS window it seems very unlikely that such an object exists before the top level QWidget is displayed, i.e. not available in the constructor. Have you looked after the widget is on screen?

Have you looked at the use of QWindow in the OpenGL Window Example?

qtoptus
24th March 2013, 00:46
I think I'm not making myself clear. First I'm not going and will never use to anything other than the new Qt5 QOpenGLxxxxx classes.

I already mentioned the windowHandle() still returns NULL inside the paint event, and yes the windows is already displayed.


Have you looked at the use of QWindow in the OpenGL Window Example?

Yes but I'm using a widget that I can embed anywhere on the forms using the designer, so using a Window control is of no help.

wysota
24th March 2013, 00:51
First I'm not going and will never use to anything other than the new Qt5 QOpenGLxxxxx classes.
You already are. QGLWidget doesn't use this API. It uses a wrapper of those classes backward compatible with Qt4. If you wish to use Qt5 OpenGL API then use QWindow and QOpenGLContext. You don't need anything else. There is no point in using QWidget (instead of QGLWidget) and QOpenGLContext. This way you end up rewriting QGLWidget.

qtoptus
24th March 2013, 01:06
This way you end up rewriting QGLWidget.

But this is the only way I can create a designer plugin widget.

wysota
24th March 2013, 01:08
You can use QGLWidget.

qtoptus
24th March 2013, 01:20
Well my advice is to the team, work on this issue, fix it, and then release please.

wysota
24th March 2013, 01:34
Well my advice is to the team, work on this issue, fix it, and then release please.

What issue? There is no "issue" here.


/*!
\preliminary

Returns the QPlatformWindow this widget will be drawn into.
*/
QWindow *QWidget::windowHandle() const
{
Q_D(const QWidget);
QTLWExtra *extra = d->maybeTopData();
if (extra)
return extra->window;

return 0;
}

I don't see any "issue" here.

qtoptus
24th March 2013, 05:26
The "issue" is that function does not work!

ChrisW67
24th March 2013, 07:39
Now, where would I have gotten the idea that the function works...


#include <QApplication>
#include <QWidget>
#include <QWindow>
#include <QTimer>
#include <QDebug>

class Widget: public QWidget
{
Q_OBJECT
public:
Widget(QWidget *p = 0): QWidget(p) {
qDebug() << "Start constructor" << windowHandle();
setWindowTitle("A Cool Title"); // this triggers OS window creation
qDebug() << "End constructor" << windowHandle();
QTimer::singleShot(0, this, SLOT(report()));
}

public slots:
void report() {
qDebug() << "After show()" << windowHandle();
if (windowHandle())
qDebug() << "QWindow::title()" << windowHandle()->title();
}

protected:
void paintEvent(QPaintEvent *event) {
qDebug() << "In paintEvent()" << windowHandle();
QWidget::paintEvent(event);
}

};

int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget w;
w.show();
return app.exec();
}
#include "main.moc"

On Linux


Start constructor QObject(0x0)
End constructor QWidgetWindow(0xe902d0, name = "WidgetClassWindow")
After show() QWidgetWindow(0xe902d0, name = "WidgetClassWindow")
QWindow::title() "A Cool Title"
In paintEvent() QWidgetWindow(0xe902d0, name = "WidgetClassWindow")
In paintEvent() QWidgetWindow(0xe902d0, name = "WidgetClassWindow")

On Windows 7 using Qt 5.0.1 MingW build:


Z:\uu>qmake -v
QMake version 3.0
Using Qt version 5.0.1 in C:\Qt\Qt5.0.1\5.0.1\mingw47_32\lib

Start constructor QObject(0x0)
End constructor QWidgetWindow(0xa1ec28, name = "WidgetClassWindow")
After show() QWidgetWindow(0xa1ec28, name = "WidgetClassWindow")
QWindow::title() "A Cool Title"
In paintEvent() QWidgetWindow(0xa1ec28, name = "WidgetClassWindow")
In paintEvent() QWidgetWindow(0xa1ec28, name = "WidgetClassWindow")

wysota
24th March 2013, 10:35
The "issue" is that function does not work!

For me it doesn't really matter if it "works" or not. What you are trying to do is plain wrong. Instead of using a given API that works, you are trying to sort of "reimplement" it in a way that most probably will start breaking everything else you have. If you start changing QWindow instance your widget draws on then you may break all other widgets working on the same QWindow that expect completely different settings than what you are trying to apply. QWidget uses a raster paint engine and expects a raster based window, QGLWidget uses an OpenGL paint engine and is probably somehow rigged in Qt5 to work with a raster QWindow. If you simply put OpenGL code in a raster QWindow then most probably it will simply not work, if you start modifying things behind Qt's back to "fix" it (e.g. by changing the window to be gl-based), then most probably all other things will stop working.

You claim you need to do it because of some Designer plugin that supposedly "doesn't work" so maybe you should focus on making it work instead of working around Qt's architecture. I don't think there are any problems in making a designer plugin that is based on QGLWidget so if it doesn't work for you then most probably you somehow goofed it.

qtoptus
24th March 2013, 21:29
If you start changing QWindow instance your widget draws on then you may break all other widgets working on the same QWindow that expect completely different settings than what you are trying to apply.

I did this successfully in Qt 4.8 with a custom widget that supports Direct3D rendering. So I don't think this is a hack to customize widgets, this is the heart of OOP. Besides they would not expose the QWindow object through windowHandle() if it should not be modified.


You claim you need to do it because of some Designer plugin that supposedly "doesn't work" so maybe you should focus on making it work instead of working around Qt's architecture.

The Designer does not allow creation of custom QWindow controls, they have to be widgets. And I'm not going to use the QGLWidget since it's lacking the capabilities of the new QOpenGL classes, such as profiles, recent version of OpenGL, ...etc.

Now regardless of what I'm trying to do or why this or that way....any idea why windowHandle() returns 0 for a widget?

ChrisW67
24th March 2013, 23:12
any idea why windowHandle() returns 0 for a widget?
It doesn't.

wysota
24th March 2013, 23:54
I did this successfully in Qt 4.8 with a custom widget that supports Direct3D rendering.
4.8 doesn't use QPA.


And I'm not going to use the QGLWidget since it's lacking the capabilities of the new QOpenGL classes, such as profiles, recent version of OpenGL, ...etc.
They are not lacking anything. QGLFormat can set OpenGL version up to 4.3 (which is currently the latest OpenGL version available) and can set the same profiles as the other API. As I said before QGL* classes are wrappers over QOpenGL* classes to provide backward compatibility and allow easy use of OpenGL widgets.


any idea why windowHandle() returns 0 for a widget?
It doesn't.

qtoptus
25th March 2013, 04:15
It doesn't.

It does.

If you know don't know, there's no need to be goat headed and throw farts in attempt to show others we are making things up and Qt is just perfect.

BTW don't bother replying to this, I'm not going to open this forum anymore, so...bye!

ChrisW67
25th March 2013, 07:24
You have been provided evidence to demonstrate that the function does, indeed, return real values. All that was required was a counter example that showed under what conditions zero was returned. Too hard I guess. Good luck with your future programming efforts.

d_stranz
25th March 2013, 20:55
All that was required was a counter example that showed under what conditions zero was returned.

After reading this thread, it amazes me how persistent some people are at insisting that their coding errors are someone else's bugs, even when you are kind enough to take the time to write code and run it on two different platforms to demonstrate that the assertion being made is incorrect.