用QT做个养成类小游戏

记录短学期作业的完成过程

我的队友是ChatGPT,致敬人工智能👩🏼‍💻

“小狗撑起一个家” 是一款有趣的小狗养成类游戏,让玩家体验养育可爱小狗、打理家庭和参与各种冒险的乐趣。在这个游戏中,玩家将扮演一位爱心满满的主人,收养一只可爱的小狗,并与它一起建立一个幸福的家庭。


1.工具准备

  • 可以编译c++程序的编译器,和编写代码的软件。我使用的是VSCode,后期直接用QTCreat写了
  • QT Creator和Qt Designer(其实QT Creator一个集合环境就可以全部实现,但是我每次设置新增页面的样式表都会卡死。为了避免卡死丢失数据我选择用Qt Designer单独完成ui界面的设置)

2.题目

基于QT开发一款动物世界小游戏

目的:模拟一个动物家庭。通过设计和编写该程序,锻炼结构化程序设计和面向对象的基本编程技能,提高程序组织的合理性、可读性和可维护性。

要求:设计一个爱心家庭;功能包括有若干动物家庭成员,模拟成员日常的吃、玩、病、以及购物、工作、做家务等功能。建议采用良好的控制台人机交互界面。

最后只实现了一个狗狗家庭成员

问题描述:

(1) 初始时具有基本的生命特征和生存条件。

(2) 当吃东西后,体重增加,体能增加;

(3) 当锻炼后,体重下降,体能下降,要求恢复体力;

(4) 干活后,体能下降,爱心增加,能力增加;

(5) 打工后,体能下降,经验和金钱上升,爱心增加;

(6) 没有食品,就处于饥饿状态,报警;

(7) 买食品,需要付出金钱;

要求有商店、商店中有多种类商品,工作也有多个种类。

3.流程

3.1 正经流程
  • 游戏开始

  • 游戏流程

  • 家庭属性和成员属性

3.2 游戏规则

首先开局家庭中有10金币,食物储存为0,爱心数量为5,可选择一位动物家庭成员。

我爱小狗,所有动物成员都是小狗,可选不同品种,不同品种有不同的特点。

收养新的家庭成员需要消耗爱心,每一只狗狗消耗五颗爱心,把十只狗狗狗领养回家可以获得一个荣誉。做家务和打工都可以获得爱心。爱心每达到十的倍数就奖励一颗爱心。

在游戏过程中,购买食物需要消耗金币,动物家庭成员外出打工可以赚金币,金币达到666可获得一个荣誉。

动物家庭成员刚刚到家时的体力为10(体力满为10),能力为0。打工和做家务都需要消耗体力,进食可以补充体力。体力低于3不能锻炼、打工和做家务,体力低于2即体力为1时会提示,体力为0就会生病。做家务和打工都可以增加能力,只有能力达到5,同时体力大于3才能外出打工。

大型犬和小型犬每次活动的消耗和回报不一样。

5.部分代码

5.1 QT内类的实现

Dog类示例

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
//头文件
#ifndef DOG_H
#define DOG_H

#include <QPixmap>

class Dog
{
protected:
int ability; //能力
double energy; //精力
QString name; //名字
int ill; //疾病状态
int worktime; //判断工作时长
int state; //判断是否正在忙碌

public:

Dog();
virtual ~Dog();

void DogGrow(); //日常精力消耗
void setDogName(QString Dogname);
void setDogAbility(int Dogability);
void setDogEnergy(double Dogenergy);
void resetDogIll();
void setDogIll(int DogIll);
void setDogState(int Dogstate);
void setDogWorktime(int Worktime);

QString getDogName();
int getDogAbility();
double getDogEnergy();
int getDogIll();
int getDogState();
int getDogWorktime();
void judgeDogIll();

void doHousework();
virtual void doWork() = 0;
virtual void eat(int food) = 0;
};

class BigDog : public Dog
{
public:
BigDog();
void eat(int food) override;
void doWork() override;
};

class SmallDog : public Dog
{
public:
SmallDog();
void eat(int food) override;
void doWork() override;
};

#endif // DOG_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
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
200
201
#include "dog.h"
#include "family.h"
#include "config.h"
#include <QMessageBox>
#include <QInputDialog>


Dog::Dog()
{
ill=0;
ability=0;
energy=10;
state=0;
worktime=0;
}

Dog::~Dog() {}

void Dog::DogGrow()
{
if(ill==1||energy<=0.0) return; //如果小狗生病了,就直接退回不会发生经历的的消耗

if(state==0)
{
if(energy-1<=0.0)
{
energy=0.0;
}
else
{
energy--; //日常活动默认精力减一
}

}
else
{
state=0;
}

}

void Dog::setDogName(QString Dogname)
{
name=Dogname;
}

void Dog::setDogEnergy(double Dogenergy)
{
energy=Dogenergy;
}

void Dog::setDogAbility(int Dogability)
{
ability=Dogability;
}

void Dog::resetDogIll()
{
worktime=0;
ill=0;
}

void Dog::setDogIll(int DogIll)
{
ill=DogIll;
}

void Dog::setDogState(int Dogstate)
{
state=Dogstate;
}

void Dog::setDogWorktime(int Worktime)
{
worktime=Worktime;
}

QString Dog::getDogName()
{
return name;
}

double Dog::getDogEnergy()
{
return energy;
}

int Dog::getDogAbility()
{
return ability;
}

int Dog::getDogIll()
{
return ill;
}

int Dog::getDogState()
{
return state;
}

int Dog::getDogWorktime()
{
return worktime;
}

void Dog::judgeDogIll()
{
if(energy==0.0)
{
ill=1;
}

if(worktime==5)
{
ill=1;
}
}

void Dog::doHousework()
{
if (energy >= 2)
{
energy --;
ability ++;
worktime ++;
QMessageBox::warning(nullptr, "做家务", "小狗帮忙家务一小时,快夸夸小狗!\n");
state=1;
}
else
{
QMessageBox::warning(nullptr, "做家务", "小狗很累,快为小狗补充体力吧!\n");
}
}

BigDog::BigDog(){}

void BigDog::eat(int food)
{
energy += (food / 2.0);
}

void BigDog::doWork()
{

if (energy >= 3.0 && ability >= 5)
{
energy -= (1 / 2.0);
ability ++;
worktime ++;
QMessageBox::warning(nullptr, "打工", "小狗将出门打工一小时,记得奖励小狗哦!\n");
state=1;
}
else
{

if (energy < 3.0)
{
QMessageBox::warning(nullptr, "打工", "小狗很累,快为小狗补充体力吧!\n");
}
else if (ability < 5)
{
QMessageBox::warning(nullptr, "打工", "经验不足被老板劝退了,去做家务增加经验吧!\n");
}

}

}

SmallDog::SmallDog(){}

void SmallDog::eat(int food)
{
energy += food;
}

void SmallDog::doWork()
{
QString message="";
if (energy >= 3.0 && ability >= 5)
{
energy --;
ability ++;
worktime ++;
QMessageBox::warning(nullptr, "打工", "小狗将出门打工一小时,记得奖励小狗哦!\n");
state=1;
}
else
{

if (energy < 3.0)
{
QMessageBox::warning(nullptr, "打工", "小狗很累,快为小狗补充体力吧!\n");
}
else if (ability < 5)
{
QMessageBox::warning(nullptr, "打工", "经验不足被老板劝退了,去做家务增加经验吧!\n");
}
}
}

5.2 部分功能介绍

读档存档

利用TXT文件的读写实现存档功能

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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

//-------------------------读档存档界面-----------------------------
//初始载入存档名称
void ShiJX_Widget::InitialRecord()
{
QFile Fread("../PuppiesMakeAHome/database/Save1.txt");
bool isExist=Fread.open(QIODevice::ReadOnly);
if(isExist){
QDataStream ds(&Fread);
QString s;
ds >> s;
if(strcmp(s.toUtf8().data(),"!@#$%^")==0){
ui->save1->setText("新建家庭"); //save1是图形化界面中组件的名字,下同
ui->read1->setText("新建家庭");
}
else
{
ui->save1->setText(s);
ui->read1->setText(s);
}
}
Fread.close();

Fread.setFileName("../PuppiesMakeAHome/database/Save2.txt");
isExist=Fread.open(QIODevice::ReadOnly);
if(isExist){
QDataStream ds(&Fread);
QString s;
ds >> s;
if(strcmp(s.toUtf8().data(),"!@#$%^")==0){
ui->save2->setText("新建家庭");
ui->read2->setText("新建家庭");
}
else{

ui->save2->setText(s);
ui->read2->setText(s);
}
}
Fread.close();

Fread.setFileName("../PuppiesMakeAHome/database/Save3.txt");
isExist=Fread.open(QIODevice::ReadOnly);
if(isExist){
QDataStream ds(&Fread);
QString s;
ds >> s;
if(strcmp(s.toUtf8().data(),"!@#$%^")==0){
ui->save3->setText("新建家庭");
ui->read3->setText("新建家庭");
}
else{

ui->save3->setText(s);
ui->read3->setText(s);
}
}
Fread.close();

Fread.setFileName("../PuppiesMakeAHome/database/Save4.txt");
isExist=Fread.open(QIODevice::ReadOnly);
if(isExist){
QDataStream ds(&Fread);
QString s;
ds >> s;
if(strcmp(s.toUtf8().data(),"!@#$%^")==0){
ui->save4->setText("新建家庭");
ui->read4->setText("新建家庭");
}
else{

ui->save4->setText(s);
ui->read4->setText(s);
}
}
Fread.close();

}

//重置存档
void ShiJX_Widget::ResetRecord(QString recordPath)
{
QPushButton* pSave=ui->save1,*pRead=ui->read1;
if(recordPath=="../PuppiesMakeAHome/database/Save1.txt"){
pSave=ui->save1;
pRead=ui->read1;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save2.txt"){
pSave=ui->save2;
pRead=ui->read2;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save3.txt"){
pSave=ui->save3;
pRead=ui->read3;
}
else if(recordPath==".../PuppiesMakeAHome/database/Save4.txt"){
pSave=ui->save4;
pRead=ui->read4;
}


QFile Fwrite(recordPath);
bool isExist=Fwrite.open(QIODevice::WriteOnly); //对存档文件进行只写操作写入空存档标志 !@#$%^
if(isExist){
QDataStream ds(&Fwrite);
QString s="!@#$%^";
ds << QString(s);
}

pSave->setText("新建家庭");
pRead->setText("新建家庭");

Fwrite.close();

}

//读档
void ShiJX_Widget::ReadRecord(QString recordPath)
{
int ret=QMessageBox::question(this,"提示","<h3>确定选择该存档?</h3>");
if(ret==QMessageBox::No) return;


QPushButton* pSave=ui->save1,*pRead=ui->read1;
if(recordPath=="../PuppiesMakeAHome/database/Save1.txt"){
pSave=ui->save1;
pRead=ui->read1;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save2.txt"){
pSave=ui->save2;
pRead=ui->read2;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save3.txt"){
pSave=ui->save3;
pRead=ui->read3;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save4.txt"){
pSave=ui->save4;
pRead=ui->read4;
}

QFile Fread(recordPath);
if(pSave->text()=="新建家庭")
{
bool isExist=Fread.open(QIODevice::WriteOnly);
if(isExist)
{
QDataStream ds(&Fread);
QString tmp="";
Family family;
//初始化家庭

Demo.Initial();
Demo.dogs.clear();
InitialStore();
InitialHome();
//家庭信息
while(tmp=="")
{
tmp=QInputDialog::getText(this,"提示",QString("<h3>请给小家起个名字吧:</h3>"));
}
Demo.setFamilyTitle(tmp);
ds<<Demo.getFamilyTitle();
pSave->setText(Demo.getFamilyTitle());
pRead->setText(Demo.getFamilyTitle());

Demo.setFamilyWealth(30);
ds<<QString::number(Demo.getFamilyWealth());
Demo.setFamilyLove(5);
ds<<QString::number(Demo.getFamilyLove());

QMessageBox::question(this,"新建家庭成功","<h3>快去领养一只狗狗吧!</h3>");
}
InitInformation();
}
else
{
QMessageBox::information(this,"读档成功","快回家看看小狗吧~");
bool isExist=Fread.open(QIODevice::ReadOnly);
if(isExist){
QDataStream ds(&Fread);
QString itmp,jtmp,ktmp,stmp;

//初始化
Demo.Initial();
InitialHome();

//家庭信息
ds>>stmp;
Demo.setFamilyTitle(stmp.toUtf8().data());
ds>>stmp;
Demo.setFamilyWealth(stmp.toUtf8().toInt());
ds>>stmp;
Demo.setFamilyLove(stmp.toUtf8().toInt());
ds>>stmp;
Demo.setFamilyReserveBonse(stmp.toUtf8().toInt());
ds>>stmp;
Demo.setFamilyReserveDogfood(stmp.toUtf8().toInt());
ds>>stmp;
Demo.setFamilyReserveMedicine(stmp.toUtf8().toInt());
ds>>stmp;
Demo.setPlayerTime(stmp.toUtf8().toInt());
ds>>stmp;
Demo.member=stmp.toUtf8().toInt();

//狗狗信息
Dog *dogTmp; // 在 if-else 结构之前声明

ds >> itmp;
for (int j = 0; j < itmp.toUtf8().toInt(); j++)
{
if (Demo.member > 4) {
dogTmp = new BigDog(); // 初始化变量
} else {
dogTmp = new SmallDog(); // 初始化变量
}

ds>>stmp;
dogTmp->setDogName(stmp.toUtf8().data());
ds>>stmp;
dogTmp->setDogAbility(stmp.toUtf8().toInt());
ds>>stmp;
dogTmp->setDogEnergy(stmp.toUtf8().toDouble());
ds>>stmp;
dogTmp->setDogIll(stmp.toUtf8().toInt());
ds>>stmp;
dogTmp->setDogState(stmp.toUtf8().toInt());
ds>>stmp;
dogTmp->setDogWorktime(stmp.toUtf8().toInt());
Demo.dogs.push_back(dogTmp);

}
}
}
Fread.close();
haveLoadGame=1;
renovate();
InitialHome();

ui->stackedWidget->setCurrentWidget(ui->home);

//禁用/启用按钮
if(haveLoadGame==0){
ui->pushButton_newmember->setEnabled(false);
ui->pushButton_gotostore->setEnabled(false);
ui->pushButton_honor->setEnabled(false);
}
else{
ui->pushButton_save->setEnabled(true);
}

}

//存档
void ShiJX_Widget::SaveRecord(QString recordPath)
{
int ret=QMessageBox::question(this,"提示","确定覆盖存档?");
if(ret==QMessageBox::No) return;

QPushButton* pSave=ui->save1,*pRead=ui->read1;
if(recordPath=="../PuppiesMakeAHome/database/Save1.txt"){
pSave=ui->save1;
pRead=ui->read1;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save2.txt"){
pSave=ui->save2;
pRead=ui->read2;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save3.txt"){
pSave=ui->save3;
pRead=ui->read3;
}
else if(recordPath=="../PuppiesMakeAHome/database/Save4.txt"){
pSave=ui->save4;
pRead=ui->read4;
}


QFile Fread(recordPath);
bool isExist=Fread.open(QIODevice::WriteOnly);
if(isExist)
{
QDataStream ds(&Fread);

//按顺序存储关键信息,读档顺序需和存档顺序一致

//家庭信息
ds<<Demo.getFamilyTitle();
pSave->setText(Demo.getFamilyTitle());
pRead->setText(Demo.getFamilyTitle());
ds<<QString::number(Demo.getFamilyWealth());
ds<<QString::number(Demo.getFamilyLove());
ds<<QString::number(Demo.getFamilyReserveBonse());
ds<<QString::number(Demo.getFamilyReserveDogfood());
ds<<QString::number(Demo.getFamilyReserveMedicine());
ds<<QString::number(Demo.getPlayerTime());
ds<<QString::number(Demo.member);

//狗狗信息
ds<<QString::number(Demo.dogs.size());
for(int j=0;j<Demo.dogs.size();j++)
{
ds<<Demo.dogs[j]->getDogName();
ds<<QString::number(Demo.dogs[j]->getDogAbility());
ds<<QString::number(Demo.dogs[j]->getDogEnergy());
ds<<QString::number(Demo.dogs[j]->getDogIll());
ds<<QString::number(Demo.dogs[j]->getDogState());
ds<<QString::number(Demo.dogs[j]->getDogWorktime());
}
}
Fread.close();
InitialRecord();
}
定时器事件

需要在主界面头文件中声明如下部分:

1
2
3
4
5
#include <QTimer>
//public
int millisecondPerHour=10000; //游戏速率
int timerKiller;
void timerEvent(QTimerEvent *e); //计时器事件

cpp文件中构造并使用定时器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//需要按时间刷新的函数一起写在定时器时间里
void ShiJX_Widget::timerEvent(QTimerEvent *)
{
int x;
x=Demo.getPlayerTime();
Demo.setPlayerTime(++x);
InitialHome();
//renovate();
DogGrowing();
Initialchoose();
}

//停止定时器语句,插入在功能函数中
killTimer(timerKiller);
//开启定时器语句
timerKiller=startTimer(millisecondPerHour);

6.QT图形化界面部分

6.1 QT环境准备

我们下载的这个程序就是QT Creator

首先下载QT,下载链接:Index of / (qt.io),选择 archive - qt/

我选择了5.12.3版本,点击直接下载,还挺慢的🥲

下载之后运行

next之后提示你登录,没有账号去注册一个就行,只需要填一个邮箱和密码就行。

我看到的教程里都是直接跳过,但现在好像不行了

接下来选择安装路径,我放在了D盘和运行程序在一个文件夹里

选择需要的组件,全选的话占内存很大没必要,毕竟我们只是做个作业又不会用它做很多东西。

这里要改成同意嗷👇🏼

下一页忘记截图了就是安装桌面快捷方式,直接默认next就好。接下来就是等待安装啦,时间很长可以去跑个两公里。

有些教程上会讲到配置环境变量,因为我本来就有C++的编译环境就不需要辣

土狗发言

Qt Creator是一个集成环境,它集成了Qt Designer,可以直接从Qt Creator中打开和编辑.ui文件。我们也可以搜索到Qt Designer运行程序并单独使用它。

我认为如果有双屏,再开一个Qt Designer单独编辑页面布局工作效率更高。

6.2 QT边学边写

QT项目需求

  • 游戏背景为一个房间内部的静态图片
  • 鼠标悬停在家庭成员小狗身上时显示对应的家庭成员的信息
  • 点击小狗家庭成员可以选择要进行的活动
  • 页面侧边有几个选项可以选择对应的活动
  • 页面顶部显示家庭信息
6.2.1 创建新项目

选择新建new project,choose第一个,设置构建路径后在类名选择部分选择widget,注意路径中不能有中文。

这个地方要把勾选取消👇🏼

会直接生成框架,这时如果ctrl+R(编译并运行)会弹出一个空的小白框

6.2.2 主场景设置

新建一个头文件config.h,添加主场景信息

窗口大小和标题设置

对应图片信息设置相对应的界面信息,在这里我的图片有点小,所以我把对应数据都乘了2

1
2
3
4
5
//游戏配置数据
#define GAME_WIDTH 1282 //界面的宽度
#define GAME_HEIGHT 792 //界面的高度
#define GAME_TITLE "小狗撑起一个家"
#define GAME_ICON ":/img/favicon.ico" //图标加载路径

再在主头文件中添加相应语句,快捷键alt+enter在.cpp文件中添加定义

对应的.cpp代码,记得在第一个函数中声明initScene()

1
2
3
4
5
6
7
8
9
10
11
12
//初始化界面配置
void MainWindow::initScene()
{
//设置窗口尺寸
setFixedSize(GAME_WIDTH,GAME_HEIGHT);

//设置标题
setWindowTitle(GAME_TITLE);

//加载图标
setWindowIcon(QIcon(GAME_ICON));
}
背景和图标设置

在当前文件夹下新建文件,选择QT-resource

右键单击文件打开,把图片素材都放进去

至此,我推翻重来。发现自己建文件的时候建成了mainwindows。🥲

UI界面

使用容器Stacked Widget,会自动分页分为两个窗口。

初步计划将第一个窗口作为home页面即游戏主页面,第二个窗口作为商店页面

所有基础的游戏背景都是使用 photoshop 制作完成。

设置按钮后利用图形界面设置跳转

选择released是点击松开后跳转。

在.cpp文件内设置响应代码使指针指向跳转页面

页面利用 ps 直接制作相应非功能按钮部分减少工作量

7.遇到的问题

7.1 C++代码

7.1.1 黑窗中文输出乱码

run code是正常的,但是黑框是乱码,据说二者不可兼得,就这样吧

哈哈没有解决方案🤪

7.1.2 商店的实现

最后发现我可以不用商店这个类,因为在游戏中的商店数据是静态的不会增加或减少,直接在main函数中设置即可,可以减少代码冗余量。

前情提要:

如果直接设置商店类,无法实现商店中有多种可选择的商品。所以设想是先定义一个商品类,商品类中存储商品的名称和价格数据。再设置商店类,在商店类中存储商品的数组,并定义购物的函数。

那么如何实现在商店中存储商品数组呢?

vector<Product> products;这句代码声明了一个名为products的变量,类型为vector<Product>vector是C++标准库中的容器类之一,用于存储多个元素的动态数组。

需要配合头文件#include<vector>使用。

除此之外,有以下几种固定的函数使用规定:

对于 vector 容器,可以对数组进行动态调整、添加、删除和查找元素等操作:

  1. 添加元素:使用 push_back() 函数将新元素添加到数组的末尾。

    1
    products.push_back(product);  // 向数组末尾添加一个新元素
  2. 删除元素:使用 erase() 函数删除指定位置或指定元素。

    • 删除指定位置的元素:

      1
      products.erase(products.begin() + index);  // 删除指定位置的元素,index 为元素的索引
    • 删除指定元素的所有匹配项:

      1
      products.erase(std::remove(products.begin(), products.end(), product), products.end());  // 删除指定元素的所有匹配项
  3. 查找元素:可以使用 find() 函数或遍历数组来查找指定元素。

    • 使用 find() 函数:

      1
      2
      3
      4
      5
      6
      auto it = std::find(products.begin(), products.end(), product);  // 在数组中查找指定元素,product 为要查找的元素
      if (it != products.end()) {
      // 元素找到
      } else {
      // 元素未找到
      }
    • 遍历数组:

      1
      2
      3
      for (const auto& item : products) {
      // 对每个元素进行操作,item 为当前遍历到的元素
      }

7.2 QT报错

7.2.1 qmake问题

Error while building/deploying project ShortTerm (kit: Desktop Qt 5.12.3 MinGW 64-bit)

When executing step “qmake”

问题原因就是构建目录不能放置在中文目录下,需要在英文目录里建立文件。

7.2.2 图片载入报错

error: No rule to make target ‘img/???-1.png’, needed by ‘debug/qrc_img.cpp’. Stop.

发生在添加完资源后在QT界面为图片重命名的情况。

找到文件夹中的.qmake.stash,将其删除重新构建一次程序即可。

7.2.3 载入资源后图片不显示

在添加完资源文件以后,要先菜单栏->构建->qmake一下,否则是无法显示的。

7.2.4 卡死

新建一页page后设置样式表会卡死,没有正面解决方法,等一会再弄或者用Qt Designer单独配置ui。

嗷,还可以直接用代码设置样式表,不要用选项就不会卡。

别管了我精神失常了

7.2.5 槽信号

D:\software\QT\qt_project\PuppiesMakeAHome\debug\moc_shijx_widget.cpp:236: error: undefined reference to `ShiJX_Widget::on_pushButton_gotostore_2_released()’

报错是因为错误地建立了一个槽信号,但是不想要了。

就只在.cpp文件中删除了对应的函数。

解决方法是在.h头文件中找到对应的声明删除,并将.cpp文件中的函数删除,最后重构项目。


用QT做个养成类小游戏
https://shmodifier.github.io/2023/09/17/用QT做个养成类小游戏/
作者
Modifier
发布于
2023年9月17日
许可协议