Qt 小项目 学生管理信息系统

主要是对数据库的增删查改的操作

登录/注册界面:

主页面: 

添加信息:

删除信息:

删除第一行(支持多行删除) 

需求分析:

用QT实现一个学生管理信息系统,数据库为MySQL
要求:
- 1、要求有完整界面,如登录界面、信息操作界面
- 2、要求有数据库
- 3、可以录入学生信息
- 4、可以查询学生信息,支持模糊查询
- 5、可以修改学生信息,支持单个和批量修改
- 6、可以删除学生信息,支持单个和批量删除
- 7、学生信息包括:班级、学号、姓名、性别、出生年月、专业、所属学院

2024.11.30 bug和所需添加记录:
- 注册账号时空值也会新建(已解决)
- 数据库sql语句写在qt上,方便运行(已解决)
- 用户名规则,开头字母

2024.12.6 bug记录
- 相同账号和不同密码,弹出信息框错误(已解决)
- 代码耦合:qt数据库常量抽取出来(已解决)
- 添加信息后没有刷新信息

登录界面:

Login.h

#ifndef LOGIN_H
#define LOGIN_H#include <QWidget>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错
#include <QMessageBox> //消息对话框
#include <QDebug>QT_BEGIN_NAMESPACE
namespace Ui {
class Login;
}
QT_END_NAMESPACEclass Login : public QWidget
{Q_OBJECTpublic:Login(QWidget *parent = nullptr);~Login();void createDataBase();private slots:void on_loginbutton_clicked();void on_registerbtn_clicked();private:Ui::Login *ui;
};
#endif // LOGIN_H

Login.cpp

#include "login.h"
#include "ui_login.h"
#include "homepage.h"
#define databaseName "qt"Login::Login(QWidget *parent): QWidget(parent), ui(new Ui::Login)
{ui->setupUi(this);//加载驱动QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");db.setHostName("127.0.0.1"); // 主机IPdb.setUserName("root"); // 用户名db.setPassword(""); // 密码if (!db.open()) {qDebug() << "WARNING: " << db.lastError().text();return; // 如果连接失败,退出函数}// qDebug() << databaseName;// 检查数据库 qt 是否存在QSqlQuery query;if (!query.exec("CREATE DATABASE IF NOT EXISTS " databaseName)) {qDebug() << "创建数据库" << databaseName << "失败:" << query.lastError().text();return; // 数据库创建失败,退出函数}else{qDebug() << "数据库" << databaseName << "已存在!";}db.setDatabaseName(databaseName); // 现在切换到 qt 数据库if (!db.open()) {qDebug() << "WARNING: 无法打开 " << databaseName << "数据库:" << db.lastError().text();return; // 如果无法连接到 qt,退出函数}// 数据库连接成功,继续后续操作qDebug() << "成功创建数据库!" << databaseName ;createDataBase();
}//sql语句创建数据库
void Login::createDataBase() {// 创建user表的SQL语句QString createUserTable = "CREATE TABLE IF NOT EXISTS `user` (""`account` VARCHAR(20) NOT NULL, ""`pwd` VARCHAR(20) NOT NULL, ""PRIMARY KEY (`account`))";// 创建student表的SQL语句QString createStudentTable = "CREATE TABLE IF NOT EXISTS `student` (""`id` INT(5) NOT NULL, ""`name` VARCHAR(20) NOT NULL, ""`gender` VARCHAR(2) NOT NULL, ""`birthdate` VARCHAR(10) NOT NULL, ""`major` VARCHAR(20) NOT NULL, ""`class` VARCHAR(20) NOT NULL, ""`college` VARCHAR(20) NOT NULL, ""PRIMARY KEY (`id`))";// 执行创建表的SQL语句QSqlQuery query;if (query.exec(createUserTable) && query.exec(createStudentTable)) {qDebug() << "数据库创建成功";} else {qDebug() << "数据库创建失败" << query.lastError().text();}}void Login::on_loginbutton_clicked() //登录功能
{QString account = ui->account->text();QString password = ui->pwd->text();QString sql = QString("select * from user where account='%1' and pwd='%2'").arg(account).arg(password);QSqlQuery query(sql);if(query.next()){QMessageBox::information(this, "登录认证", "登录成功");//登录成功后可以跳转到主页面HomePage *window = new HomePage();window->show();this->close(); //关闭登录窗口}else{QMessageBox::information(this, "登录认证", "登录失败,账户或者密码错误");}// HomePage *window = new HomePage(); //测试专用// window->show();// this->close(); //关闭登录窗口
}void Login::on_registerbtn_clicked() //注册按钮
{QString account = ui->account->text().trimmed();QString password = ui->pwd->text().trimmed();//判断账号和密码是否为空if(account.isEmpty() || password.isEmpty()){QMessageBox::warning(this,"注册认证","账号或密码不能为空!");return; //退出函数}//相同账号,不同密码的情况:QString sql = QString("select * from user where account='%1'").arg(account);QSqlQuery query(sql);if(query.next()){QMessageBox::warning(this,"注册认证","账号已存在!");return; //退出函数}//注册账号sql = QString("insert into user(account,pwd) values('%1','%2');").arg(account).arg(password);if(query.exec(sql)){ //表中存在该账号和密码QMessageBox::information(this,"注册认证","注册失败!");}else{QMessageBox::information(this,"注册认证","注册成功!");}
}Login::~Login()
{delete ui;
}

Login.ui

学生管理信息系统界面:

HomePage.h

#ifndef HOMEPAGE_H
#define HOMEPAGE_H#include <QWidget>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错
#include <QMessageBox> //消息对话框
#include <QDebug>namespace Ui {
class HomePage;
}class HomePage : public QWidget
{Q_OBJECTpublic:explicit HomePage(QWidget *parent = nullptr);~HomePage();void initDatabase(); //加载数据库驱动函数void refreshTable(QString inquiresql); //刷新表格,查询数据库全部内容private slots:void on_refresh_btn_clicked();void on_delete_btn_clicked();void on_inquire_btn_clicked();void on_add_btn_clicked();void on_modify_btn_clicked();private:Ui::HomePage *ui;
};#endif // HOMEPAGE_H

HomePage.cpp

#include "homepage.h"
#include "ui_homepage.h"
#include "add.h"
#include "modify.h"
#define databaseName "qt"HomePage::HomePage(QWidget *parent): QWidget(parent), ui(new Ui::HomePage)
{ui->setupUi(this);initDatabase(); //加载数据库驱动//设置表头QStringList headerList; //定义headerList变量headerList << "选择栏" << "学号" << "姓名" << "性别" << "出生年月" << "专业" << "班级" << "学院"; //添加内容QFont font; //设置字号font.setPointSize(17);ui->tableWidget->setFont(font);ui->tableWidget->setColumnCount(headerList.size()); //设置列数=表头列数ui->tableWidget->setHorizontalHeaderLabels(headerList); //添加headerList到表头ui->tableWidget->setRowCount(3); //设置行数,不设置显示不出文本// 设置列表自动填充满窗口ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);// 设置输入框提示信息为占位符文本,一旦用户开始输入,提示信息会消失。ui->inquire_lineEdit->setPlaceholderText("支持模糊查询,输入姓名或者学号关键词");refreshTable(NULL);
}void HomePage::initDatabase(){ //加载数据库驱动函数QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");db.setHostName("127.0.0.1"); // 主机IPdb.setUserName("root"); // 用户名db.setPassword(""); // 密码db.setDatabaseName(databaseName); // 要连接哪个数据库,它的名字// 打开数据库,如果打不开就弹出报错对话框if(db.open() == false){qDebug() << "WARNING:" <<  db.lastError().text() << "\n";}// 打开成功qDebug() << "数据库成功打开" << "\n";
}void HomePage::refreshTable(QString inquiresql){//先【从最后往前】删除表格所有行for(int row = ui->tableWidget->rowCount()-1; row >= 0; row--){ui->tableWidget->removeRow(row);}QSqlQuery query;if(inquiresql.isEmpty()){QString sql = "select * from student";query.exec(sql);}else{query.exec(inquiresql);}//数据库查询并添加int row = 0;while(query.next()){int Old_RowCount = ui->tableWidget->rowCount(); //获取当前表格行数ui->tableWidget->setRowCount(Old_RowCount+1); //添加一行//第一列添加复选框QTableWidgetItem *checkbox = new QTableWidgetItem();checkbox->setCheckState(Qt::Unchecked); //设置非选中状态ui->tableWidget->setItem(row, 0, checkbox);//添加数据,未设置只读状态ui->tableWidget->setItem(row, 1, new QTableWidgetItem(query.value(0).toString())); // 学号ui->tableWidget->setItem(row, 2, new QTableWidgetItem(query.value(1).toString())); // 姓名ui->tableWidget->setItem(row, 3, new QTableWidgetItem(query.value(2).toString())); // 性别ui->tableWidget->setItem(row, 4, new QTableWidgetItem(query.value(3).toString())); // 出生年月ui->tableWidget->setItem(row, 5, new QTableWidgetItem(query.value(4).toString())); // 专业ui->tableWidget->setItem(row, 6, new QTableWidgetItem(query.value(5).toString())); // 班级ui->tableWidget->setItem(row, 7, new QTableWidgetItem(query.value(6).toString())); // 学院row++; //下一行}
}void HomePage::on_refresh_btn_clicked() //刷新学生信息
{QString nullString = NULL;refreshTable(nullString); //刷新表格
}void HomePage::on_delete_btn_clicked() //删除学生信息
{QList<QString> StudentId; //存储需要删除的学生id//遍历表格每一行for(int row = ui->tableWidget->rowCount()-1; row >= 0; row--){QTableWidgetItem *checkBoxItem = ui->tableWidget->item(row, 0); //读取勾选框的列表项if(checkBoxItem->checkState() == Qt::Checked){QTableWidgetItem *idItem = ui->tableWidget->item(row, 1); //读取id的列表项if (idItem) {StudentId.append(idItem->text());}}}//没勾选就不删了,退出函数if(StudentId.empty()){QMessageBox::information(this, "提示", "请先勾选需要删除的行");return;}//构建批量删除的SQL语句,参数化查询防止SQL注入QString sql = "DELETE FROM student WHERE id IN (";for (int i = 0; i < StudentId.size(); i++) {sql += "?";if (i < StudentId.size() - 1)sql += ",";}sql += ")";QSqlQuery query;query.prepare(sql);for (int i = 0; i < StudentId.size(); i++) {query.addBindValue(StudentId[i]);}if(query.exec()) {QString nullString = NULL;refreshTable(nullString); //删除成功后立即刷新表格QMessageBox::information(this, "成功", "删除成功!");} else {QMessageBox::information(this, "失败", "删除失败:" + query.lastError().text());}
}void HomePage::on_inquire_btn_clicked() //查询信息
{QString inquireString = ui->inquire_lineEdit->text().trimmed();QString sql = QString("select id, name, gender, birthdate, major, class, college from student where id like \"%1%2\" or name like \"%3%4\"").arg(inquireString, "%", inquireString, "%");refreshTable(sql);
}void HomePage::on_add_btn_clicked() //添加信息
{int Old_RowCount = ui->tableWidget->rowCount(); //获取当前表格行数ui->tableWidget->setRowCount(Old_RowCount+1); //添加一行add *window = new add();window->show();
}void HomePage::on_modify_btn_clicked() //根据学号修改信息
{Modify *window = new Modify();window->show();
}HomePage::~HomePage()
{delete ui;
}

HomePage.ui

添加信息界面:

add.h

#ifndef ADD_H
#define ADD_H#include <QWidget>
#include <QMessageBox> //消息对话框
#include <QDebug>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错namespace Ui {
class add;
}class add : public QWidget
{Q_OBJECTpublic:explicit add(QWidget *parent = nullptr);~add();private slots:void on_add_btn_clicked();private:Ui::add *ui;
};#endif // ADD_H

add.cpp

#include "add.h"
#include "ui_add.h"
#include "homepage.h"add::add(QWidget *parent): QWidget(parent), ui(new Ui::add)
{ui->setupUi(this);
}void add::on_add_btn_clicked()
{QString id = ui->id_linedit->text().trimmed();QString name = ui->name_lineEdit->text().trimmed();QString gender = ui->gender_lineEdit->text().trimmed();QString birthdate = ui->birth_lineEdit->text().trimmed();QString major = ui->major_lineEdit->text().trimmed();QString Class = ui->class_lineEdit->text().trimmed();QString college = ui->college_lineEdit->text().trimmed();//结束条件if(id.isEmpty() || name.isEmpty() || gender.isEmpty()|| birthdate.isEmpty() || major.isEmpty() || Class.isEmpty() || college.isEmpty()){QMessageBox::warning(this, "警告", "信息请填写完整!");return;}//判断学号是否存在,存在则结束QString sql = "select * from student where id = ?";QSqlQuery query;query.prepare(sql);query.bindValue("?", id);query.exec();if(query.next()){QMessageBox::warning(this, "警告", "学号已存在!");return;}//添加学生sql = QString("insert into student (id, name, gender, birthdate, major, class, college) values (\"%1\", \"%2\", \"%3\", \"%4\", \"%5\", \"%6\", \"%7\")").arg(id, name, gender, birthdate, major, Class, college);if(query.exec(sql)) {QMessageBox::information(this, "成功", "插入成功!");close(); //关闭窗口HomePage *homepage = new HomePage();homepage->refreshTable(NULL); //刷新表格}else {QMessageBox::information(this, "失败", "插入失败:" + query.lastError().text());}
}add::~add()
{delete ui;
}

add.ui

修改信息界面:

Modify.h

#ifndef MODIFY_H
#define MODIFY_H#include <QWidget>
#include <QMessageBox> //消息对话框
#include <QDebug>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错namespace Ui {
class Modify;
}class Modify : public QWidget
{Q_OBJECTpublic:explicit Modify(QWidget *parent = nullptr);~Modify();private slots:void on_modify_btn_clicked();private:Ui::Modify *ui;
};#endif // MODIFY_H

Modify.cpp

#include "modify.h"
#include "ui_modify.h"
#include "homepage.h"Modify::Modify(QWidget *parent): QWidget(parent), ui(new Ui::Modify)
{ui->setupUi(this);
}void Modify::on_modify_btn_clicked()
{QString id = ui->id_linedit->text().trimmed();QString name = ui->name_lineEdit->text().trimmed();QString gender = ui->gender_lineEdit->text().trimmed();QString birthdate = ui->birth_lineEdit->text().trimmed();QString major = ui->major_lineEdit->text().trimmed();QString Class = ui->class_lineEdit->text().trimmed();QString college = ui->college_lineEdit->text().trimmed();if(id.isEmpty() || name.isEmpty() || gender.isEmpty()|| birthdate.isEmpty() || major.isEmpty() || Class.isEmpty() || college.isEmpty()){QMessageBox::warning(this, "警告", "信息请填写完整!");return;}QSqlQuery query;QString sql = QString("update student set name = \"%1\"," "gender =\"%2\", birthdate =\"%3\", major = \"%4\", ""Class = \"%5\", college = \"%6\" where id =%7").arg(name, gender, birthdate, major, Class, college, id);if(query.exec(sql)){QMessageBox::information(this, "成功", "修改成功!");HomePage *homepage = new HomePage();QString nullString = NULL;homepage->refreshTable(nullString); //刷新表格close(); //关闭窗口}else{QMessageBox::information(this, "失败", "修改失败!");}
}Modify::~Modify()
{delete ui;
}

Modify.ui

参考资料:

【C++】C++ QT实现 学生信息管理系统(QT源码)【独一无二】_qt学生管理系统-CSDN博客

如何用qt实现学生信息管理系统_用qtcreater做一个学生信息管理系统-CSDN博客

Qt 学习第十一天:QTableWidget 的使用_qt tablewidget resize-CSDN博客

Qt 学习第十一天:QTableWidget 的使用_qt tablewidget resize-CSDN博客

Qt设计精美的登录注册界面(包含SQLite数据库应用)_qt登录界面设计-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/62256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“量子跃迁与数据织网:深入探索K最近邻算法在高维空间中的优化路径、神经网络融合技术及未来机器学习生态系统的构建“

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

硬件选型规则

光源选型: 先用型号中带H的&#xff0c;没有的选标准的. 光源和光源控制器的搭配需要确保接口一致。 根据型号表中的最佳工作距离和相机的尺寸。 光源控制器选型&#xff1a; 首先选择海康风格系列光源控制器考虑与光源的接口匹配。功率应该满足接近光源功率。检查是否退市…

【计算机网络】 —— 数据链路层(壹)

文章目录 前言 一、概述 1. 基本概念 2. 数据链路层的三个主要问题 二、封装成帧 1. 概念 2. 帧头、帧尾的作用 3. 透明传输 4. 提高效率 三、差错检测 1. 概念 2. 奇偶校验 3. 循环冗余校验CRC 1. 步骤 2. 生成多项式 3. 例题 4. 总结 四、可靠传输 1. 基本…

golang实现简单的redis服务

golang 手搓redis服务器仓库地址:实现思路: golang 手搓redis服务器 仓库地址: 仓库: https://github.com/dengjiayue/my-redis.git 实现思路: ● 协议: tcp通信 ● 数据包: 长度(4byte)方法(1byte)数据json ● 数据处理: 单线程map读写 ○ 依次处理待处理队列的请求(chan)…

智慧银行反欺诈大数据管控平台方案(八)

智慧银行反欺诈大数据管控平台的核心理念&#xff0c;在于通过整合先进的大数据技术、算法模型和人工智能技术&#xff0c;构建一个全面、智能、动态的反欺诈管理框架&#xff0c;以实现对金融交易的全方位监控、欺诈行为的精准识别和高效处理。这一理念强调数据驱动决策&#…

3D 生成重建019-LERF用文本在Nerf中开启上帝之眼

3D 生成重建019-LERF用文本在Nerf中开启上帝之眼 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 人类利用自然语言描述物理世界&#xff0c;根据各种特性&#xff08;视觉外观、语义、抽象关联&#xff09;寻找具体的3D位置。在这项工作中&#xff0c;作者提出了语言嵌…

如何选择合适的期刊投稿?从课题组经验到在线工具的使用全解析

~~~本文是作者个人的经验分享&#xff0c;建立在导师让自己选刊的情况下~~~ 投稿选刊是科研过程中至关重要的一步&#xff0c;选刊过程可能让许多初投稿的研究者感到迷茫和困惑&#xff1a;期刊那么多&#xff0c;如何找到最合适的&#xff1f; 本文将从多个角度介绍如何选择投…

.NET MAUI与.NET for Android/IOS的关系

2024年11月13日微软发布了.Net9.0,我打算体验一下。安装好.Net9.0 SDK后发现Visual Studio识别不到9.0&#xff0c;但是通过命令行dotnet --info查看是正常的&#xff0c;后面看到了VS有版本可以升级&#xff0c;把VS升级到17.12.0就可以了。更新完打开以后看到如下界面 这里…

【vivado】时序报告--best时序和worst时序

利用vivado进行开发时&#xff0c;生成best时序报告和worst时序报告。 best时序报告 slow选择min_max&#xff0c;fast选择none。 worst时序报告 fast选择min_max&#xff0c;slow选择none。

FastAPI 响应状态码:管理和自定义 HTTP Status Code

FastAPI 响应状态码&#xff1a;管理和自定义 HTTP Status Code 本文介绍了如何在 FastAPI 中声明、使用和修改 HTTP 状态码&#xff0c;涵盖了常见的 HTTP 状态码分类&#xff0c;如信息响应&#xff08;1xx&#xff09;、成功状态&#xff08;2xx&#xff09;、客户端错误&a…

第P1周:Pytorch实现mnist手写数字识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目标 1. 实现pytorch环境配置 2. 实现mnist手写数字识别 3. 自己写几个数字识别试试具体实现 &#xff08;一&#xff09;环境 语言环境&#xff1a;Python…

网络安全技术详解:虚拟专用网络(VPN) 安全信息与事件管理(SIEM)

虚拟专用网络&#xff08;VPN&#xff09;详细介绍 虚拟专用网络&#xff08;VPN&#xff09;通过在公共网络上创建加密连接来保护数据传输的安全性和隐私性。 工作原理 VPN的工作原理涉及建立安全隧道和数据加密&#xff1a; 隧道协议&#xff1a;使用协议如PPTP、L2TP/IP…

河南省的教育部科技查新工作站有哪些?

郑州大学图书馆&#xff08;Z12&#xff09;&#xff1a;2007年1月被批准设立“教育部综合类科技查新工作站”&#xff0c;同年12月被河南省科技厅认定为河南省省级科技查新机构。主要面向河南省的高校、科研机构、企业提供科技查新、查收查引等服务。 河南大学图书馆&#xf…

Leetcode经典题6--买卖股票的最佳时机

买卖股票的最佳时机 题目描述&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。…

【Pytorch】torch.reshape与torch.Tensor.reshape区别

问题引入&#xff1a; 在Pytorch文档中&#xff0c;有torch.reshape与torch.Tensor.reshape两个reshape操作&#xff0c;他们的区别是什么呢&#xff1f; 我们先来看一下官方文档的定义&#xff1a; torch.reshape&#xff1a; torch.Tensor.reshape: 解释&#xff1a; 在p…

spring6:3容器:IoC

spring6&#xff1a;3容器&#xff1a;IoC 目录 spring6&#xff1a;3容器&#xff1a;IoC3、容器&#xff1a;IoC3.1、IoC容器3.1.1、控制反转&#xff08;IoC&#xff09;3.1.2、依赖注入3.1.3、IoC容器在Spring的实现 3.2、基于XML管理Bean3.2.1、搭建子模块spring6-ioc-xml…

【认证法规】安全隔离变压器

文章目录 定义反激电源变压器 定义 安全隔离变压器&#xff08;safety isolating transformer&#xff09;&#xff0c;通过至少相当于双重绝缘或加强绝缘的绝缘使输入绕组与输出绕组在电气上分开的变压器。这种变压器是为以安全特低电压向配电电路、电器或其它设备供电而设计…

车机端同步outlook日历

最近在开发一个车机上的日历助手&#xff0c;其中一个需求就是要实现手机端日历和车机端日历数据的同步。然而这种需求似乎没办法实现&#xff0c;毕竟手机日历是手机厂商自己带的系统应用&#xff0c;根本不能和车机端实现数据同步的。 那么只能去其他公共的平台寻求一些机会&…

OpenCV-图像阈值

简单阈值法 此方法是直截了当的。如果像素值大于阈值&#xff0c;则会被赋为一个值&#xff08;可能为白色&#xff09;&#xff0c;否则会赋为另一个值&#xff08;可能为黑色&#xff09;。使用的函数是 cv.threshold。第一个参数是源图像&#xff0c;它应该是灰度图像。第二…

城电科技 | 光伏景观长廊 打造美丽乡村绿色低碳示范区 光伏景观设计方案

光伏景观长廊是一种结合了光伏发电技术和零碳景观设计的新型公共公共设施&#xff0c;光伏景观长廊顶上的光伏板不仅可以为周边用电设备提供清洁电能&#xff0c;而且还能作为遮阳设施使用&#xff0c;为人们提供一个美丽又实用的休闲娱乐空间。 光伏景观长廊建设对打造美丽乡…