QT三维图形3

267 阅读2分钟

我们现在要设计一个滑动条,可以通过滑动来实现立方体位置和边框长度的改变。

因为立方体的长宽都是小数,普通的进度条难以实现,这里我们封装一个double类型的进度条:

`class QDoubleSlider : public QSlider`

然后在里面定义函数:

    `void setRange(double Min, double Max);
void setMinimum(double Min);
double minimum() const;
void setMaximum(double Max);
double maximum() const;
double value() const;`

以及信号和槽:

`public slots:
        void setValue(int value);
public slots:
        void setValue(double Value, bool BlockSignals = false);
signals:
        void valueChanged(double Value);
signals:
        void rangeChanged(double Min, double Max);`

这里面的修改应该是借助过别人的程序,记得是github某个程序上截取出来的,首先表示感谢。因为原代码也没有附带任何版权说明,我也忘了是谁的程序了,如果作者看到了请联系我。

函数:

`QDoubleSlider::QDoubleSlider(QWidget* pParent) :
        QSlider(pParent),
        m_Multiplier(10000.0)
{
        connect(this, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));

        setSingleStep(1);

        setOrientation(Qt::Horizontal);
        setFocusPolicy(Qt::NoFocus);
}

void QDoubleSlider::setValue(int Value)
{

        emit valueChanged((double)Value / m_Multiplier);
}

void QDoubleSlider::setValue(double Value, bool BlockSignals)
{
        QSlider::blockSignals(BlockSignals);

        QSlider::setValue(Value * m_Multiplier);

        if (!BlockSignals)
                emit valueChanged(Value);

        QSlider::blockSignals(false);
}

void QDoubleSlider::setRange(double Min, double Max)
{
        QSlider::setRange(Min * m_Multiplier, Max * m_Multiplier);

        emit rangeChanged(Min, Max);
}

void QDoubleSlider::setMinimum(double Min)
{
        QSlider::setMinimum(Min * m_Multiplier);

        emit rangeChanged(minimum(), maximum());
}

double QDoubleSlider::minimum() const
{
        return QSlider::minimum() / m_Multiplier;
}

void QDoubleSlider::setMaximum(double Max)
{
        QSlider::setMaximum(Max * m_Multiplier);

        emit rangeChanged(minimum(), maximum());
}

double QDoubleSlider::maximum() const
{
        return QSlider::maximum() / m_Multiplier;
}

double QDoubleSlider::value() const
{
        int Value = QSlider::value();
        return (double)Value / m_Multiplier;
}`

使用的话,就跟int类型的QSlider一样就行了,只是它可以设置浮点数量。精度是1/10000。

我们定义两个类,分别调节立方体坐标值和立方体的边长:

`class My3DHalfBoundary : public QGroupBox
class My3DCentralPoint : public QGroupBox`

注意第一个边界也是定义的半边界。

中心点比较麻烦,因为大家设想一下,如果边界变了,中心点的运动范围也得变,但是如果中心点位置变了,边界的范围就不会变。所以我们先设计边界长度类:

`class My3DHalfBoundary : public QGroupBox {
        Q_OBJECT

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

        QDoubleSlider *xSlider4HalfBnd;
        QDoubleSlider *ySlider4HalfBnd;
        QDoubleSlider *zSlider4HalfBnd;
        QLabel *xLabelHalfBnd;
        QLabel *yLabelHalfBnd;
        QLabel *zLabelHalfBnd;

private:

};`

没有设计任何信号的槽。

`#include "my3dhalfboundary.hpp"
#include <qgridlayout.h>
#include <qopenglwindow.h>
extern GLfloat centralRectPos[3];
extern GLfloat halfBoundaries[3];
My3DHalfBoundary::My3DHalfBoundary(QWidget * parent) : QGroupBox(parent) {
        setTitle("Boundary Setting");
        QGridLayout *gridlayout = new QGridLayout(this);
        xSlider4HalfBnd = new QDoubleSlider;
        ySlider4HalfBnd = new QDoubleSlider;
        zSlider4HalfBnd = new QDoubleSlider;
        xLabelHalfBnd = new QLabel("xBound: ");
        yLabelHalfBnd = new QLabel("yBound: ");
        zLabelHalfBnd = new QLabel("zBound: ");
        gridlayout->addWidget(xLabelHalfBnd, 0, 0);
        gridlayout->addWidget(yLabelHalfBnd, 1, 0);
        gridlayout->addWidget(zLabelHalfBnd, 2, 0);
        gridlayout->addWidget(xSlider4HalfBnd, 0, 1);
        gridlayout->addWidget(ySlider4HalfBnd, 1, 1);
        gridlayout->addWidget(zSlider4HalfBnd, 2, 1);


        xSlider4HalfBnd->setRange(0.02, 0.5);
        xSlider4HalfBnd->setValue(halfBoundaries[0]);
        ySlider4HalfBnd->setRange(0.02, 0.5);
        ySlider4HalfBnd->setValue(halfBoundaries[1]);
        zSlider4HalfBnd->setRange(0.02, 0.5);
        zSlider4HalfBnd->setValue(halfBoundaries[2]);

}

My3DHalfBoundary::~My3DHalfBoundary() {

}`

在构造函数中,我们设置边长的变化范围是0.02——0.5,太小了也没有什么意义。

这个类很简单。但是下一节要说的关于中心点的类就有点难了。