python3GUI--图片浏览器By:PyQt5(附源码)


一.前言

本次使用PyQt5开发一款图片浏览器,本篇主要练习QDockWidget、QTreeWidget,软件打包好放在了文末,可自取。

二.展示

1.主界面

在这里插入图片描述

2.添加图片

点击“添加目录”后,选择目录,软件会扫描文件夹及子文件夹下的所有图片文件,最后展示到左侧的目录树中。
在这里插入图片描述

3.多级目录

支持多级目录图片展示
在这里插入图片描述

4.查看文件信息

右击文件,点击查看文件信息
在这里插入图片描述

5.调整UI布局

通过鼠标拖动QDockWidget,选择悬停位置改变UI布局。
在这里插入图片描述

三.源代码

1.image_god_main_v.py

文件主逻辑调用

import os
import re
import sys
import traceback
from PyQt5.QtCore import Qt, QFileInfo, QSize
from PyQt5.QtGui import QPixmap, QIcon, QCursor
import qtawesome

from image_god_GUI import Ui_MainWindow as mainWindow
from webbrowser import open as open_url
from PyQt5.QtWidgets import QApplication, QMainWindow, QDockWidget, QTreeWidgetItem, QFileDialog, QAbstractItemView, \
    QMenu, QFileIconProvider, QMessageBox, QAction


class ImageGod(QMainWindow, mainWindow):
    pixRatio = 1

    def __init__(self):
        super(ImageGod, self).__init__()
        self.setupUi(self)
        self.ui_init()
        self.slot_init()

    def ui_init(self):
        def icon_init():
            self.action_addDir.setIcon(qtawesome.icon("mdi.folder-open", color="#3D59AB"))
            self.action_broom.setIcon(qtawesome.icon("ei.broom", color="#DDA0DD"))
            self.action_zoomIn.setIcon(qtawesome.icon("msc.zoom-in", color="brown"))
            self.action_zoomOut.setIcon(qtawesome.icon("msc.zoom-out", color="brown"))
            self.action_zoomFit.setIcon(qtawesome.icon("mdi.restore", color="green"))
            self.action_exit.setIcon(qtawesome.icon("mdi6.exit-to-app", color="gray"))

        self.treeWidget.setColumnCount(1)
        self.treeWidget.setColumnWidth(0, 30)
        self.treeWidget.setHeaderLabels(["目录文件"])
        self.treeWidget.setIconSize(QSize(25, 25))
        self.treeWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.setCentralWidget(self.scrollArea)
        self.scrollArea.setWidgetResizable(True)
        self.action_broom.setEnabled(False)
        self.scrollArea.setAlignment(Qt.AlignCenter)
        self.label.setAlignment(Qt.AlignCenter)
        self.currPixmap = QPixmap()
        icon_init()
        self.change_action_ui(False)
        self.menu_init()

    def slot_init(self):
        self.action_addDir.triggered.connect(self.on_openDir_triggered)
        self.action_exit.triggered.connect(self.close)
        self.actionabout_author.triggered.connect(lambda: open_url("https://blog.csdn.net/a1397852386"))
        self.actionabout_qt.triggered.connect(lambda: QMessageBox.aboutQt(self, "关于QT"))
        self.action_zoomIn.triggered.connect(self.on_actionZoomIn_triggered)
        self.action_zoomOut.triggered.connect(self.on_actionZoomOut_triggered)
        self.action_zoomFit.triggered.connect(self.on_actionFid_triggered)
        self.action_broom.triggered.connect(self.clear_dirTree)
        self.actiontree.triggered.connect(lambda: self.dockWidget.setVisible(self.actiontree.isChecked()))
        # self.dockWidget.closeEvent=self.actiontree.setChecked(not self.dockWidget.isVisible())
        self.treeWidget.customContextMenuRequested.connect(self.onTreeWidgetCustomContextMenuRequested)
        self.treeWidget.itemClicked.connect(self.onTreeItemClicked)

    def menu_init(self):
        """
        treeWidget右击菜单初始化
        :return:
        """
        self.treeWidget_menu = QMenu(self.treeWidget)
        self.action_show_image = QAction(self)  # 查看图片
        self.action_show_infos = QAction(self)  # 查看文件信息
        self.action_open_image_folder = QAction(self)  # 打开所在文件夹
        self.action_show_image.setText("查看图片")
        self.action_show_infos.setText("查看文件信息")
        self.action_open_image_folder.setText("打开所在文件夹")
        self.treeWidget_menu.addActions(
            [self.action_show_image, self.action_show_infos, self.action_open_image_folder, ])

    def on_openDir_triggered(self):
        """
        打开有图片的目录
        :return:
        """

        def CreateTree(dirs, root, path):
            """
            创建目录树
            :param dirs:
            :param root:
            :param path:
            :return:
            """
            for i in dirs:
                path_new = path + '\\' + i
                if os.path.isdir(path_new):
                    fileInfo = QFileInfo(path_new)
                    child = QTreeWidgetItem(root)
                    dirs_new = os.listdir(path_new)
                    data = ""
                    if self.check_dir(path_new):  # 确定文件夹有图片文件后,再创建子节点
                        CreateTree(dirs_new, child, path_new)

                else:
                    fileInfo = QFileInfo(path_new)
                    if not self.check_file(fileInfo.suffix()): continue
                    child = QTreeWidgetItem(root)
                    data = fileInfo.absoluteFilePath()
                    # 添加其他队列
                    # child.setText(1, str(fileInfo.size()))
                    # child.setToolTip(1, str(fileInfo.size()))
                    # child.setText(2, fileInfo.suffix())
                    # child.setToolTip(2, fileInfo.suffix())
                child.setData(0, Qt.UserRole, data)
                fileIcon = QFileIconProvider()
                icon = QIcon(fileIcon.icon(fileInfo))
                child.setText(0, i)
                child.setToolTip(0, i)
                child.setIcon(0, QIcon(icon))
                child.setExpanded(False)

        path = QFileDialog.getExistingDirectory(self, "选取文件夹", "./")
        # self.treeWidget.setHeaderLabels(["目录文件", "大小", "类型", "创建时间", "上次修改时间"])
        if not path: return
        dirs = os.listdir(path)
        if self.check_dir(path, root=True):  # 确定文件夹有图片文件后,再创建子节点
            fileInfo = QFileInfo(path)
            fileIcon = QFileIconProvider()
            icon = QIcon(fileIcon.icon(fileInfo))
            fileName_root = QTreeWidgetItem(self.treeWidget)
            fileName_root.setText(0, fileInfo.fileName())
            fileName_root.setToolTip(0, fileInfo.fileName())
            fileName_root.setIcon(0, QIcon(icon))
            fileName_root.setData(0, Qt.UserRole, "")
            CreateTree(dirs, fileName_root, path)
            self.action_broom.setEnabled(True)
            QApplication.processEvents()
        else:
            QMessageBox.warning(self, "警告", "选择的目录不存在图片文件!")

    def clear_dirTree(self):
        """
        清空目录树
        :return:
        """
        self.treeWidget.clear()
        self.action_broom.setEnabled(False)
        self.label.setPixmap(QPixmap(""))
        self.change_action_ui(False)

    def onTreeItemClicked(self, item, column):
        """
        treeWidget节点被单击
        :return:
        """
        file = item.data(column, Qt.UserRole)
        self.show_image(file)

    def show_image(self, file):
        if file:
            self.pixRatio = 1  # 每次都重置为1
            self.statusbar.showMessage(file)  # 将文件名展示到状态栏
            self.currPixmap.load(file)
            self.on_zoomFitH_triggered()
            self.change_action_ui(True)

    def show_file_infos(self, file):
        """
        文件信息
        :param file:
        :return:
        """
        infos = ""
        try:
            file_obj = QFileInfo(file)
            file_name = file_obj.fileName()
            file_size = file_obj.size()
            file_suffix = file_obj.suffix()
            file_last = file_obj.lastModified().toString()
            file_create = file_obj.created().toString()
            file_ow_id = file_obj.ownerId()
            infos = "文件名:{}\n文件类型:{}\n文件大小:{}字节\n创建时间:{}\n上次修改时间:{}\nownerId:{}".format(file_name, file_suffix,
                                                                                        file_size,
                                                                                        file_create, file_last,
                                                                                        file_ow_id)
        except:
            traceback.print_exc()
        if infos:
            QMessageBox.information(self, "文件信息", infos)
        else:
            QMessageBox.warning(self, "警告", "文件未找到")

    def onTreeWidgetCustomContextMenuRequested(self, pos):
        """
        treeWidget被右击事件
        :return:
        """
        try:
            item = self.treeWidget.currentItem()
            index=self.treeWidget.indexFromItem(item,0).row()
            print("index===",index)
            column = self.treeWidget.currentColumn()
            item1 = self.treeWidget.itemAt(pos)
            file = item.data(column, Qt.UserRole)
            if item != None and item1 != None and file != "":
                try:
                    self.action_show_image.triggered.disconnect()
                    self.action_show_infos.triggered.disconnect()
                    self.action_open_image_folder.triggered.disconnect()
                except:
                    traceback.print_exc()
                print(item.text(column))
                print(file)
                self.action_show_image.triggered.connect(lambda: self.show_image(file))
                self.action_show_infos.triggered.connect(lambda: self.show_file_infos(file))
                self.action_open_image_folder.triggered.connect(lambda: os.startfile(os.path.dirname(file)))
                self.treeWidget_menu.exec_(QCursor.pos())
        except:
            traceback.print_exc()

    def on_zoomFitH_triggered(self):
        """
        自动适应高度
        :return:
        """
        height = self.scrollArea.height()
        readHeight = self.currPixmap.height()
        self.pixRatio = float(height) / readHeight
        pix = self.currPixmap.scaledToHeight(height - 30)
        self.label.setPixmap(pix)

    def on_zoomFitW_triggered(self):
        """
        自动适应宽度
        :return:
        """
        width = self.scrollArea.width()
        readHWidth = self.currPixmap.width()
        self.pixRatio = float(width) / readHWidth
        pix = self.currPixmap.scaledToWidth(width - 30)
        self.label.setPixmap(pix)

    def on_actionZoomIn_triggered(self):
        """
        放大图片
        :return:
        """
        self.pixRatio = self.pixRatio * 1.2
        width = self.pixRatio * self.currPixmap.width()
        height = self.pixRatio * self.currPixmap.height()
        pix = self.currPixmap.scaled(width, height)
        self.label.setPixmap(pix)

    def on_actionFid_triggered(self):
        """
        自适应大小
        :return:
        """
        self.pixRatio = 1
        self.label.setPixmap(self.currPixmap)

    def on_actionZoomOut_triggered(self):
        """
        放大图片
        :return:
        """
        pixRatio_tmp = self.pixRatio
        self.pixRatio = self.pixRatio * 0.8
        width = self.pixRatio * self.currPixmap.width()
        height = self.pixRatio * self.currPixmap.height()
        if width < self.scrollArea.width() and height < self.scrollArea.height():  # 避免缩小太小导致失真
            self.pixRatio = pixRatio_tmp
            return
        pix = self.currPixmap.scaled(width, height)
        self.label.setPixmap(pix)

    def closeEvent(self, event):
        reply = QMessageBox.question(self, '关闭', "确定要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    def check_dir(self, dir, root=False):
        """
        查看文件夹是否有图片文件
        :param dir:
        :return:
        """
        for file in os.listdir(dir):
            file_abs = dir + '\\' + file
            if os.path.isdir(file_abs):
                return True
            if "." in file:
                if self.check_file(file.split(".")[-1]):
                    return True
        return False

    def check_file(self, suffix):
        """
        看文件是否为图片文件
        :param suffix:
        :return:
        """
        if suffix in ['jpg', 'png', 'jpeg', 'psd', 'bmp', 'webp']:
            return True
        else:
            return False

    def change_action_ui(self, flag):
        """
        改变按钮UI状态
        :param falg:
        :return:
        """
        self.action_zoomIn.setEnabled(flag)
        self.action_zoomOut.setEnabled(flag)
        self.action_zoomFit.setEnabled(flag)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = ImageGod()
    ui.show()
    sys.exit(app.exec_())

2.image_god_GUI.py

UI文件,通过uic转化而来

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'image_god_GUI.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1107, 622)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 845, 553))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label = QtWidgets.QLabel(self.scrollAreaWidgetContents)
        self.label.setText("")
        self.label.setScaledContents(True)
        self.label.setObjectName("label")
        self.verticalLayout_2.addWidget(self.label)
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.horizontalLayout.addWidget(self.scrollArea)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1107, 23))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        self.menu_3 = QtWidgets.QMenu(self.menubar)
        self.menu_3.setObjectName("menu_3")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.dockWidget = QtWidgets.QDockWidget(MainWindow)
        self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable|QtWidgets.QDockWidget.DockWidgetMovable)
        self.dockWidget.setObjectName("dockWidget")
        self.dockWidgetContents = QtWidgets.QWidget()
        self.dockWidgetContents.setObjectName("dockWidgetContents")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.dockWidgetContents)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.treeWidget = QtWidgets.QTreeWidget(self.dockWidgetContents)
        self.treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.treeWidget.setObjectName("treeWidget")
        self.treeWidget.headerItem().setText(0, "1")
        self.verticalLayout.addWidget(self.treeWidget)
        self.dockWidget.setWidget(self.dockWidgetContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.dockWidget)
        self.toolBar = QtWidgets.QToolBar(MainWindow)
        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.toolBar.setObjectName("toolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.action_addDir = QtWidgets.QAction(MainWindow)
        self.action_addDir.setObjectName("action_addDir")
        self.action_broom = QtWidgets.QAction(MainWindow)
        self.action_broom.setObjectName("action_broom")
        self.action_zoomIn = QtWidgets.QAction(MainWindow)
        self.action_zoomIn.setObjectName("action_zoomIn")
        self.action_zoomOut = QtWidgets.QAction(MainWindow)
        self.action_zoomOut.setObjectName("action_zoomOut")
        self.action_zoomFit = QtWidgets.QAction(MainWindow)
        self.action_zoomFit.setObjectName("action_zoomFit")
        self.action_exit = QtWidgets.QAction(MainWindow)
        self.action_exit.setObjectName("action_exit")
        self.actiontree = QtWidgets.QAction(MainWindow)
        self.actiontree.setCheckable(True)
        self.actiontree.setChecked(True)
        self.actiontree.setObjectName("actiontree")
        self.actionabout_author = QtWidgets.QAction(MainWindow)
        self.actionabout_author.setObjectName("actionabout_author")
        self.actionabout_qt = QtWidgets.QAction(MainWindow)
        self.actionabout_qt.setObjectName("actionabout_qt")
        self.menu.addAction(self.action_addDir)
        self.menu.addAction(self.action_broom)
        self.menu.addAction(self.actiontree)
        self.menu.addSeparator()
        self.menu.addAction(self.action_exit)
        self.menu_2.addAction(self.action_zoomIn)
        self.menu_2.addAction(self.action_zoomOut)
        self.menu_2.addAction(self.action_zoomFit)
        self.menu_3.addAction(self.actionabout_author)
        self.menu_3.addAction(self.actionabout_qt)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())
        self.menubar.addAction(self.menu_3.menuAction())
        self.toolBar.addAction(self.action_addDir)
        self.toolBar.addAction(self.action_broom)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.action_zoomIn)
        self.toolBar.addAction(self.action_zoomOut)
        self.toolBar.addAction(self.action_zoomFit)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.action_exit)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Image_god"))
        self.menu.setTitle(_translate("MainWindow", "目录"))
        self.menu_2.setTitle(_translate("MainWindow", "视图"))
        self.menu_3.setTitle(_translate("MainWindow", "关于"))
        self.dockWidget.setWindowTitle(_translate("MainWindow", "目录树"))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
        self.action_addDir.setText(_translate("MainWindow", "添加目录"))
        self.action_addDir.setToolTip(_translate("MainWindow", "添加目录"))
        self.action_broom.setText(_translate("MainWindow", "清空目录树"))
        self.action_broom.setToolTip(_translate("MainWindow", "清空目录树"))
        self.action_zoomIn.setText(_translate("MainWindow", "放大"))
        self.action_zoomIn.setToolTip(_translate("MainWindow", "放大"))
        self.action_zoomOut.setText(_translate("MainWindow", "缩小"))
        self.action_zoomOut.setToolTip(_translate("MainWindow", "缩小"))
        self.action_zoomFit.setText(_translate("MainWindow", "原始大小"))
        self.action_zoomFit.setToolTip(_translate("MainWindow", "原始大小"))
        self.action_exit.setText(_translate("MainWindow", "退出"))
        self.action_exit.setToolTip(_translate("MainWindow", "退出"))
        self.actiontree.setText(_translate("MainWindow", "显示目录树"))
        self.actiontree.setToolTip(_translate("MainWindow", "显示目录树"))
        self.actionabout_author.setText(_translate("MainWindow", "关于作者"))
        self.actionabout_author.setToolTip(_translate("MainWindow", "关于作者"))
        self.actionabout_qt.setText(_translate("MainWindow", "关于QT"))
        self.actionabout_qt.setToolTip(_translate("MainWindow", "关于QT"))

四.总结

本次练习了PyQt5相关组件使用,制作了一款图片浏览器,可以按照目录级别预览图片,支持放大、缩小、查看信息,实现功能比较基础,整体UI风格为PyQt5原生ui风格,未使用QSS做具体细节绘制。软件打包好放在了这里,解压后大小为37.5M。希望得到大家的赞,谢谢大家!
在这里插入图片描述

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 学生宿舍管理系统是基于PythonPyQt5和MySQL开发的一个项目,旨在帮助学校高效管理学生宿舍的入住、退宿、维修等信息。下面是该项目的详细说明文档: 1. 系统功能 - 学生宿舍的入住管理:可以添加、删除、修改学生的宿舍信息,包括姓名、学号、宿舍楼号、宿舍号等内容。 - 学生宿舍的维修管理:可以记录宿舍的维修情况,包括宿舍号、维修日期、维修原因等信息,并能够查看历史维修记录。 - 学生宿舍的退宿管理:可以退宿学生,并更新宿舍的入住状态。 - 学生宿舍的查询功能:可以通过学号、宿舍楼号、宿舍号等信息,查询学生宿舍的相关信息。 2. 系统架构 - 前端界面使用PyQt5库实现,包括各个功能模块的界面设计。 - 后端数据存储使用MySQL数据库,存储学生宿舍的相关信息。 - Python作为开发语言,通过PyQt5库提供的方法与MySQL数据库进行交互。 3. 系统运行环境 - 操作系统:推荐使用Windows系统,也可以在Linux或Mac OS上运行。 - Python版本:推荐Python3.x版本。 - PyQt5安装:使用pip命令安装PyQt5库,pip install pyqt5。 - MySQL安装:安装MySQL数据库,并创建对应的数据库和表。 4. 运行方式 - 下载源码:从GitHub或其他源码托管平台下载学生宿舍管理系统的源码。 - 配置数据库:在源码中修改连接数据库的相关信息,包括MySQL的地址、用户名、密码等。 - 运行程序:通过Python命令运行主程序文件,即可启动系统界面。 - 页面操作:根据界面提供的按钮和输入框进行相应的添加、修改、删除、查询等操作。 5. 注意事项 - 由于本项目是基于PythonPyQt5开发的,需要对PythonGUI界面开发有一定的了解。 - 在使用该系统之前,需要创建对应的数据库和表,并将相关信息配置到源码中。 - 可以根据实际需要进行功能的扩展和修改,例如增加宿舍楼管理、学生信息管理等模块。 这个学生宿舍管理系统源码提供了一个简单易用的GUI界面,方便学校管理学生宿舍的各项信息,并且可以快速查询和统计宿舍相关数据,帮助学校实现宿舍管理的自动化和规范化。 ### 回答2: 学生宿舍管理系统是基于PythonPyQt5和MySQL实现的一款图形用户界面(GUI)应用程序。该系统旨在帮助学校管理学生宿舍的入住、退房和维护等事务。 系统的数据库设计如下: 1. 学生表(Student):包含学生的基本信息,如学号、姓名、性别、年龄等。 2. 宿舍楼表(DormitoryBuilding):记录宿舍楼的信息,如楼号、楼层数、可容纳人数等。 3. 宿舍房间表(DormitoryRoom):每个宿舍楼内包括多个宿舍房间,该表记录了宿舍房间的编号、所在楼号、可容纳人数等。 4. 入住记录表(CheckInRecord):记录学生的入住情况,包括入住日期、房间号、学生信息等。 系统的功能模块如下: 1. 学生管理:可以对学生的基本信息进行增加、删除、修改和查询操作。 2. 宿舍楼管理:可以对宿舍楼的信息进行增加、删除、修改和查询操作。 3. 宿舍房间管理:可以对宿舍房间的信息进行增加、删除、修改和查询操作。 4. 入住管理:可以对学生的入住情况进行登记、查询和退房操作。 5. 统计功能:可以统计宿舍楼的入住情况和宿舍房间的入住率。 系统的GUI界面采用PyQt5库进行开发,具有用户友好的操作界面,方便用户进行操作和管理。 总结起来,该学生宿舍管理系统使用Python编程语言、PyQt5图形界面库和MySQL数据库,实现了学生、宿舍楼、宿舍房间和入住记录的管理功能,方便学校对学生宿舍的管理和维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值