如何让 Qt Widget 填充父 Widget?
Posted
技术标签:
【中文标题】如何让 Qt Widget 填充父 Widget?【英文标题】:How to make Qt Widget fill parent Widget? 【发布时间】:2012-01-21 07:15:33 【问题描述】:我是 Qt 编程新手。我想创建一个简单的应用程序,它可以显示 OpenGL 模型并提供一些简单的 UI 控件来操作它。
到目前为止,我已经创建了自己的 GlWidget,它是 QGLWidget 的子类,并使用 Qt Designer 创建了一个简单的表单。在我的主窗体中,我添加了一些 UI 元素和一个空的 QWidget,它定义了我希望 GlWidget 填充的区域(我来自 Java 背景,这是在 Java 中完成的方式)。我还创建了一个 GlWidged 实例并将其添加到这个空小部件中。 GlWidget 甚至可以正确呈现!唯一的问题是它是邮票大小的,我不知道如何让它填满它的整个父小部件。
我该如何解决这个问题?
MainForm.h
#ifndef _MAINFORM_H
#define _MAINFORM_H
#include "ui_MainForm.h"
#include "GlWidget.h"
class MainForm : public QMainWindow
Q_OBJECT
public:
MainForm();
virtual ~MainForm();
private:
Ui::MainForm widget;
GlWidget* glWidget;
;
#endif /* _MAINFORM_H */
MainForm.cpp
#include "MainForm.h"
MainForm::MainForm()
widget.setupUi(this);
glWidget = new GlWidget(widget.widget_gl);
MainForm::~MainForm()
GlWidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <qtimer.h>
#include <Qt/qgl.h>
class GlWidget : QGLWidget
Q_OBJECT
public:
GlWidget(QWidget* parent = 0);
protected:
virtual void initializeGL();
virtual void resizeGL(int width, int height);
virtual void paintGL();
virtual void keyPressEvent(QKeyEvent *e);
virtual void timeOut();
protected slots:
virtual void timeOutSlot();
private:
QTimer *m_timer;
;
#endif /* GLWIDGET_H */
GlWidget.cpp
#include "GlWidget.h"
#include <qapplication.h>
#include <qtimer.h>
#include <qevent.h>
GlWidget::GlWidget(QWidget* parent)
: QGLWidget(parent)
//setLayout();
//showMaximized();
int timerInterval = 1;
if (timerInterval == 0)
m_timer = 0;
else
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(timeOutSlot()));
m_timer->start(timerInterval);
void GlWidget::keyPressEvent(QKeyEvent *e)
switch (e->key())
case Qt::Key_Escape:
close();
void GlWidget::timeOut()
void GlWidget::timeOutSlot()
timeOut();
void GlWidget::initializeGL()
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
void GlWidget::resizeGL(int width, int height)
height = height ? height : 1;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat) width / (GLfloat) height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
void GlWidget::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-1.5f, 0.0f, -6.0f);
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
glTranslatef(3.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();
【问题讨论】:
【参考方案1】:您需要为主窗口设置布局,然后将 QGLWidget 添加到布局中。例如,您的 mainwindow.ui
文件可能如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>478</width>
<height>392</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGLWidget" name="glView"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>478</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QGLWidget</class>
<extends>QWidget</extends>
<header>qglwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
要将QGLWidget
添加到表单,只需将QWidget
添加到表单,然后将其提升为QGLWidget
。有关详细信息,请参阅this question 及其接受的答案。
【讨论】:
【参考方案2】:我不确定你在做什么。您需要做的是创建一个窗口和一个布局。然后将所有 UI 元素,包括 GL 小部件添加到此布局中,最后,执行 window->setLayout(layout)。那么它应该很好地伸展。如果您仍然有问题,请查看 sizeHint 方法以及您选择的布局具有的任何拉伸选项。
【讨论】:
如何在 Qt Designer 中将自定义小部件添加到表单中?据我所知,它只会让你添加标准的 Qt 小部件,如按钮和文本字段以上是关于如何让 Qt Widget 填充父 Widget?的主要内容,如果未能解决你的问题,请参考以下文章
我在QT主控件mainwindow里我加了一个widget控件,我用QPainter只能在mainwindow里画直线,如何画在widget
QT UI 如果发现布局之后,button不在父widget的中间
Qt::WindowFlags枚举类型(对Qt::Widget Qt::Window Qt::Dialog分别讲解,其中Qt::Widget是两用的,如新的窗口部件没有父窗口部件,则它是一个独立的窗口