PDA

View Full Version : DockWidget with Direct3D Widget and expanding problem



NIteLordz
29th December 2014, 15:39
I have the following setup within Qt


class Editor : public QMainWindow {
...
};
Within this Editor class, i create a SceneWidget which is defined as


class EditorSceneWindow : public QDockWidget {
...
};
Within the EditorSceneWindow i have a custom Direct3D widget defined as


class D3DRenderWidget : public QWidget {
...
};

I create an EditorSceneWindow and set it's parent to MainWindow. In EditorSceneWindow, i create a D3DRenderWidget that initializes my engine.

My problem is that when the application starts up, the size of my Direct3DWidget is 100x30 (Toolbar dimensions of the DockWidget. I know i can set the minimum width/height, however, i want the Direct3DWidget to fill the entire DockWidget. I have tried setting numerous different combos of the QSizePolicy for the Direct3DWidget, as it is the child of the SceneWindow DockWidget.

Thanks in advance.

d_stranz
29th December 2014, 18:19
You probably need to put your render widget inside a layout inside the dock widget. If the render widget is the only widget in the dock widget, then either a QVBoxLayout or a QHBoxLayout will do.



class EditorSceneWindow : public QDockWidget {
Q_OBJECT;

EditorSceneWindow( QWidget * parent )
: QDockWidget( parent )
{
QHBoxLayout * layout = new QHBoxLayout( this );
layout->addWidget( new D3DRenderWidget( this ) );
setLayout( layout );
// ....
}
};

anda_skoa
29th December 2014, 18:28
Did you call setWidget() on the dock widget?

Cheers,
_

NIteLordz
29th December 2014, 20:16
So i just created a QVBoxLayout based on the code snippet above, but still got the same results.

EditorSceneWindow file

void EditorSceneWindow::Create(WeakPtr<Engine> engine) {
engine_ = engine;

QVBoxLayout* layout = new QVBoxLayout(this);

d3dRendererWidget_ = new D3DRenderWidget(this, engine_);
layout->addWidget(d3dRendererWidget_);

this->setLayout(layout);
}

D3DRenderWidget file

D3DRenderWidget::D3DRenderWidget(QWidget* parent, Engine* engine) :
QWidget(parent) {

setAttribute(Qt::WA_PaintOnScreen, true);
setAttribute(Qt::WA_NativeWindow, true);

QSizePolicy sizePolicy = this->sizePolicy();
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
}

d_stranz
30th December 2014, 01:25
Did you try calling QDockWidget::setWidget() as anda_skoa suggested?

Does your render widget have an inherent size? Or do you have to set it somewhere? Presumably if you are going to use it to render something with Direct3D, you need to give it a size somewhere. What happens if you call resize( 300, 300 ) (for example) in the render widget constructor?

NIteLordz
30th December 2014, 02:12
Yea, i call QDockWidget::setWidget() and calling resize(300, 300) creates the display, but it does not expand vertically filling the widget. It does fill it in horizontally. I have three dock widgets, all set at the top, and when i close one of the non scene dock window, the scene dock window expands horizontally to fill the area. However, if i close the dock window that is docked on the bottom, the scene window does not fill in that additional area.

Also, if i only use the scene dock window, no other dock windows, it is has the same outcome.

Editor.cpp

void Editor::CreateSceneDockWindow() {
sceneWindow_ = new EditorSceneWindow(context_, "Scene", this);
sceneWindow_->Create(engine_);
addDockWidget(Qt::TopDockWidgetArea, sceneWindow_);
}

EditorSceneWindow.cpp

EditorSceneWindow::EditorSceneWindow(Context* context, QString title, QWidget* parent) :
EditorWindow(context, title, parent),
d3dRendererWidget_(0) {
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

EditorSceneWindow::~EditorSceneWindow() {

}

void EditorSceneWindow::Create(WeakPtr<Engine> engine) {
engine_ = engine;

QWidget* container = new QWidget(this);
container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

QVBoxLayout* layout = new QVBoxLayout(this);
d3dRendererWidget_ = new D3DRenderWidget(this, engine_);
layout->addWidget(d3dRendererWidget_);
container->setLayout(layout);

setWidget(container);
}

D3DRenderWindow.cpp

D3DRenderWidget::D3DRenderWidget(QWidget* parent, Engine* engine) :
QWidget(parent) {

setAttribute(Qt::WA_PaintOnScreen, true);
setAttribute(Qt::WA_NativeWindow, true);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
resize(640, 480);

//
engine_ = engine;

// Set our Direct3D widget as the window to render into
Platform* platform = engine_->GetSubsystem<Platform>();
platform->SetExternalWindow(reinterpret_cast<void*>(this->winId()));

// Configure the engine for Editor functionality
VariantMap engineParameters;
engineParameters["Fullscreen"] = false;

QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(16);
}

D3DRenderWidget::~D3DRenderWidget() {

}

void D3DRenderWidget::paintEvent(QPaintEvent* event) {
if (!engine_) return;

engine_->RunFrame();
}

void D3DRenderWidget::resizeEvent(QResizeEvent* event) {
int widgetWidth = width();
int widgetHeight= height();

using namespace WindowResized;

VariantMap resizeEventMap;
resizeEventMap[P_WIDTH] = width();
resizeEventMap[P_HEIGHT] = height();
engine_->SendEvent(E_WINDOWRESIZED, resizeEventMap);
}

Added after 21 minutes:

Issue Resolved!!!

Found this (http://stackoverflow.com/questions/3531031/qmainwindow-with-only-qdockwidgets-and-no-central-widget) article which states that you have to have a central widget, even if nothing is present in it. you can just hide it. one line of code, and BOOM!

placed this inside Editor.cpp constructore, and now it fills in the area as expected.

ui->centralWidget->hide();

Thanks much for your help!!!

Note, as i am new on these forums, is there reputation points or anything, if so, i would give you a +1, if not, thanks anyways

d_stranz
30th December 2014, 16:55
you have to have a central widget

Strange side effect, but if it works, fine. So it sounds like in effect you are using dock widgets like MDI subwindows? Why not just use MDI instead? Or do you need the docking ability for some reason?


is there reputation points or anything,

Clicking the "Thanks" and six-pointed star buttons do that. We all appreciate it.

NIteLordz
30th December 2014, 20:09
I am using the dock widgets for two reasons, one being i wanted to learn about docking, and two, actually in my application i plan to have a handful of windows, and providing the undock feature seems an interesting fit. I'm the kind of coder who enjoys learning new techniques, and this is definitely one that i am learning a lot about, from concept through implementation.

Thanks again for your help!