QT三维图形4

我们先把基本的功能写上:

#include <QGroupBox>
#include "qDoubleSlider.hpp"
#include <qlabel.h>
#include <qgridlayout.h>
class My3DCentralPoint : public QGroupBox {
	Q_OBJECT

public:
	My3DCentralPoint(QWidget * parent = Q_NULLPTR);
	~My3DCentralPoint();

	QDoubleSlider *xSlider4Pos;
	QDoubleSlider *ySlider4Pos;
	QDoubleSlider *zSlider4Pos;
	QLabel *xLabelPos;
	QLabel *yLabelPos;
	QLabel *zLabelPos;

	double xLeft, xRight;
	double yLeft, yRight;
	double zLeft, zRight;
	double xCurrent, yCurrent, zCurrent;

signals:
	void needUpdate(void);

private slots:
	void xBoundaryChanged(double);
	void yBoundaryChanged(double);
	void zBoundaryChanged(double);

	void xPosChanged(double);
	void yPosChanged(double);
	void zPosChanged(double);
};

里面的xLeft这些分别是中心点在各个方向上可以运动的左右边界。

信号是发送给之前的OpenGL类的,用于其更新显示区。

槽里面有自身使用的三个槽:

    void xPosChanged(double);
    void yPosChanged(double);
    void zPosChanged(double);

当该类里面的滑动条运动的时候,要通知我们的类去修改坐标值:

void My3DCentralPoint::xPosChanged(double Value) {
	xCurrent = Value;
	centralRectPos[0] = xCurrent;
	emit needUpdate();
}
void My3DCentralPoint::yPosChanged(double Value) {
	yCurrent = Value;
	centralRectPos[1] = yCurrent;
	emit needUpdate();
}
void My3DCentralPoint::zPosChanged(double Value) {
	emit needUpdate();
	centralRectPos[2] = zCurrent;
	zCurrent = Value;
}

而剩下的三个槽,则比较复杂,我们待会再说。

#include "my3dcentralpoint.hpp"
#include <qopenglwindow.h>
extern GLfloat centralRectPos[3];
extern GLfloat halfBoundaries[3];

My3DCentralPoint::My3DCentralPoint(QWidget * parent) : QGroupBox(parent) {
	setTitle("Central Point Setting");
	QGridLayout *gridlayout = new QGridLayout(this);
	xSlider4Pos = new QDoubleSlider;
	ySlider4Pos = new QDoubleSlider;
	zSlider4Pos = new QDoubleSlider;
	xLabelPos = new QLabel("xPos: ");
	yLabelPos = new QLabel("yPos: ");
	zLabelPos = new QLabel("zPos: ");
	gridlayout->addWidget(xLabelPos, 0, 0);
	gridlayout->addWidget(yLabelPos, 1, 0);
	gridlayout->addWidget(zLabelPos, 2, 0);
	gridlayout->addWidget(xSlider4Pos, 0, 1);
	gridlayout->addWidget(ySlider4Pos, 1, 1);
	gridlayout->addWidget(zSlider4Pos, 2, 1);


	xLeft = halfBoundaries[0] - 0.5;
	xRight =  0.5 - halfBoundaries[0];
	yLeft = halfBoundaries[1] - 0.5;
	yRight = 0.5 - halfBoundaries[1];
	zLeft = halfBoundaries[2] - 0.5;
	zRight = 0.5 - halfBoundaries[2];
	xCurrent = centralRectPos[0];
	yCurrent = centralRectPos[1];
	zCurrent = centralRectPos[2];
	xSlider4Pos->setRange(xLeft, xRight);
	xSlider4Pos->setValue(centralRectPos[0]);
	xSlider4Pos->setRange(yLeft, yRight);
	xSlider4Pos->setValue(centralRectPos[1]);
	xSlider4Pos->setRange(zLeft, zRight);
	xSlider4Pos->setValue(centralRectPos[2]);

	connect(xSlider4Pos, SIGNAL(valueChanged(double)),
		this, SLOT(xPosChanged(double)));
	connect(ySlider4Pos, SIGNAL(valueChanged(double)),
		this, SLOT(yPosChanged(double)));
	connect(zSlider4Pos, SIGNAL(valueChanged(double)),
		this, SLOT(zPosChanged(double)));


}

在构造函数中,我们首先根据初始值来把滑动条的范围给限定好。然后绑定自己的信号和槽。

在DockWidget中,我们再绑定另外三个槽,以及我们这个类中的信号:

connect(my3dhalfboundary->xSlider4HalfBnd, SIGNAL(valueChanged(double)),
		my3dcentralpoint, SLOT(xBoundaryChanged(double)));
	connect(my3dhalfboundary->ySlider4HalfBnd, SIGNAL(valueChanged(double)),
		my3dcentralpoint, SLOT(yBoundaryChanged(double)));
	connect(my3dhalfboundary->zSlider4HalfBnd, SIGNAL(valueChanged(double)),
		my3dcentralpoint, SLOT(zBoundaryChanged(double)));

	connect(my3dcentralpoint, SIGNAL(needUpdate(void)),
		my3dDisplayWidget, SLOT(neededUpdate(void)));

这样相当于边界变化以后,中心点位置类先做调整,把数组更新,然后告诉OpenGL部件需要重新更新一下。

之后再单独拿出来一个轴的槽来讲解:

void My3DCentralPoint::xBoundaryChanged(double Value) {
	if ((xCurrent - Value) < -0.5) {
		xCurrent =  Value - 0.5;
		
	}
	else if ((xCurrent + Value)>0.5) {
		xCurrent = 0.5 - Value;
	}
	centralRectPos[0] = xCurrent;
	halfBoundaries[0] = Value;
	xSlider4Pos->setRange(Value - 0.5, 0.5 - Value);
	emit needUpdate();
}

如果当前中心点位置的值(xCurrent)减去边界值(Value)超过了边界,则我们需要移动中心点,让它往中间移(即令立方体的边贴着大立方体的边)。然后给中心点设置其变化范围。

也就是说,假如我们现在的边界长是0.3了,我们的坐标位置在0.3处,而0.3+0.3是大于0.5的,所以中心点是需要往中间来偏移。

现在各个功能都已经说完了,我们看一下最后的效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dezeming

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值