OSG与QT控件相互响应
响应的来龙去脉
最近自己导入三维模型折腾,基本上导入模型和QT的信号传递,基本上是弄清楚了,举个QT控件控制小车旋转的简单例子吧:
在UI设计师中点开信号与槽的图标
按照惯例我们先选择输入信号Clicked()输出信号为我们自定义的信号Pushbutton_add()作为槽函数响应,这样在ui_osg_qt.h中就会有
QObject::connect(pushButton_add, SIGNAL(clicked()), osg_qtClass, SLOT(PushButton_add()));
PS:这么一行代码自动生成(connect相关的)我们在写自定义的控件connect的时候还是不要这么写,会有坑的,为什么不要这么写后面我再详细点的说。
同样写出与我们控件相关的osg实现代码先:
osg_qt.cpp
///读取文件
osg::ref_ptr<osg::MatrixTransform> floortrans = new osg::MatrixTransform;
osgDB::Options *funa = new osgDB::Options(std::string("noTriStripPolygons"));
car = osgDB::readNodeFile("my_car.STL", funa);
car->setName("mycar");
///角度调整
osg::ref_ptr<osg::MatrixTransform> rotate_node = new osg::MatrixTransform;
rotate_node = control_angle(car);//角度调整节点
///角度调整的实现
osg::ref_ptr<osg::MatrixTransform> osg_qt::control_angle(osg::Node* node)
{
//位置+角度
osg::ref_ptr<osg::MatrixTransform> car_mat = new osg::MatrixTransform;
car_mat->setMatrix(osg::Matrix::translate(0, 0, 0));//这里是小车位置的Node控制
osg::Quat quat(osg::DegreesToRadians(_Zrotate), osg::Z_AXIS);
osg::Matrix rotMatrix(quat);
rotate_car->setMatrix(rotMatrix);
rotate_car->addChild(node);
car_mat->addChild(rotate_car);
return car_mat;
}
旋转节点控制rotate_car的主要是通过四元数控制绕Z轴旋转的所以
osg_qt.h头文件中把角度声明全局
public:
double _Zrotate = 0.0
osg::ref_ptr<osg::MatrixTransform> control_angle(osg::Node* node);
接下来就是槽函数了
osg_qt.h添加
private slots:
void PushButton_add();
osg_qt.cpp中加上
void osg_qt::PushButton_add()
{
_Zrotate += 1;
osg::Quat quat(osg::DegreesToRadians(_Zrotate), osg::Z_AXIS);
osg::Matrix rotMatrix(quat);
rotate_car->setMatrix(rotMatrix);
}
即可将osg与控件相关联
实现大概如下
消息栏的其他相互响应也是差不多的都是QT响应的基础
为什么不要用SIGNAL()和SLOT()
不用SIGNAL()和SLOT()原因很简单我们现在基本上QT都是用的QT5了这个语法还是QT4的假若我们用这个写得对没问题,响应一般都是成功的,但是如果没有写对就很麻烦,所以一般还是用下面这种形式来写connect
(信号发送者,发送的信号,信号接收者,处理函数)
eg:pick_handler为我在CPickHandler类的一个extern指针
connect(pick_handler,&CPickHandler::singnalPicked,this,&osg_qt::showpickData);
写给自己的话
自己继承的时候一定要搞清楚继承的顺序如果要用qt的信号槽机制一定要记得在类里面加上QObeject
eg:
class CPickHandler :public QObject ,public osgGA::GUIEventHandler//一定记得是GUIeventhandeler
{
Q_OBJECT
.....
}
还有在表格控件响应时用了extern
在信号响应中要记得自己的控件为提升类无论是connect还是槽函数
其“指针”一律为类+控件被提升的对象非控件传递信号的则不用直接类的指针就好
pQtab_wideget->tableWidget_postion->...
QT的lineEdit用osg::Vec3d直接强制转化传入可能会有问题建议先格式转化再传入
eg:
float x = pos[0];
QString data_x = QString("%1").arg(x);//断点报错因为传入格式问题
ui.lineEdit_x->setText(data_x);
点选模型时用到了qt的信号与槽函数一定要会书写改掉原来的直接在类里面实现构造函数的习惯
.h的构造函数声明
CPickHandler(osgViewer::Viewer *viewer);
.cpp的构造函数实现
CPickHandler::CPickHandler(osgViewer::Viewer *viewer):mViewer(viewer) {
};
大概就这么多吧
后面几天着重写路径漫游,争取能写出自己满意的实现代码~