7. 绘图和样式表

Qt GUI模块提供了用于窗口系统集成,事件处理,OpenGL和OpenGL ES集成,2D图形,基本图像,字体和文本等类。 其中最重要的类是QGuiApplication和QWindow。Qt应用程序将需要利用这两个类将内容显示在屏幕上。

  • QGuiApplication包含主事件循环,在该循环中,来自窗口系统和其他来源的所有事件都将被处理和调度。它还处理应用程序的初始化和完成。

  • QWindow类表示在底层窗口系统的窗口。它提供了许多虚拟功能来处理来自窗口系统的事件(QEvent),例如触摸输入,曝光,焦点,按键和几何形状更改。

应用程序通常会将QWidget或QQuickView用于其UI,而不是直接使用QWindow。

QWidget类 是所有用户界面对象的基类: 它从窗口系统接收鼠标,键盘和其他事件,并在屏幕上绘制其自身的表示形式。 每个窗口都是矩形的,并且按 Z-order 排序。窗口会被其父窗口及显示在它前面的窗口裁剪。

未嵌入到其他窗口的窗口被称为 window,我们可以理解为独立窗口。通常,window 具有框架和标题栏, 尽管也可以使用适当的窗口标记来创建没有这种修饰的窗口。在Qt中,QMainWindow和QDialog的各种子类是最常见的 window 类型。

Qt的绘画系统可以使用相同的API在屏幕和打印设备上绘画,并且主要基于QPainter,QPaintDevice和QPaintEngine类。 QPainter与QPaintDevice和QPaintEngine类一起构成了Qt绘画系统Arthur的基础。 QPainter用于执行绘制操作,QPaintDevice是可以使用QPainter绘制的二维空间的抽象, 并且QPaintEngine提供了绘制器用来在不同类型的设备上绘制的接口。

QPaintDevice作为一个基类,由QWidget、QImage、QPixmap、QPicture等继承并最终在窗口上绘制UI。

7.1. 2D图形

QPainter提供了高度优化的功能,可以完成大多数图形GUI程序所需的功能。它可以绘制从简单的线条到复杂的形状(如派和弦)的所有内容。 它还可以绘制对齐的文本和像素图。通常,它在逻辑坐标系中绘制,但也可以进行逻辑坐标到物理坐标的转换。 QPainter可以对继承QPaintDevice类的任何对象进行操作。

QPainter的常见用法是在控件的绘画事件中:构造和自定义(例如,设置笔或画笔)Painter,然后进行图形绘制。

7.1.1. 基本概念

在开始使用QPainter之前我们先来了解一些概念。

7.1.1.1. 颜色

Qt中的任何颜色都由支持RGB,HSV和CMYK颜色模型的QColor类表示。 通常使用 QColor RGB(R,G,B) 来指定颜色。 QColor还支持alpha混合轮廓和填充(指定透明效果), 并且该类与平台和设备无关(使用QColormap类将颜色映射到硬件)。

// Specify semi-transparent red
painter.setBrush(QColor(255, 0, 0, 127));
painter.drawRect(0, 0, width()/2, height());

// Specify semi-transparent blue
painter.setBrush(QColor(0, 0, 255, 127));
painter.drawRect(0, 0, width(), height()/2);

预定义的颜色

QColorConstants命名空间中有20个预定义的QColor对象, 包括黑色,白色,原色和辅助色,这些颜色的较暗版本以及三种灰度。

QColor002
brush.setColor(Qt::blue);
pen.setColor(Qt::red);

7.1.1.2. 窗口坐标

我们通常用x轴y轴组成的平面坐标系来限定2D绘图,Qt中坐标系由QPainter类控制。

window001

绘画设备的默认坐标系的原点位于左上角。该X值增加向右和ÿ值向下增加。 在基于像素的设备上,默认单位是一个像素。

逻辑QPainter坐标到物理QPaintDevice坐标的映射由QPainter的变换矩阵,视口和窗口处理所决定。 默认情况下,逻辑坐标系和物理坐标系重合。

7.1.1.3. 窗口和视口

在使用QPainter进行绘制时,我们使用逻辑坐标指定点,然后将其转换为绘画设备的物理坐标。

逻辑坐标到物理坐标的映射由QPainter的world transformation worldTransform()以及QPainter的viewport()和window()处理。 视口表示指定任意矩形的物理坐标。“窗口”在逻辑坐标中描述相同的矩形。 默认情况下,逻辑坐标系和物理坐标系重合,相当于绘制设备的矩形。

使用窗口-视口转换,可以使逻辑坐标系符合您的首选项。该机制还可用于使绘图代码独立于绘图设备。 例如,可以通过调用QPainter::setWindow()函数使逻辑坐标从(-50,-50)扩展到(50,50),其中(0,0)位于中心:

QPainter painter(this);
painter.setWindow(QRect(-50, -50, 100, 100));

现在,逻辑坐标(-50,-50)对应于绘图设备的物理坐标(0,0)。 与绘画设备无关,绘画代码将始终在指定的逻辑坐标上运行。

7.1.2. 绘画和填充

7.1.2.1. QPen

QPen类绘制线条和轮廓。笔由其样式(PenStyle),宽度,画笔,如何绘制端点(PenCapStyle)以及如何绘制两条连接线之间的连接(PenJoinStyle)定义

Qt提供了以Qt :: PenStyle枚举表示的几种内置样式, 可用过setStyle()设置;

PenStyle

QPen001

样式

描述

Qt::NoPen

0

完全没有线。例如,QPainter :: drawRect()填充但不绘制任何边界线

Qt::SolidLine

1

一条简单的线

Qt::DashLine

2

短划线隔开几个像素

Qt::DotLine

3

点分开几个像素

Qt::DashDotLine

4

交替的点和破折号

Qt::DashDotDotLine

5

一个破折号,两个点,一个破折号,两个点

Qt::CustomDashLine

6

使用QPainterPathStroker :: setDashPattern()定义的自定义模式

端点样式定义了如何使用QPainter绘制线的端点。PenCapStyle仅适用于宽线(宽度为1或更大)。 在Qt的:: PenCapStyle枚举提供了以下样式,setCapStyle()设置。

PenCapStyle

QPen002

连接样式定义了如何使用QPainter绘制两条连接线之间的连接。连接样式仅适用于宽线(宽度为1或更大)。 在Qt的:: PenJoinStyle枚举提供了以下样式,setJoinStyle()设置

PenJoinStyle

QPen003

除此以外 setColor() , setWidth() 分别设置颜色和线宽。

7.1.2.2. QBrush

笔刷是QBrush对象,用于填充用笔生成的笔划,即QBrush类定义填充图案。

笔刷具有样式,颜色,渐变和纹理等属性。

QBrush使用setColor()设置笔刷颜色,setStyle()设置笔刷样式,setTexture()设置图片作为笔刷

笔刷样式使用Qt :: BrushStyle枚举定义填充图案,Qt支持的画笔样式如下:

样式

描述

Qt::NoBrush

0

没有画笔图案

Qt::SolidPattern

1

颜色均匀

Qt::Dense1Pattern

2

极其密集的画笔图案

Qt::Dense2Pattern

3

非常密集的画笔图案

Qt::Dense3Pattern

4

有点密集的画笔图案

Qt::Dense4Pattern

5

半密实的画笔图案

Qt::Dense5Pattern

6

有点稀疏的画笔图案

Qt::Dense6Pattern

7

非常稀疏的画笔图案

Qt::Dense7Pattern

8

极稀疏的画笔图案

Qt::HorPattern

9

水平线

Qt::VerPattern

10

垂直线

Qt::CrossPattern

11

跨越水平和垂直线

Qt::BDiagPattern

12

向后的对角线

Qt::FDiagPattern

13

向前的对角线

Qt::DiagCrossPattern

14

交叉对角线

Qt::LinearGradientPattern

15

线性渐变(使用专用的QBrush构造函数设置)

Qt::ConicalGradientPattern

17

锥形渐变(使用专用的QBrush构造函数设置)

Qt::RadialGradientPattern

16

径向渐变(使用专用的QBrush构造函数设置)

Qt::TexturePattern

24

自定义模式(请参阅QBrush :: setTexture())

其效果如下:

QBrush001

7.1.2.3. QGradient

QGradient与QBrush组合使用,可以实现包括从均匀颜色到非常稀疏的图案的基本图案,各种线条组合,渐变填充和纹理等等效果。

Qt提供了三种不同的渐变:QLinearGradient,QConicalGradient和QRadialGradient 这些都继承自QGradient。

QBrush002

7.1.3. 绘图

QPainter001

7.1.3.1. drawPoint

绘制点,函数原型:

void QPainter::drawPoint(const QPointF &position)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//点
painter.setPen(QColor(255,0,0));
painter.setBrush(QColor(255,0,0));
QPolygonF points;
for(int i=0; i<10; i++)
    for(int j=0; j<10; j++)
    {
        painter.drawPoint(QPoint(305+i*10,110+j*10));
        points.append(QPoint(405+i*10,110+j*10));
    }

painter.setPen(QColor(0,0,255));
painter.setBrush(QColor(0,0,255));
painter.drawPoints(points);

7.1.3.2. drawLine

绘制直线,函数原型:

void QPainter::drawLine(const QLineF &line)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
4
5
6
7
8
9
pen.setWidth(5);
pen.setStyle(Qt::SolidLine);
pen.setCapStyle(Qt :: SquareCap);
painter.setPen(pen);
painter.drawLine(QPointF(5, 110), QPointF(195, 110));
pen.setStyle(Qt::DashLine);
pen.setColor(QColor(255, 0, 0));
painter.setPen(pen);
painter.drawLine(QPointF(5, 130), QPointF(195, 130));

7.1.3.3. drawRect

绘制矩形,函数原型:

void QPainter::drawRect(const QRectF &rectangle)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//有填充矩形
pen.setColor(QColor(255, 0, 0));
brush.setStyle(Qt::SolidPattern);
brush.setColor(QColor(0, 255, 0, 125));
painter.setPen(pen);
painter.setBrush(brush);
painter.drawRect(505, 110, 90, 90);

//无填充矩形
pen.setStyle(Qt::SolidLine);
pen.setColor(QColor(255, 0, 0));
brush.setStyle(Qt::NoBrush);
painter.setPen(pen);
painter.setBrush(brush);
painter.drawRect(605, 110, 90, 90);

7.1.3.4. drawRoundedRect

绘制圆角的矩形,函数原型:

void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
QRectF rectangle(705.0, 110.0, 90.0, 90.0);
painter.drawRoundedRect(rectangle, 20.0, 20.0);

7.1.3.5. drawEllipse

绘制圆,函数原型:

void QPainter::drawEllipse(const QRectF &rectangle)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
4
//椭圆
painter.drawEllipse(QRectF(305,220,90,60));
//圆
painter.drawEllipse(QRectF(405,210,90,90));

7.1.3.6. drawArc

绘制弧线,函数原型:

void QPainter::drawArc(const QRectF &rectangle, int startAngle, int spanAngle)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
int startAngle = 30 * 16;//起始角度
int spanAngle = 120 * 16;//跨越度数
painter.drawArc(QRectF(5.0, 210.0, 90.0, 90.0), startAngle, spanAngle);

7.1.3.7. drawPie

绘制扇形,函数原型:

void QPainter::drawPie(const QRectF &rectangle, int startAngle, int spanAngle)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
int startAngle = 30 * 16;//起始角度
int spanAngle = 120 * 16;//跨越度数
painter.drawPie(QRectF(105.0, 210.0, 90.0, 90.0), startAngle, spanAngle);

7.1.3.8. drawChord

绘制带弦的弧,函数原型:

void QPainter::drawChord(const QRectF &rectangle, int startAngle, int spanAngle)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
int startAngle = 30 * 16;//起始角度
int spanAngle = 120 * 16;//跨越度数
painter.drawChord(QRect(205, 210, 90, 90), startAngle, spanAngle);

7.1.3.9. drawPolyline

绘制折线,函数原型:

void QPainter::drawPolyline(const QPointF *points, int pointCount)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
4
5
6
7
8
QPointF Polylinepoints[5] = {
    QPointF(505.0, 210.0),
    QPointF(555.0, 290.0),
    QPointF(535.0, 275.0),
    QPointF(595.0, 295.0),
    QPointF(505.0, 215.0),
};
painter.drawPolyline(Polylinepoints, 5);

7.1.3.10. drawConvexPolygon

绘制多边形,函数原型:

void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule = Qt::OddEvenFill)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
4
5
6
7
QPointF Polygonpoints[4] = {
    QPointF(610.0, 280.0),
    QPointF(620.0, 210.0),
    QPointF(680.0, 230.0),
    QPointF(690.0, 270.0),
};
painter.drawConvexPolygon(Polygonpoints, 4);

7.1.3.11. 渐变

绘制多边形,函数原型:

void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule = Qt::OddEvenFill)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
//线性渐变
QLinearGradient linearGradient(QPointF(40, 190), QPointF(70, 190));
linearGradient.setColorAt(0, Qt::yellow);
linearGradient.setColorAt(0.5, Qt::red);
linearGradient.setColorAt(1, Qt::green);
linearGradient.setSpread(QGradient::RepeatSpread);
painter.setBrush(linearGradient);
painter.drawRect(5, 310, 90, 90);

//辐射渐变
QRadialGradient radialGradient(QPointF(150, 350),40,QPointF(550,40));
radialGradient.setColorAt(0, QColor(255, 255, 100, 150));
radialGradient.setColorAt(1, QColor(0, 0, 0, 50));
painter.setBrush(radialGradient);
painter.drawEllipse(QPointF(150, 350), 40, 40);

//锥形渐变
QConicalGradient conicalGradient(QPointF(250, 350), 100);
conicalGradient.setColorAt(0.2, Qt::cyan);
conicalGradient.setColorAt(0.9, Qt::black);
painter.setBrush(conicalGradient);
painter.drawEllipse(QPointF(250, 350), 40, 40);

7.1.3.12. 文字

绘制文字,函数原型:

void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule = Qt::OddEvenFill)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
//设置一个矩形
QRectF rect(305, 310, 190, 90);
painter.drawRect(rect);
painter.setPen(QColor(Qt::red));
painter.drawText(rect, Qt::AlignHCenter, "野火电子");

//绘制文字
QFont font("宋体", 10, QFont::Bold, true);
font.setLetterSpacing(QFont::AbsoluteSpacing,5);
painter.setFont(font);
painter.drawText(310, 350, "Qt 嵌入式教程");

//绘制文字
painter.setPen(Qt::green);
font.setLetterSpacing(QFont::AbsoluteSpacing,0);
font.setBold(false);
font.setFamily("黑体");
font.setPointSize(10);
font.setItalic(true);
painter.setFont(font);
painter.drawText(310, 380, "显示文字 显示文字");

7.1.3.13. QPainterPath

绘制路径,函数原型:

void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule = Qt::OddEvenFill)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//简单的使用路径
QPainterPath path1;
path1.addEllipse(510, 320, 50, 50);
path1.lineTo(505, 380);
painter.setPen(Qt::blue);
painter.setBrush(Qt::red);
painter.drawPath(path1);

//复制图形
QPainterPath path2;
path2.addPath(path1);
path2.translate(70,0);
painter.drawPath(path2);

QPainterPath path4;
painter.setBrush(Qt::transparent);
path4.lineTo(0,105);
path4.lineTo(this->width(),105);
path4.lineTo(this->width(),205);
path4.lineTo(0,205);
path4.lineTo(0,305);
path4.lineTo(this->width(),305);
path4.lineTo(this->width(),405);
path4.lineTo(0,405);
painter.drawPath(path4);

7.1.3.14. 图片

绘制图片,函数原型:

void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule = Qt::OddEvenFill)
embed_qt_develop_tutorial_code/Graphics/QPainter/mainwindow.cpp
1
2
3
4
5
6
7
8
//简单绘制图片
QPixmap pix;
pix.load(":/image/test.png");
painter.drawPixmap(650, 305, 25, 25, pix);

//缩放
pix = pix.scaled(pix.width()*2, pix.height()*2,Qt::KeepAspectRatio);
painter.drawPixmap(650, 330, pix);

7.2. QSS

在Web开发中,CSS(层叠样式表) 主要用来设计网页的样式,美化网页; 它不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。 CSS能够对网页中元素位置的排版进行像素级精确控制,可以有效地对页面的布局、字体、颜色、背景和其它效果实现更加精确的控制, 拥有对网页对象和模型样式编辑的能力。

在Qt中也引入了类似的概念,可以称之为QSS。

7.2.1. 盒子模型

在使用CSS或QSS时,我们可以视控件为具有四个同心矩形的框:边距矩形,边框矩形,填充矩形和内容矩形。

QSS001
  • Margin(边距) 清除边框外的区域,边距是透明的。

  • Border(边框) 围绕在内边距和内容外的边框。

  • Padding(填充) 清除内容周围的区域,填充也是透明的。

  • Content(内容) 控件的内容,显示文本和图像。

7.2.2. 属性

在使用QSS的时候,我们可以通过特定的属性来控制上述四个盒子的样式,从而使控件呈现出我们想要的效果。

比如说margin,边距

  • margin-top 上边距。

  • margin-right 右边距。

  • margin-bottom 底边距。

  • margin-left 左边距。

我们完全可以通过指定上下左右边距的值来实现下面的效果。

QSS002

再比如常见的 background 属性 用来设置背景,其中又可以细分如下

  • background-color 背景颜色

  • background-image 背景图像

  • background-repeat 背景图像的填充方式

  • background-position 背景图片的对齐方式

  • background-attachment 背景图像是相对于视口滚动还是固定的

  • background-clip background-color和background-image被剪切到的矩形

  • background-origin 背景矩形,与background-position和结合使用

embed_qt_develop_tutorial_code/Graphics/QSS/mainwindow.ui
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
QPushButton {
    color: rgb(206, 246, 223);
    background-color:rgb(18, 210, 100);

    border-radius:20px;padding:10px 40px;

}

QPushButton :pressed{
    color: rgb(206, 246, 223);
    background-color:rgba(18, 216, 105, 5);

    border-radius:20px;padding:10px 40px;
}

例如在示例中,我们对控件设置如上面的样式,其中设置控件的背景颜色(background-color)为rgba(18, 216, 105, 5), 文字颜色(color)为rgb(206, 246, 223),并通过border-radius设置控件显示为圆角。

QSS003

Qt中支持的属性可参考这里,https://doc.qt.io/qt-5/stylesheet-reference.html#list-of-properties

7.2.3. 伪状态

除了样式,QSS还支持伪状态。比如按键常用的几种伪状态:

  • :hover 鼠标移动到控件上

  • :pressed 鼠标按下

  • :checked 鼠标点击

  • :release 鼠标抬起

embed_qt_develop_tutorial_code/Graphics/QSS/mainwindow.ui
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
QToolButton{
    border-image: url(:/resource/image/light/6-social-person.png);
    border-style: flat;
    border-radius:5px;padding:2px 4px;
}
QToolButton:hover{
    border-image: url(:/resource/image/dark/6-social-person.png);
    border-radius:5px;padding:2px 4px;
}
QToolButton:pressed{

    border-image: url(:/resource/image/light/6-social-person.png);
    border-style: flat;
    border-radius:5px;padding:2px 4px;
}
QToolButton:checked{
    border-image: url(:/resource/image/light/6-social-person.png);
    border-radius:5px;padding:2px 4px;
}
QToolButton:release{
    border-image: url(:/resource/image/light/6-social-person.png);
    border-radius:5px;padding:2px 4px;
}

像这样就可以通过QSS来控制按键不同状态显示不同的样式。

Qt中支持的伪状态: https://doc.qt.io/qt-5/stylesheet-reference.html#list-of-pseudo-states

7.2.4. 选择器

Qt中使用样式表和CSS还是有一些差异,特定的控件样式和演示可参考官方文档 https://doc.qt.io/qt-5/stylesheet-examples.html

例程中我们简单的使用QSS模仿360的界面,顺便练习使用Qt Designer布局。

QSS004

7.3. 例程说明

野火提供的Qt Demo已经开源,仓库地址在:

文档所涉及的示例代码也提供下载,仓库地址在:

本章例程在 embed_qt_develop_tutorial_code/Graphics

例程中包含两个示例demo,QtPainter和QSS,QtPainter演示了Qt 2D绘图,QSS则演示了在Qt中使用样式表

7.3.1. 编程思路

QtPainter

  • 新建空白工程

  • Qt绘图事件 void paintEvent(QPaintEvent *event);

  • 在paintEvent()中绘制各种2D图形

QSS

  • 使用Qt Designer 模仿360界面,对控件进行布局

  • 使用QSS控制控件样式,最终达到相近的效果

7.3.2. 代码讲解

绘图和QSS代码在前面都有讲解,这里讲一下如何实现点击窗口任意位置都可拖动窗口。 实现思路如下:

当鼠标按下时,接收鼠标按下事件,记录下鼠标和窗口的初始位置; 按下过程中,移动鼠标会产生鼠标移动事件,根据鼠标和窗口的相对位置,移动窗口; 松开鼠标时,会产生鼠标抬起事件,窗口移动结束。

embed_qt_develop_tutorial_code/Graphics/QSS/mainwindow.h
1
2
3
4
5
6
bool        windowsDrag;
QPoint      mouseStartPoint;
QPoint      windowTopLeftPoint;
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
embed_qt_develop_tutorial_code/Graphics/QSS/mainwindow.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//拖拽操作
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        windowsDrag = true;
        //获得鼠标的初始位置
        mouseStartPoint = event->globalPos();
        //mouseStartPoint = event->pos();
        //获得窗口的初始位置
        windowTopLeftPoint = this->frameGeometry().topLeft();
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if(windowsDrag)
    {
        //获得鼠标移动的距离
        QPoint distance = event->globalPos() - mouseStartPoint;
        //QPoint distance = event->pos() - mouseStartPoint;
        //改变窗口的位置
        this->move(windowTopLeftPoint + distance);
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        windowsDrag = false;
    }
}

7.3.3. 编译构建

build001
  • Ubuntu 选择 Desktop Qt 5.11.3 GCC 64bit 套件,编译运行

  • LubanCat 选择 ebf_lubancat,只编译

提示

当两种构建套件进行切换时,请重新构建项目或清除之前项目。针对我们的工程还需要手动重新构建QtUI和Skin。

build002

7.3.4. 运行结果

7.3.4.1. PC实验

直接点击编译并运行程序,结果如下:

result001

7.3.4.2. LubanCat实验

通过SCP或者NFS将编译好的程序拷贝到LubanCat上

NFS环境搭建 参考这里

SCP命令如下:

# scp传输文件
# scp 文件名 服务器上的某个用户@服务器ip:/文件保存路径
scp filename server_user_name@192.168.0.205:server_file_path
# 从服务器拉取文件
# scp 服务器上的某个用户@服务器ip:/服务器文件存放路径 拉取文件保存路径
scp server_user_name@192.168.0.229:server_file_path local_path

编译好的程序在 embed_qt_develop_tutorial_code/app_bin/graphics 目录中,通过scp命令将编译好的程序拉到LubanCat。

scp root@192.168.0.174:/home/embed_qt_develop_tutorial_code/app_bin/graphics/QSS /usr/local/qt-app/

在LubanCat运行程序,使用run_myapp.sh配置好环境,并执行 QSS 。

sudo /usr/local/qt-app/run_myapp.sh /usr/local/qt-app/QSS

不得不说,Qt在跨平台还是做得挺好的,一套代码,在Window、Ubuntu、嵌入式效果几乎相同。

result002