Qt基础类04-浮点直线类QLineF
- 摘要
- 基本信息
- 成员函数
- 程序全貌
- qreal QLineF::angle() const
- qreal QLineF::angleTo(const QLineF &line) const
- [static] QLineF QLineF::fromPolar(qreal length, qreal angle)
- QLineF::IntersectType QLineF::intersect(const QLineF &&line, QPointF *intersectionPoint) const
- qreal QLineF::length() const
- QLineF QLineF::normalVector() const
- QPointF QLineF::pointAt(qreal t) const
- QLine QLineF::toLine() const
- QLineF QLineF::unitVector() const
- 技巧
- 写在后面
- 系列博文
摘要
1.本文测试验证了QT5中的QLineF浮点直线类的各成员函数和属性
2.本文适用于学习QT的新手入门及练习,老手请绕路。
3.工程上传至CSDN,供同一时期学习QT的网友参考,可自行查看。
4.转载请注明出处
基本信息
时间:2024.09.11
QT版本:5.14.2
平台:window 10
程序简介:
-
本工程是Qt基础类和基本数据类型专题例程,QLineF浮点直线类
-
本工程对照着Qt的帮助文档,把每个属性和成员函数测试了一遍
成员函数
程序全貌
这个练习程序,是对照着QT中QLine的帮助文档,一个一个测试形成的。
与QLine直线类相同的成员函数、比较简单的成员函数,看一眼上去知道怎么用,没有进行测试,只针对仅在QLineF类中包含的成员函数进行了测试。
可流化的2个函数没有进行测试。
本文链接地址 Qt基础类04-浮点直线类QLineF ,转载请注明出处。
QLineF浮点直线类与QLine直线类,有一些函数的功能是一样的,只是QLine是整形的,而QLineF是浮点类型的。但也有一些重要的区别,比如,QLineF提供了如Angle()求与x正半轴的夹角,AngleTo()求两直线的夹角,intersect()求两直线交点等等。详见下文。
本测试程序全貌如下图:
qreal QLineF::angle() const
作用:获取某直线与X轴正半周的夹角
void DrawAngle::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline_right(600,250,700,250);
QLineF qline_up(600,250,600,150);
QLineF qline_left(600,250,500,250);
QLineF qline_down(600,250,600,350);
painter.setPen(Qt::red);
painter.drawLine(qline_right);
painter.setPen(Qt::green);
painter.drawLine(qline_up);
painter.setPen(Qt::blue);
painter.drawLine(qline_left);
painter.setPen(Qt::yellow);
painter.drawLine(qline_down);
label1->setText(tr("qline_right的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline_right.x1()).arg(qline_right.y1()).arg(qline_right.x2()).arg(qline_right.y2()));
label2->setText(tr("qline_up的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline_up.x1()).arg(qline_up.y1()).arg(qline_up.x2()).arg(qline_up.y2()));
label3->setText(tr("qline_left的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline_left.x1()).arg(qline_left.y1()).arg(qline_left.x2()).arg(qline_left.y2()));
label4->setText(tr("qline_down的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline_down.x1()).arg(qline_down.y1()).arg(qline_down.x2()).arg(qline_down.y2()));
qreal result1=0.0,result2=0.0,result3=0.0,result4=0.0;
result1=qline_right.angle();
result2=qline_up.angle();
result3=qline_left.angle();
result4=qline_down.angle();
label5->setText(tr("qline_right与x轴正向的夹角是:%1").arg(result1));
label6->setText(tr("qline_up与x轴正向的夹角是:%1").arg(result2));
label7->setText(tr("qline_left与x轴正向的夹角是:%1").arg(result3));
label8->setText(tr("qline_down与x轴正向的夹角是:%1").arg(result4));
}
程序运行效果如下:
qreal QLineF::angleTo(const QLineF &line) const
作用:获取2条直线的夹角
void DrawAngleTo::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline1(650,250,750,250);
QLineF qline2(650,225,650,125);
QLineF qline3(500,250,550,200);
QLineF qline4(450,250,350,250);
painter.setPen(Qt::red);
painter.drawLine(qline1);
painter.setPen(Qt::red);
painter.drawLine(qline2);
painter.setPen(Qt::blue);
painter.drawLine(qline3);
painter.setPen(Qt::blue);
painter.drawLine(qline4);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
label2->setText(tr("qline2的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline2.x1()).arg(qline2.y1()).arg(qline2.x2()).arg(qline2.y2()));
label3->setText(tr("qline3的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline3.x1()).arg(qline3.y1()).arg(qline3.x2()).arg(qline3.y2()));
label4->setText(tr("qline4的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline4.x1()).arg(qline4.y1()).arg(qline4.x2()).arg(qline4.y2()));
qreal result12=0.0;
qreal result34=0.0;
result12=qline1.angleTo(qline2);
result34=qline3.angleTo(qline4);
label5->setText(tr("qline1与qline2的夹角是:%1").arg(result12));
label6->setText(tr("qline3与qline4的夹角是:%1").arg(result34));
}
程序运行效果如下:
[static] QLineF QLineF::fromPolar(qreal length, qreal angle)
作用:获取一条起点为原点,指定长度和与X轴正半轴夹角的一条直线
void DrawFromPolar::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline1(650,250,750,250);
QLineF qline2(650,250,650,150);
painter.setPen(Qt::blue);
painter.drawLine(qline1);
painter.setPen(Qt::blue);
painter.drawLine(qline2);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
label2->setText(tr("qline2的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline2.x1()).arg(qline2.y1()).arg(qline2.x2()).arg(qline2.y2()));
QLineF qlinef_result1;
QLineF qlinef_result2;
qlinef_result1=qline1.fromPolar(600.00,345.0);
qlinef_result2=qline2.fromPolar(600.00,345.0);
painter.setPen(Qt::red);
painter.drawLine(qlinef_result1);
painter.drawLine(qlinef_result2);
label5->setText(tr("qline_result1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qlinef_result1.x1()).arg(qlinef_result1.y1()).arg(qlinef_result1.x2()).arg(qlinef_result1.y2()));
label6->setText(tr("qlinef_result2的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qlinef_result2.x1()).arg(qlinef_result2.y1()).arg(qlinef_result2.x2()).arg(qlinef_result2.y2()));
label7->setText(tr("与原始的线无关,只有长度和角度有关"));
label8->setText(tr("返回的线,起点在原点,不显性直接指定终点,长度和角度来自fromPolar()函数,返回一条直线"));
}
程序运行效果如下:
QLineF::IntersectType QLineF::intersect(const QLineF &&line, QPointF *intersectionPoint) const
作用:获取2条直接的交点,其结果可能是如下3种情况:
-
平行,值为0
-
直线相交,值为1
-
延时线相交,值为2
void DrawIntersect::paintEvent(QPaintEvent *)
{
QPainter painter(this);
//qline1与qline2平行
QLineF qline1(350,250,450,250);
QLineF qline2(350,200,450,200);
//qline3与qline4内相交
QLineF qline3(500,250,600,250);
QLineF qline4(550,200,550,300);
//qline5与qline6外相交
QLineF qline5(650,250,750,250);
QLineF qline6(700,225,700,125);
painter.setPen(Qt::red);
painter.drawLine(qline1);
painter.setPen(Qt::red);
painter.drawLine(qline2);
painter.setPen(Qt::green);
painter.drawLine(qline3);
painter.setPen(Qt::green);
painter.drawLine(qline4);
painter.setPen(Qt::blue);
painter.drawLine(qline5);
painter.setPen(Qt::blue);
painter.drawLine(qline6);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
label2->setText(tr("qline2的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline2.x1()).arg(qline2.y1()).arg(qline2.x2()).arg(qline2.y2()));
label3->setText(tr("qline3的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline3.x1()).arg(qline3.y1()).arg(qline3.x2()).arg(qline3.y2()));
label4->setText(tr("qline4的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline4.x1()).arg(qline4.y1()).arg(qline4.x2()).arg(qline4.y2()));
label5->setText(tr("qline5的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline5.x1()).arg(qline5.y1()).arg(qline5.x2()).arg(qline5.y2()));
label6->setText(tr("qline6的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline6.x1()).arg(qline6.y1()).arg(qline6.x2()).arg(qline6.y2()));
QLineF::IntersectType result1;
QLineF::IntersectType result2;
QLineF::IntersectType result3;
QPointF p1(0,0);
QPointF p2(0,0);
QPointF p3(0,0);
result1=qline1.intersect(qline2,&p1);
result2=qline3.intersect(qline4,&p2);
result3=qline5.intersect(qline6,&p3);
label7->setText(tr("qline1与qline2相交判定结果result1=%1,交点坐标:%2,%3").arg(result1).arg(p1.x()).arg(p1.y()));
label8->setText(tr("qline3与qline4相交判定结果result2=%1,交点坐标:%2,%3").arg(result2).arg(p2.x()).arg(p2.y()));
label9->setText(tr("qline5与qline6相交判定结果result3=%1,交点坐标:%2,%3").arg(result3).arg(p3.x()).arg(p3.y()));
}
程序运行效果如下:
qreal QLineF::length() const
作用:获取某直线的长度
void DrawLength::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline1(450,200,550,200);
QLineF qline2(450,250,600,250);
QLineF qline3(450,300,650,300);
QLineF qline4(450,350,700,350);
painter.setPen(Qt::red);
painter.drawLine(qline1);
painter.setPen(Qt::green);
painter.drawLine(qline2);
painter.setPen(Qt::darkYellow);
painter.drawLine(qline3);
painter.setPen(Qt::blue);
painter.drawLine(qline4);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
label2->setText(tr("qline2的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline2.x1()).arg(qline2.y1()).arg(qline2.x2()).arg(qline2.y2()));
label3->setText(tr("qline3的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline3.x1()).arg(qline3.y1()).arg(qline3.x2()).arg(qline3.y2()));
label4->setText(tr("qline4的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline4.x1()).arg(qline4.y1()).arg(qline4.x2()).arg(qline4.y2()));
qreal l1=qline1.length();
qreal l2=qline2.length();
qreal l3=qline3.length();
qreal l4=qline4.length();
label5->setText(tr("qline1的长度是:%1").arg(l1));
label6->setText(tr("qline2的长度是:%1").arg(l2));
label7->setText(tr("qline3的长度是:%1").arg(l3));
label8->setText(tr("qline4的长度是:%1").arg(l4));
}
程序运行效果如下:
QLineF QLineF::normalVector() const
作用:获取某条直线的垂线。该垂线具有相同的起点和长度
void DrawNormalVector::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline1(650,250,750,250);
painter.setPen(Qt::red);
painter.drawLine(qline1);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
QLineF result_line=qline1.normalVector();
painter.setPen(Qt::blue);
painter.drawLine(result_line);
label5->setText(tr("result_line的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(result_line.x1()).arg(result_line.y1()));
}
程序运行效果如下:
QPointF QLineF::pointAt(qreal t) const
作用:通过参数t获取某条直接的起点、终点,或者是任意比例的某一点。参数t的范围是0~1
void DrawPointAt::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline1(300,250,700,250);
painter.setPen(Qt::red);
painter.drawLine(qline1);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
QPointF p_start(0.0,0.0);
QPointF p_end(0.0,0.0);
QPointF p_any20(0.0,0.0);
QPointF p_any40(0.0,0.0);
QPointF p_any50(0.0,0.0);
QPointF p_any60(0.0,0.0);
QPointF p_any80(0.0,0.0);
qreal t1=0,t2=1,t3=0.2,t4=0.4,t5=0.6,t6=0.8,t7=0.5;
p_start=qline1.pointAt(t1);
p_end=qline1.pointAt(t2);
p_any20=qline1.pointAt(t3);
p_any40=qline1.pointAt(t4);
p_any60=qline1.pointAt(t5);
p_any80=qline1.pointAt(t6);
p_any50=qline1.pointAt(t7);
label2->setText(tr("p_start的坐标是%1,%2").arg(p_start.x()).arg(p_start.y()));
label3->setText(tr("p_end的坐标是%1,%2").arg(p_end.x()).arg(p_end.y()));
label4->setText(tr("p_any20的坐标是%1,%2").arg(p_any20.x()).arg(p_any20.y()));
label5->setText(tr("p_any40的坐标是%1,%2").arg(p_any40.x()).arg(p_any40.y()));
label6->setText(tr("p_any60的坐标是%1,%2").arg(p_any60.x()).arg(p_any60.y()));
label7->setText(tr("p_any80的坐标是%1,%2").arg(p_any80.x()).arg(p_any80.y()));
label8->setText(tr("p_any50的坐标是%1,%2").arg(p_any50.x()).arg(p_any50.y()));
painter.setPen(Qt::blue);
painter.drawLine(p_start.x(),p_start.y(),p_start.x(),p_start.y()-10);
painter.drawLine(p_end.x(),p_end.y(),p_end.x(),p_end.y()-10);
painter.setPen(Qt::darkYellow);
painter.drawLine(p_any20.x(),p_any20.y(),p_any20.x(),p_any20.y()-5);
painter.drawLine(p_any40.x(),p_any40.y(),p_any40.x(),p_any40.y()-5);
painter.drawLine(p_any60.x(),p_any60.y(),p_any60.x(),p_any60.y()-5);
painter.drawLine(p_any80.x(),p_any80.y(),p_any80.x(),p_any80.y()-5);
}
程序运行效果如下:
QLine QLineF::toLine() const
作用:获取某直线的基于整数的副本
void DrawToLine::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline1(300.22,250.22,700.88,250.22);
painter.setPen(Qt::red);
painter.drawLine(qline1);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
QLine qline2=qline1.toLine();
painter.setPen(Qt::blue);
painter.drawLine(qline2);
label2->setText(tr("qline2的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline2.x1()).arg(qline2.y1()).arg(qline2.x2()).arg(qline2.y2()));
}
程序运行效果如下:
QLineF QLineF::unitVector() const
作用:获取某直线线的单位向量,即从这条线的同一点开始的长度为1.0的线
void DrawUnitVector::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QLineF qline1(300.10,250.50,700.10,250.50);
painter.setPen(Qt::red);
painter.drawLine(qline1);
label1->setText(tr("qline1的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(qline1.x1()).arg(qline1.y1()).arg(qline1.x2()).arg(qline1.y2()));
QLineF result_qlinef;
result_qlinef=qline1.unitVector();
painter.setPen(Qt::blue);
painter.drawLine(result_qlinef);
label2->setText(tr("result_qlinef的起点坐标是:%1,%2,终点坐标是:%3,%4").arg(result_qlinef.x1()).arg(result_qlinef.y1()).arg(result_qlinef.x2()).arg(result_qlinef.y2()));
}
程序运行效果如下:
技巧
-
本例程中,写2个同样的connect函数,会弹出2个相同的窗体。注意理解connect函数的逻辑。
-
tr()格式化输出时,如果忘记写%1,程序会运行,但会有如下提示
QString::arg: Argument missing: ???, 90
-
这个例程,使用代码直接写了布局,并且使用了QGroupBox容器嵌入窗体中,并在其中添加了一系列的按钮。这里主要使用了QGroutBox类的setLayout()
-
在布局时,第3个参数和第4个参数,指的是占用几行,或占用几列。这里的2指占用2行的意思。布局专题中,再详细描述。
layout->addWidget(button,0,0,2,1);
写在后面
-
自己独立写了几个测试程序后,对QT感觉熟悉多了。也挺容易上手的。
-
自己尝试比较慢,也容易忽视细节。本例程百度解决的在主窗上添加3个QGroupBox,并实现了自己想要的布局效果。
-
之前胡乱摸索时就发现,在垂直布局时,如果使用QTextEdit和QLabel垂直摆放,QTextEdit总会自动占一半的高度空间,也不知为什么。但今天设置一下QTextEdit的setFixedHeight()就搞定了,我的天,对小白来说,这也算个事儿。
-
QLineF中,关于2直线相关,有一个枚举的定义,解决平行、2直线直接相交,2直线延长线相交的问题。如下:
enum QLineF::IntersectType
序号 | 内容 | 值 | 含义 |
---|---|---|---|
1 | QLineF::NoIntersection | 0 | 平行 |
2 | QLineF::BoundedIntersection | 1 | 相交 |
3 | QLineF::UnboundedIntersection | 2 | 延长线相交 |