创建一个QT窗口,左侧是相关天气环境的Checkbox,已经Listview,右侧的mainwindow嵌入osg的osgearth.
简单粗暴上代码,感谢:
https://blog.csdn.net/csu_passer/article/details/79141515?tdsourcetag=s_pctim_aiomsg
https://blog.csdn.net/qq_34719188/article/details/92806907
使用步骤
停靠窗口QDockWidget类使用步骤:
- 创建QDockWidget对象的停靠窗体
- 设置停靠窗体的属性
- 新建一个要插入停靠窗体的控件,eg…QListWidget,QTextEdit
- 将控件插入到QDockWidget中–setWidget()方法
- 使用addDockWidget方法在mainWindow中加入停靠窗体
mainwindow.cpp
#include "mainwindow.h"
#include <QDockWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QCheckBox>
#include <QListView>
#include "OsgContainer.h"
mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent)
{
this->setWindowTitle("test");
OsgContainer* osgViewer = new OsgContainer(this);
this->setCentralWidget(osgViewer);
QDockWidget* qw1 = new QDockWidget("dockwidget1", this);
qw1->setFeatures(QDockWidget::AllDockWidgetFeatures);
qw1->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
QWidget* leftwidget = new QWidget();
QVBoxLayout* vLayout = new QVBoxLayout();
vLayout->setSpacing(6);
vLayout->setContentsMargins(11, 11, 11, 11);
vLayout->setObjectName(QStringLiteral("verticalLayout"));
vLayout->setContentsMargins(0, 0, 0, 0);
QCheckBox* rainCheckBox = new QCheckBox();
rainCheckBox->setObjectName(QStringLiteral("rainCheckBox"));
rainCheckBox->setText(QStringLiteral("rain"));
vLayout->addWidget(rainCheckBox);
QCheckBox*snowCheckBox = new QCheckBox();
snowCheckBox->setObjectName(QStringLiteral("snowCheckBox"));
snowCheckBox->setText(QStringLiteral("snow"));
vLayout->addWidget(snowCheckBox);
QCheckBox*fogCheckBox = new QCheckBox();
fogCheckBox->setObjectName(QStringLiteral("fogCheckBox"));
fogCheckBox->setText(QStringLiteral("fog"));
vLayout->addWidget(fogCheckBox);
QCheckBox* smogCheckBox = new QCheckBox();
smogCheckBox->setObjectName(QStringLiteral("smogCheckBox"));
smogCheckBox->setText(QStringLiteral("smog"));
vLayout->addWidget(smogCheckBox);
QCheckBox* fireCheckBox = new QCheckBox();
fireCheckBox->setObjectName(QStringLiteral("fireCheckBox"));
fireCheckBox->setText(QStringLiteral("fire"));
vLayout->addWidget(fireCheckBox);
QCheckBox* bombCheckBox = new QCheckBox();
bombCheckBox->setObjectName(QStringLiteral("bombCheckBox"));
bombCheckBox->setText(QStringLiteral("bomb"));
vLayout->addWidget(bombCheckBox);
QListView* listView = new QListView();
listView->setObjectName(QStringLiteral("listView"));
listView->setGeometry(QRect(160, 50, 256, 192));
vLayout->addWidget(listView);
leftwidget->setLayout(vLayout);
qw1->setWidget(leftwidget);
this->addDockWidget(Qt::LeftDockWidgetArea, qw1);
}
mainwindow.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_mainwindow.h"
class mainwindow : public QMainWindow
{
Q_OBJECT
public:
mainwindow(QWidget *parent = Q_NULLPTR);
private:
Ui::mainwindowClass ui;
};
OsgContainer.cpp
#include "OsgContainer.h"
#include <QInputEvent>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgGA/MultiTouchTrackballManipulator>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <QApplication>
#include <Windows.h>
#include <typeinfo>
#include <osg/Notify>
#include <osgGA/GUIEventHandler>
#include <osgViewer/Viewer>
#include <osgEarth/Registry>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/Controls>
#include <osgEarthUtil/ExampleResources>
#include <osgEarthSymbology/Color>
OsgContainer::OsgContainer(QWidget *parent)
: QOpenGLWidget(parent) {
init3D();
setMouseTracking(true);
setFocusPolicy(Qt::StrongFocus);
}
OsgContainer::~OsgContainer() {
}
bool OsgContainer::event(QEvent *event) {
switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchEnd:
case QEvent::TouchUpdate: {
QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
unsigned int id = 0;
unsigned int tapCount = touchPoints.size();
osg::ref_ptr<osgGA::GUIEventAdapter> osgEvent(NULL);
osgGA::GUIEventAdapter::TouchPhase phase = osgGA::GUIEventAdapter::TOUCH_UNKNOWN;
foreach(const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
if (!osgEvent) {
if (event->type() == QEvent::TouchBegin) {
phase = osgGA::GUIEventAdapter::TOUCH_BEGAN;
osgEvent = window->getEventQueue()->touchBegan(id, osgGA::GUIEventAdapter::TOUCH_BEGAN, touchPoint.pos().x(), touchPoint.pos().y());
} else if (event->type() == QEvent::TouchEnd) {
phase = osgGA::GUIEventAdapter::TOUCH_ENDED;
osgEvent = window->getEventQueue()->touchEnded(id, osgGA::GUIEventAdapter::TOUCH_ENDED, touchPoint.pos().x(), touchPoint.pos().y(), tapCount);
} else if (event->type() == QEvent::TouchUpdate) {
phase = osgGA::GUIEventAdapter::TOUCH_MOVED;
osgEvent = window->getEventQueue()->touchMoved(id, osgGA::GUIEventAdapter::TOUCH_MOVED, touchPoint.pos().x(), touchPoint.pos().y());
}
} else {
osgEvent->addTouchPoint(id, osgGA::GUIEventAdapter::TOUCH_ENDED, touchPoint.pos().x(), touchPoint.pos().y());
osgEvent->addTouchPoint(id, phase, touchPoint.pos().x(), touchPoint.pos().y());
}
id++;
}
break;
}
default:
break;
}
return QOpenGLWidget::event(event);
}
void OsgContainer::setKeyboardModifiers(QInputEvent *event) {
int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier);
unsigned int mask = 0;
if (modkey & Qt::ShiftModifier) {
mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
}
if (modkey & Qt::ControlModifier) {
mask |= osgGA::GUIEventAdapter::MODKEY_CTRL;
}
if (modkey & Qt::AltModifier) {
mask |= osgGA::GUIEventAdapter::MODKEY_ALT;
}
window->getEventQueue()->getCurrentEventState()->setModKeyMask(mask);
update();
}
void OsgContainer::keyPressEvent(QKeyEvent *event) {
setKeyboardModifiers(event);
window->getEventQueue()->keyPress(event->key());
QOpenGLWidget::keyPressEvent(event);
update();
}
void OsgContainer::keyReleaseEvent(QKeyEvent *event) {
setKeyboardModifiers(event);
window->getEventQueue()->keyRelease(event->key());
QOpenGLWidget::keyReleaseEvent(event);
update();
}
void OsgContainer::mousePressEvent(QMouseEvent *event) {
int button = 0;
switch (event->button()) {
case Qt::LeftButton: button = 1; break;
case Qt::MidButton: button = 2; break;
case Qt::RightButton: button = 3; break;
case Qt::NoButton: button = 0; break;
default: button = 0; break;
}
setKeyboardModifiers(event);
window->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
update();
}
void OsgContainer::mouseReleaseEvent(QMouseEvent *event) {
int button = 0;
switch (event->button()) {
case Qt::LeftButton: button = 1; break;
case Qt::MidButton: button = 2; break;
case Qt::RightButton: button = 3; break;
case Qt::NoButton: button = 0; break;
default: button = 0; break;
}
setKeyboardModifiers(event);
window->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
QOpenGLWidget::mouseReleaseEvent(event);
update();
}
void OsgContainer::mouseDoubleClickEvent(QMouseEvent *event) {
int button = 0;
switch (event->button()) {
case Qt::LeftButton: button = 1; break;
case Qt::MidButton: button = 2; break;
case Qt::RightButton: button = 3; break;
case Qt::NoButton: button = 0; break;
default: button = 0; break;
}
setKeyboardModifiers(event);
window->getEventQueue()->mouseDoubleButtonPress(event->x(), event->y(), button);
QOpenGLWidget::mouseDoubleClickEvent(event);
update();
}
void OsgContainer::mouseMoveEvent(QMouseEvent *event) {
setKeyboardModifiers(event);
window->getEventQueue()->mouseMotion(event->x(), event->y());
QOpenGLWidget::mouseMoveEvent(event);
update();
}
void OsgContainer::wheelEvent(QWheelEvent *event) {
setKeyboardModifiers(event);
window->getEventQueue()->mouseScroll(
event->orientation() == Qt::Vertical ?
(event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) :
(event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT));
QOpenGLWidget::wheelEvent(event);
update();
}
void OsgContainer::resizeEvent(QResizeEvent *event) {
const QSize &size = event->size();
window->resized(x(), y(), size.width(), size.height());
window->getEventQueue()->windowResize(x(), y(), size.width(), size.height());
window->requestRedraw();
// const QSize& oldSize = event->oldSize();
// int oldWidth = oldSize.width();
// int oldHeight = oldSize.height();
// int newWidth = size.width();
// int newHeight = size.height();
// double widthChangeRatio = double(newWidth) / double(oldWidth);
// double heigtChangeRatio = double(newHeight) / double(oldHeight);
// double aspectRatioChange = widthChangeRatio / heigtChangeRatio;
QOpenGLWidget::resizeEvent(event);
}
void OsgContainer::moveEvent(QMoveEvent *event) {
const QPoint &pos = event->pos();
window->resized(pos.x(), pos.y(), width(), height());
window->getEventQueue()->windowResize(pos.x(), pos.y(), width(), height());
QOpenGLWidget::moveEvent(event);
}
void OsgContainer::timerEvent(QTimerEvent *) {
update();
}
void OsgContainer::paintGL() {
if (isVisibleTo(QApplication::activeWindow())) {
frame();
}
}
void OsgContainer::init3D() {
osg::Node* node = osgDB::readNodeFile("D://xxppt_1018_1//xxppt//map//base.earth");
if (!node)
{
return ;
}
osg::Group* root = new osg::Group();
root->addChild(node);
//ControlCanvas* cs = new ControlCanvas();
//root->addChild(cs);
setCamera(createCamera(0, 0, width(), height()));
osg::ref_ptr<osgGA::TrackballManipulator> manipulator = new osgGA::TrackballManipulator;
setCameraManipulator(manipulator);
addEventHandler(new osgViewer::StatsHandler);
addEventHandler(new osgViewer::ThreadingHandler());
addEventHandler(new osgViewer::HelpHandler);
addEventHandler(new osgGA::StateSetManipulator(this->getCamera()->getOrCreateStateSet()));
setThreadingModel(osgViewer::Viewer::SingleThreaded);
root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
root->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
setSceneData(root);
// setRunFrameScheme(ON_DEMAND);
startTimer(10);
}
osg::ref_ptr<osg::Camera> OsgContainer::createCamera(int x, int y, int w, int h) {
window = new osgViewer::GraphicsWindowEmbedded(x, y, w, h);
// osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->windowDecoration = true;
traits->x = x;
traits->y = y;
traits->width = w;
traits->height = h;
traits->doubleBuffer = true;
traits->sharedContext = 0;
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(window);
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera->setProjectionMatrixAsPerspective(
30.0f, double(traits->width) / double(traits->height), 1.0f, 10000.0f);
camera->setClearColor(osg::Vec4(0.3, 0.3, 0.6, 0.1));
return camera.release();
}
OsgContainer.h
#ifndef OSGCONTAINER_H
#define OSGCONTAINER_H
#include <QOpenGLWidget>
#include <osgViewer/Viewer>
class QInputEvent;
class OsgContainer : public QOpenGLWidget, public osgViewer::Viewer {
Q_OBJECT
public:
OsgContainer(QWidget *parent = 0);
~OsgContainer();
bool event(QEvent *event);
void setKeyboardModifiers(QInputEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void resizeEvent(QResizeEvent *event);
void moveEvent(QMoveEvent *event);
void timerEvent(QTimerEvent *);
osgViewer::Viewer *getOSGViewer() {
return this;
}
osg::Group *getRoot() {
return root;
}
protected:
virtual void paintGL();
private:
void init3D();
osg::ref_ptr<osg::Camera> createCamera(int x, int y, int w, int h);
private:
osg::ref_ptr<osg::Group> root;
osgViewer::GraphicsWindow *window;
};
#endif // OSGCONTAINER_H
main.cpp
#include "mainwindow.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
mainwindow w;
w.show();
w.resize(1200,600);
return a.exec();
}
效果图