这是新开的C++QT开发专栏,接下来将会花费较多的时间进行讲述基于LinuxC++车载显示器开发。

项目要求

此作品将会基于I.MX6ULL MINI Linux开发板进行开发,主要功能将会实现:视频播放器、音频播放器、地图显示、蓝牙聊天、TCP、DUP等的部署开发。

开发环境

基于正点原子I.MX6ULL QT开发手册进行开发,主要软件准备:

  • QT版本:qt-opensource-linux-x64-5.12.9
  • Ubuntu版本:18.4
  • 交叉编译器:fsl-imx-x11-glibc-x86_64-meta-toolchain-qt5-cortexa7hf-neon-toolchain-4.1.15-2.1.0

程序部分

整体界面显示

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
AppMainView::AppMainView(QWidget *parent)
{
this->setParent(parent);
this->setGeometry(0, 0, 800, 480);
this->setMinimumSize(800, 480);

bgWidget = new QWidget(this);
bgWidget->setStyleSheet("border-image: url(:/images/bg.png)");

mySlidePage = new SlidePage(this);
mySlidePage->resize(this->size());

appDemo[0] = new AppDemo();
mySlidePage->addPage(appDemo[0]);
}

AppMainView::~AppMainView()
{
}


void AppMainView::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
mySlidePage->resize(this->size());
bgWidget->resize(this->size());
}

显示的界面如下(源码例程中修改),先把滚动部分的代码去除

原始界面_1786x800

可以滚动,但是不能切换界面,目前只有一个界面

添加新文件夹

这里将会学习到如何在QT项目中,添加.pri文件

首先,在项目的PRO文件中加入

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
34
35
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
main.cpp \
widget.cpp

HEADERS += \
widget.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

include(../slidepage/slidepage.pri)
include(../appdemo/appdemo.pri)
include(../video/video.pri)
RESOURCES += \
resource.qrc

include(../video/video.pri)此为新加入的文件,先使用该文件,进行按键点击跳转的功能。添加完文件路径后,还需要在pri文件中,加入文件的信息:

1
2
3
4
5
6
7
SOURCES += \
../video/video.cpp

HEADERS += \
../video/video.h
RESOURCES += \
../video/res.qrc

该文件中,还添加了一个CSS样式,用来绘画窗口的。

新窗口

上述,我们引入了新的文件——Video,接下来看看,几个文件的函数部分

video.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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include "video.h"
#include <QFile>

Video::Video(QWidget *parent)
: QWidget(parent)
// ui(new ui::Video)
{
this->setGeometry(0, 0, 1030, 600);
this->resize(1030, 600);
this->setMinimumSize(1030, 600);
this->setAttribute(Qt::WA_TranslucentBackground, true);

mainWidget = new QWidget(this);
topWidget = new QWidget();
middleWidget = new QWidget();
bottomWidget = new QWidget();

mid_left_Widget = new QWidget();
mid_right_Widget = new QWidget();

mid_right_top_Widget = new QWidget();
mid_right_bottom_Widget = new QWidget();


for (int i = 0; i < 6; i++) {
mid_pushButton[i] = new QPushButton();
mid_pushButton[i]->setObjectName(tr("mid_pushButton%1").arg(QString::number(i)));
mid_pushButton[i]->setFocusPolicy(Qt::NoFocus);

if (i != 5) {
top_pushButton[i] = new QPushButton();
top_pushButton[i]->setFixedSize(120, 60);
top_pushButton[i]->setObjectName(tr("top_pushButton%1").arg(QString::number(i)));
top_pushButton[i]->setFocusPolicy(Qt::NoFocus);
}
}

for (int i = 0; i < 7; i++) {
bottom_pushButton[i] = new QPushButton();
bottom_pushButton[i]->setFixedSize(60, 60);
bottom_pushButton[i]->setObjectName(tr("bottom_pushButton%1").arg(QString::number(i)));
bottom_pushButton[i]->setFocusPolicy(Qt::NoFocus);
}


mainVLayout = new QVBoxLayout();
topHLayout = new QHBoxLayout();
bottomHLayout = new QHBoxLayout();
middleHLayout = new QHBoxLayout();
mid_left_VLayout = new QVBoxLayout();
mid_right_VLayout = new QVBoxLayout();
mid_right_top_HLayout = new QHBoxLayout();
mid_right_bottom_HLayout = new QHBoxLayout();

/* 主布局 */
mainVLayout->addWidget(topWidget);
mainVLayout->addWidget(middleWidget);
middleWidget->setFixedHeight(305);
mainVLayout->addWidget(bottomWidget);
mainWidget->setLayout(mainVLayout);
mainVLayout->setAlignment(Qt::AlignCenter);
mainVLayout->setContentsMargins(0, 0, 0, 0);

/* 中间布局 */
middleHLayout->addWidget(mid_left_Widget);
middleHLayout->setAlignment(Qt::AlignCenter);
mid_left_Widget->setFixedSize(305, 305);
middleHLayout->addWidget(mid_right_Widget);
middleHLayout->setContentsMargins(5, 0, 0, 0);
middleWidget->setLayout(middleHLayout);
middleWidget->setFixedSize(795, 300);



/* 中间右边布局 */
mid_right_VLayout->addWidget(mid_right_top_Widget);
mid_right_VLayout->addWidget(mid_right_bottom_Widget);
mid_right_VLayout->setContentsMargins(0, 0, 0, 0);
mid_right_Widget->setLayout(mid_right_VLayout);

/* 中间右边顶部布局 */
mid_right_top_HLayout->addWidget(mid_pushButton[1]);
mid_pushButton[1]->setFixedSize(150, 150);
mid_pushButton[1]->setText("Name of song");
mid_right_top_HLayout->addWidget(mid_pushButton[2]);
mid_pushButton[2]->setFixedSize(150, 150);
mid_pushButton[2]->setText("Categories");
mid_right_top_HLayout->addWidget(mid_pushButton[3]);
mid_pushButton[3]->setFixedSize(150, 150);
mid_pushButton[3]->setText("Top List");
mid_right_top_HLayout->setContentsMargins(0, 0, 0, 0);
mid_right_top_Widget->setLayout(mid_right_top_HLayout);

/* 中间右边底部布局 */
mid_right_bottom_HLayout->addWidget(mid_pushButton[4]);
mid_pushButton[4]->setFixedSize(150, 150);
mid_pushButton[4]->setText("New");
mid_right_bottom_HLayout->addWidget(mid_pushButton[5]);
mid_pushButton[5]->setFixedHeight(150);
mid_pushButton[5]->setText("Stars");
mid_right_bottom_HLayout->setContentsMargins(0, 0, 0, 0);
mid_right_bottom_Widget->setLayout(mid_right_bottom_HLayout);

/* 顶部布局 */
for (int i = 0; i < 5; i++) {
if (i == 4) {
QSpacerItem *hSpacer0 = new QSpacerItem(150, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
topHLayout->addSpacerItem(hSpacer0);
}
topHLayout->addWidget(top_pushButton[i]);
topHLayout->setAlignment(Qt::AlignTop | Qt::AlignHCenter | Qt::AlignLeft);
topHLayout->setContentsMargins(0, 0, 0, 20);
}
topHLayout->setSpacing(20);
top_pushButton[1]->setText("Select songs");
top_pushButton[2]->setText("Interation");
top_pushButton[3]->setText("More ");
top_pushButton[4]->setText("Back ");
topWidget->setFixedHeight(80);
topWidget->setFixedWidth(800);
topWidget->setLayout(topHLayout);

/* 底部布局 */
for (int i = 0; i < 7; i++) {
bottomHLayout->addWidget(bottom_pushButton[i]);
}

bottomHLayout->setContentsMargins(5, 0, 5, 0);
bottomHLayout->setAlignment(Qt::AlignLeft);
bottomHLayout->setSpacing(62);
bottomWidget->setFixedHeight(100);
bottomWidget->setLayout(bottomHLayout);
bottom_pushButton[0]->setText("led");
bottom_pushButton[1]->setText("Score");
bottom_pushButton[2]->setText("Volume");
bottom_pushButton[4]->setText("Original");
bottom_pushButton[5]->setText("Next");
bottom_pushButton[6]->setText("List");

connect(top_pushButton[4], SIGNAL(clicked()), this, SLOT(top_pushButton_4()));
/* 加载qss样式文件 */
//loadStyle();
}

void Video::loadStyle()
{
/* 指定文件 */
QFile file(":/style.qss");

/* 判断文件是否存在 */
if (file.exists() ) {
/* 以只读的方式打开 */
file.open(QFile::ReadOnly);
/* 以字符串的方式保存读出的结果 */
QString styleSheet = QLatin1String(file.readAll());
/* 设置全局样式 */
this->setStyleSheet(styleSheet);
/* 关闭文件 */
file.close();
}
}
Video::~Video()
{
}

int Video::add(int a, int b)
{
//qDebug() << "a + b=" << a+b;
//this->resize(800, 480);
//this->setMinimumSize(800, 480);
// this->setAttribute(Qt::WA_TranslucentBackground, true);
//this->setStyleSheet("QWidget { background-color: rgba(255, 245, 238, 100%); }");
return a+b;
}
void Video::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
mainWidget->resize(this->size());
qDebug() << 222222 ;
}

void Video::top_pushButton_4()
{
/* 设置主窗口的样式1 */
//this->setStyleSheet("QMainWindow { background-color: rgba(255, 245, 238, 100%); }");
this->hide();
AppDemo *appDemo = new AppDemo();
appDemo->show();
}

/* 槽函数的实现 */
void Video::pushButton2_Clicked()
{
/* 设置主窗口的样式2 */
this->setStyleSheet("QMainWindow { background-color: rgba(238, 122, 233, 100%); }");
}



video.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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#ifndef VIDEO_H
#define VIDEO_H

#include <QWidget>
#include <QDebug>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include "../appdemo/appdemo.h"
class Video : public QWidget
{
Q_OBJECT
public:
explicit Video(QWidget *parent = nullptr);
~Video();
private:
/* 主widget */
QWidget *mainWidget;

/* 顶部widget */
QWidget *topWidget;

/* 中间widget */
QWidget *middleWidget;

/* 底部widget */
QWidget *bottomWidget;

/* 中间_左边Widget,也就是人物Widget */
QWidget *mid_left_Widget;

/* 中间_右边Widget,也就是小方格Widget */
QWidget *mid_right_Widget;

/* 中间_右边_顶部Widget */
QWidget *mid_right_top_Widget;

/* 中间_右边_底部Widget */
QWidget *mid_right_bottom_Widget;

/* 主布局 */
QVBoxLayout *mainVLayout;

/* 顶部布局 */
QHBoxLayout *topHLayout;

/* 中间布局 */
QHBoxLayout *middleHLayout;

/* 底部布局 */
QHBoxLayout *bottomHLayout;

/* 中间_左边布局 */
QVBoxLayout *mid_left_VLayout;

/* 中间_右边布局 */
QVBoxLayout *mid_right_VLayout;

/* 中间_右边顶部布局*/
QHBoxLayout *mid_right_top_HLayout;

/* 中间_右边底部布局*/
QHBoxLayout *mid_right_bottom_HLayout;

/* 中间按钮,从左到右,从上到下分布 */
QPushButton *mid_pushButton[6];

/* 顶部按钮,从左到右 */
QPushButton *top_pushButton[5];

/* 底部按钮,从左到右 */
QPushButton *bottom_pushButton[7];

/* 重设大小 */
void resizeEvent(QResizeEvent *event);
/* 加载qss */
void loadStyle();

/* 声明一个QPushButton对象pushButton1 */
QPushButton *pushButton1;
/* 声明一个QPushButton对象pushButton2 */
QPushButton *pushButton2;
// Ui::Video *ui;
private slots:
/* 声明对象pushButton1的槽函数 */
void top_pushButton_4();
/* 声明对象pushButton2的槽函数 */
void pushButton2_Clicked();
public:
int add(int a, int b);


signals:

public slots:
};

#endif // TEST_H

如上即为,新界面的数据。

在appdemo中调用如下:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include "appdemo.h"
#include <QFile>

AppDemo::AppDemo(QWidget *parent)
: QWidget(parent)
{
this->resize(800, 480);
this->setMinimumSize(800, 480);
this->setAttribute(Qt::WA_TranslucentBackground, true);

mainWidget = new QWidget(this);
topWidget = new QWidget();
middleWidget = new QWidget();
bottomWidget = new QWidget();

mid_left_Widget = new QWidget();
mid_right_Widget = new QWidget();

mid_right_top_Widget = new QWidget();
mid_right_bottom_Widget = new QWidget();


for (int i = 0; i < 6; i++) {
mid_pushButton[i] = new QPushButton();
mid_pushButton[i]->setObjectName(tr("mid_pushButton%1").arg(QString::number(i)));
mid_pushButton[i]->setFocusPolicy(Qt::NoFocus);

if (i != 5) {
top_pushButton[i] = new QPushButton();
top_pushButton[i]->setFixedSize(120, 60);
top_pushButton[i]->setObjectName(tr("top_pushButton%1").arg(QString::number(i)));
top_pushButton[i]->setFocusPolicy(Qt::NoFocus);
}
}

for (int i = 0; i < 7; i++) {
bottom_pushButton[i] = new QPushButton();
bottom_pushButton[i]->setFixedSize(60, 60);
bottom_pushButton[i]->setObjectName(tr("bottom_pushButton%1").arg(QString::number(i)));
bottom_pushButton[i]->setFocusPolicy(Qt::NoFocus);
}


mainVLayout = new QVBoxLayout();
topHLayout = new QHBoxLayout();
bottomHLayout = new QHBoxLayout();
middleHLayout = new QHBoxLayout();
mid_left_VLayout = new QVBoxLayout();
mid_right_VLayout = new QVBoxLayout();
mid_right_top_HLayout = new QHBoxLayout();
mid_right_bottom_HLayout = new QHBoxLayout();

/* 主布局 */
mainVLayout->addWidget(topWidget);
mainVLayout->addWidget(middleWidget);
middleWidget->setFixedHeight(305);
mainVLayout->addWidget(bottomWidget);
mainWidget->setLayout(mainVLayout);
mainVLayout->setAlignment(Qt::AlignCenter);
mainVLayout->setContentsMargins(0, 0, 0, 0);

/* 中间布局 */
middleHLayout->addWidget(mid_left_Widget);
middleHLayout->setAlignment(Qt::AlignCenter);
mid_left_Widget->setFixedSize(305, 305);
middleHLayout->addWidget(mid_right_Widget);
middleHLayout->setContentsMargins(5, 0, 0, 0);
middleWidget->setLayout(middleHLayout);
middleWidget->setFixedSize(795, 300);

/* 中间左边布局 */
mid_left_VLayout->addWidget(mid_pushButton[0]);
mid_pushButton[0]->setFixedSize(305, 305);
mid_left_VLayout->setContentsMargins(0, 0, 0, 0);
mid_left_Widget->setLayout(mid_left_VLayout);

/* 中间右边布局 */
mid_right_VLayout->addWidget(mid_right_top_Widget);
mid_right_VLayout->addWidget(mid_right_bottom_Widget);
mid_right_VLayout->setContentsMargins(0, 0, 0, 0);
mid_right_Widget->setLayout(mid_right_VLayout);

/* 中间右边顶部布局 */
mid_right_top_HLayout->addWidget(mid_pushButton[1]);
mid_pushButton[1]->setFixedSize(150, 150);
mid_pushButton[1]->setText("Name of song");
mid_right_top_HLayout->addWidget(mid_pushButton[2]);
mid_pushButton[2]->setFixedSize(150, 150);
mid_pushButton[2]->setText("Categories");
mid_right_top_HLayout->addWidget(mid_pushButton[3]);
mid_pushButton[3]->setFixedSize(150, 150);
mid_pushButton[3]->setText("Top List");
mid_right_top_HLayout->setContentsMargins(0, 0, 0, 0);
mid_right_top_Widget->setLayout(mid_right_top_HLayout);

/* 中间右边底部布局 */
mid_right_bottom_HLayout->addWidget(mid_pushButton[4]);
mid_pushButton[4]->setFixedSize(150, 150);
mid_pushButton[4]->setText("New");
mid_right_bottom_HLayout->addWidget(mid_pushButton[5]);
mid_pushButton[5]->setFixedHeight(150);
mid_pushButton[5]->setText("Stars");
mid_right_bottom_HLayout->setContentsMargins(0, 0, 0, 0);
mid_right_bottom_Widget->setLayout(mid_right_bottom_HLayout);

/* 顶部布局 */
for (int i = 0; i < 5; i++) {
if (i == 4) {
QSpacerItem *hSpacer0 = new QSpacerItem(150, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
topHLayout->addSpacerItem(hSpacer0);
}
topHLayout->addWidget(top_pushButton[i]);
topHLayout->setAlignment(Qt::AlignTop | Qt::AlignHCenter | Qt::AlignLeft);
topHLayout->setContentsMargins(0, 0, 0, 20);
}
topHLayout->setSpacing(20);
top_pushButton[1]->setText("Select songs");
top_pushButton[2]->setText("Interation");
top_pushButton[3]->setText("More ");
top_pushButton[4]->setText("Search ");
topWidget->setFixedHeight(80);
topWidget->setFixedWidth(800);
topWidget->setLayout(topHLayout);

/* 底部布局 */
for (int i = 0; i < 7; i++) {
bottomHLayout->addWidget(bottom_pushButton[i]);
}

bottomHLayout->setContentsMargins(5, 0, 5, 0);
bottomHLayout->setAlignment(Qt::AlignLeft);
bottomHLayout->setSpacing(62);
bottomWidget->setFixedHeight(100);
bottomWidget->setLayout(bottomHLayout);
bottom_pushButton[0]->setText("Service");
bottom_pushButton[1]->setText("Score");
bottom_pushButton[2]->setText("Volume");
bottom_pushButton[4]->setText("Original");
bottom_pushButton[5]->setText("Next");
bottom_pushButton[6]->setText("List");

/* 加载qss样式文件 */
loadStyle();

connect(bottom_pushButton[0], SIGNAL(clicked()), this, SLOT(pushButton1_Clicked()));

}

AppDemo::~AppDemo()
{
}

void AppDemo::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
mainWidget->resize(this->size());
qDebug() << 222222 ;
}

void AppDemo::loadStyle()
{
/* 指定文件 */
QFile file(":/style.qss");

/* 判断文件是否存在 */
if (file.exists() ) {
/* 以只读的方式打开 */
file.open(QFile::ReadOnly);
/* 以字符串的方式保存读出的结果 */
QString styleSheet = QLatin1String(file.readAll());
/* 设置全局样式 */
this->setStyleSheet(styleSheet);
/* 关闭文件 */
file.close();
}
}
/* 槽函数的实现 */
void AppDemo::pushButton1_Clicked()
{
/* 设置主窗口的样式1 */
this->hide();
Video *video = new Video();
video->show();

}


整体的点击后效果如下:

新创界面_1786x800

到处点击跳转的功能已经实现,back后的效果如下:

back界面_1786x800

收获总结

经过一天的时间,对源码的分析、拆解,逐渐达到自己需要的效果,后续再进行自主开发、学习。对C++的开发有了跟深入的理解,在这问题上遇到了PC端上的现象跟开发板板的现象不一致,应该是存在着细微的差别,在PC上运行存在一些问题,但是在开发板上,是能正常显示的,这一类问题,需要后续注意,双方要互相验证一下。

这几天,继续快马加鞭的开发,把需要学习的地方,深入学习一下。