目录

主要功能

环境配置

实现过程

1、设计ui

主界面

弹出框

窗体文件

2、主体实现

打开文件

计算函数

代码附录

title.ui

titleok.ui

title.py

titleok.py

main多线程运算分块.py

主要功能

1、打开文件夹,读取tif文件列表,填入数据列表框

2、多线程对所有tif文件分块处理,防止阻塞窗体

3、更新进度条

环境配置

主要版本如下:

python 3.9.7

PyQt5 5.15.6

GDAL 3.4.1

numpy 1.22.3

pandas 1.4.2

较为详细的环境配置:【Python笔记】pyqt5窗体程序制作流程

实现过程

以下主要叙述流程和关键技术点,设计部分具体过程参照:【Python笔记】pyqt5窗体程序制作流程

1、设计ui

主界面

创建一个QMainWindow,添加组件 标签QLabel、文本框LineList、数据列表框QListWeight、菜单QMenu、按钮QPushButton等,保存为

弹出框

创建一个Dialog,添加组件 进度条QProgressBar

窗体文件

分别保存title.ui、titleok.ui文件,使用拓展工具转化为对应的py文件 ,完整ui、py文件代码见代码附录

2、主体实现

打开文件

设置全局变量-字典self.maindata={},打开文件夹,将文件夹路径赋给全局字典,同时获取文件夹内的所有后缀为.tif文件列表,加入数据列表框,给数据列表框添加点击事件itemClick

    def wenjianjia(self):if not os.path.exists(r"E:\pyimg\tif2csv"):self.maindata["tifDir"] = QFileDialog.getExistingDirectory(None, "选取文件夹", "C:/")  # 返回选中的文件夹路径else:self.maindata["tifDir"] = QFileDialog.getExistingDirectory(None, "选取文件夹", "E:\\pyimg\\tif2csv")  # 返回选中的文件夹路径# self.maindata["tifDir"]=QFileDialog.getExistingDirectory(None,"选取文件夹","E:/")  # 返回选中的文件夹路径print(self.maindata)self.maindata["tifs"] = [i for i in os.listdir(self.maindata["tifDir"]) if i.endswith(".tif")]# 数据列表框添加内容for img in self.maindata["tifs"]:self.listWidget.addItem(str(img))#数据列表框添加点击事件def itemClick(self, item):print(item.text() + " clicked!")QMessageBox.information(self, "ListWidget", "你选择了:" + item.text())

计算函数

多线程弹出子界面,同时开启子线程传入相关参数进行分块处理,此处略过分块代码,子线程定义信号_signal传回数据更新进度条,进度条到达100时显示完成按钮,完整代码“main多线程运算分块.py”见代码附录

#计算函数def start_cacu(self):#子窗体self.child = childWindow()self.child.pushButton.setVisible(False)self.child.show()self.maindata["分块大小"]=self.lineEdit.text()# 创建线程self.thread = Runthread(self.maindata)# 连接信号self.thread._signal.connect(self.call_backlog)  # 进程连接回传到GUI的事件self.child.stop_thread.connect(self.thread.terminate)# 开始线程self.thread.start()# 将线程的参数传入进度条事件def call_backlog(self, msg):self.child.progressBar.setValue(int(msg))if(msg==100):self.child.pushButton.setVisible(True)
# 多线程
class Runthread(QtCore.QThread):#  通过类成员对象定义信号对象_signal = pyqtSignal(int)def __init__(self,main):super(Runthread, self).__init__()self.main=main
#计算函数def run(self):# 分块处理代码print(self.main)

代码附录

title.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>tile</class><widget class="QMainWindow" name="tile"><property name="geometry"><rect><x>0</x><y>0</y><width>472</width><height>279</height></rect></property><property name="windowTitle"><string>分块</string></property><widget class="QWidget" name="centralwidget"><widget class="QListWidget" name="listWidget"><property name="geometry"><rect><x>10</x><y>20</y><width>311</width><height>211</height></rect></property><property name="layoutDirection"><enum>Qt::LeftToRight</enum></property></widget><widget class="QLabel" name="label"><property name="geometry"><rect><x>330</x><y>130</y><width>54</width><height>20</height></rect></property><property name="text"><string>分块大小:</string></property></widget><widget class="QPushButton" name="pushButton"><property name="geometry"><rect><x>390</x><y>210</y><width>71</width><height>23</height></rect></property><property name="text"><string>分块</string></property></widget><widget class="QLineEdit" name="lineEdit"><property name="geometry"><rect><x>390</x><y>130</y><width>71</width><height>20</height></rect></property><property name="text"><string>256</string></property><property name="dragEnabled"><bool>false</bool></property><property name="placeholderText"><string>256</string></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>330</x><y>160</y><width>54</width><height>12</height></rect></property><property name="text"><string>输出路径:</string></property></widget><widget class="QLabel" name="label_3"><property name="geometry"><rect><x>10</x><y>0</y><width>54</width><height>16</height></rect></property><property name="text"><string>影像列表:</string></property></widget><widget class="QLineEdit" name="lineEdit_2"><property name="geometry"><rect><x>330</x><y>180</y><width>131</width><height>20</height></rect></property><property name="font"><font><family>Adobe Devanagari</family><pointsize>9</pointsize></font></property></widget></widget><widget class="QMenuBar" name="menubar"><property name="geometry"><rect><x>0</x><y>0</y><width>472</width><height>23</height></rect></property><widget class="QMenu" name="menu"><property name="title"><string>文件</string></property><addaction name="actiondakai"/><addaction name="actionda"/></widget><addaction name="menu"/></widget><widget class="QStatusBar" name="statusbar"/><action name="actionda"><property name="text"><string>打开文件夹</string></property></action><action name="actiondakai"><property name="checkable"><bool>false</bool></property><property name="text"><string>打开文件</string></property><property name="font"><font><family>Adobe Devanagari</family><pointsize>10</pointsize></font></property><property name="menuRole"><enum>QAction::TextHeuristicRole</enum></property><property name="priority"><enum>QAction::NormalPriority</enum></property></action></widget><resources/><connections/>
</ui>

titleok.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Dialog</class><widget class="QDialog" name="Dialog"><property name="geometry"><rect><x>0</x><y>0</y><width>423</width><height>150</height></rect></property><property name="windowTitle"><string>分块</string></property><widget class="QProgressBar" name="progressBar"><property name="geometry"><rect><x>120</x><y>30</y><width>261</width><height>23</height></rect></property><property name="value"><number>0</number></property></widget><widget class="QLabel" name="label"><property name="geometry"><rect><x>30</x><y>30</y><width>54</width><height>12</height></rect></property><property name="text"><string>正在处理:</string></property></widget><widget class="QPushButton" name="pushButton"><property name="geometry"><rect><x>250</x><y>110</y><width>75</width><height>23</height></rect></property><property name="text"><string>完成</string></property></widget><widget class="QPushButton" name="pushButton_2"><property name="geometry"><rect><x>330</x><y>110</y><width>75</width><height>23</height></rect></property><property name="text"><string>取消</string></property></widget></widget><resources/><connections/>
</ui>

title.py

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'title.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, QtWidgetsclass Ui_tile(object):def setupUi(self, tile):tile.setObjectName("tile")tile.resize(472, 279)self.centralwidget = QtWidgets.QWidget(tile)self.centralwidget.setObjectName("centralwidget")self.listWidget = QtWidgets.QListWidget(self.centralwidget)self.listWidget.setGeometry(QtCore.QRect(10, 20, 311, 211))self.listWidget.setLayoutDirection(QtCore.Qt.LeftToRight)self.listWidget.setObjectName("listWidget")self.label = QtWidgets.QLabel(self.centralwidget)self.label.setGeometry(QtCore.QRect(330, 130, 54, 20))self.label.setObjectName("label")self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setGeometry(QtCore.QRect(390, 210, 71, 23))self.pushButton.setObjectName("pushButton")self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)self.lineEdit.setGeometry(QtCore.QRect(390, 130, 71, 20))self.lineEdit.setDragEnabled(False)self.lineEdit.setObjectName("lineEdit")self.label_2 = QtWidgets.QLabel(self.centralwidget)self.label_2.setGeometry(QtCore.QRect(330, 160, 54, 12))self.label_2.setObjectName("label_2")self.label_3 = QtWidgets.QLabel(self.centralwidget)self.label_3.setGeometry(QtCore.QRect(10, 0, 54, 16))self.label_3.setObjectName("label_3")self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)self.lineEdit_2.setGeometry(QtCore.QRect(330, 180, 131, 20))font = QtGui.QFont()font.setFamily("Adobe Devanagari")font.setPointSize(9)self.lineEdit_2.setFont(font)self.lineEdit_2.setObjectName("lineEdit_2")tile.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(tile)self.menubar.setGeometry(QtCore.QRect(0, 0, 472, 23))self.menubar.setObjectName("menubar")self.menu = QtWidgets.QMenu(self.menubar)self.menu.setObjectName("menu")tile.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(tile)self.statusbar.setObjectName("statusbar")tile.setStatusBar(self.statusbar)self.actionda = QtWidgets.QAction(tile)self.actionda.setObjectName("actionda")self.actiondakai = QtWidgets.QAction(tile)self.actiondakai.setCheckable(False)font = QtGui.QFont()font.setFamily("Adobe Devanagari")font.setPointSize(10)self.actiondakai.setFont(font)self.actiondakai.setMenuRole(QtWidgets.QAction.TextHeuristicRole)self.actiondakai.setPriority(QtWidgets.QAction.NormalPriority)self.actiondakai.setObjectName("actiondakai")self.menu.addAction(self.actiondakai)self.menu.addAction(self.actionda)self.menubar.addAction(self.menu.menuAction())self.retranslateUi(tile)QtCore.QMetaObject.connectSlotsByName(tile)def retranslateUi(self, tile):_translate = QtCore.QCoreApplication.translatetile.setWindowTitle(_translate("tile", "分块"))self.label.setText(_translate("tile", "分块大小:"))self.pushButton.setText(_translate("tile", "分块"))self.lineEdit.setText(_translate("tile", "256"))self.lineEdit.setPlaceholderText(_translate("tile", "256"))self.label_2.setText(_translate("tile", "输出路径:"))self.label_3.setText(_translate("tile", "影像列表:"))self.menu.setTitle(_translate("tile", "文件"))self.actionda.setText(_translate("tile", "打开文件夹"))self.actiondakai.setText(_translate("tile", "打开文件"))

titleok.py

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'titleok.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, QtWidgetsclass Ui_Dialog(object):def setupUi(self, Dialog):Dialog.setObjectName("Dialog")Dialog.resize(423, 150)self.progressBar = QtWidgets.QProgressBar(Dialog)self.progressBar.setGeometry(QtCore.QRect(120, 30, 261, 23))self.progressBar.setProperty("value", 0)self.progressBar.setObjectName("progressBar")self.label = QtWidgets.QLabel(Dialog)self.label.setGeometry(QtCore.QRect(30, 30, 54, 12))self.label.setObjectName("label")self.pushButton = QtWidgets.QPushButton(Dialog)self.pushButton.setGeometry(QtCore.QRect(250, 110, 75, 23))self.pushButton.setObjectName("pushButton")self.pushButton_2 = QtWidgets.QPushButton(Dialog)self.pushButton_2.setGeometry(QtCore.QRect(330, 110, 75, 23))self.pushButton_2.setObjectName("pushButton_2")self.retranslateUi(Dialog)QtCore.QMetaObject.connectSlotsByName(Dialog)def retranslateUi(self, Dialog):_translate = QtCore.QCoreApplication.translateDialog.setWindowTitle(_translate("Dialog", "分块"))self.label.setText(_translate("Dialog", "正在处理:"))self.pushButton.setText(_translate("Dialog", "完成"))self.pushButton_2.setText(_translate("Dialog", "取消"))

main多线程运算分块.py

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QIcon
from title import *
from titleok import *
from osgeo import gdal
import os# 多线程
class Runthread(QtCore.QThread):#  通过类成员对象定义信号对象_signal = pyqtSignal(int)def __init__(self,main):super(Runthread, self).__init__()self.main=main
#计算函数def run(self):# 分块影像所在文件夹,不能有中文print(self.main)tifDir = self.main["tifDir"]# 输出的文件夹,不能有中文,如果文件夹不存在则会被创建outPath =self.main["outPath"]if not os.path.exists(outPath):os.makedirs(outPath)tifs = [i for i in os.listdir(tifDir) if i.endswith(".tif")]print("有 %s 个tif文件" % len(tifs))print("tifs", tifs)datelist1 = []for i in tifs:datelist1.append(i[:-4])datelist = list(set(datelist1))datelist.sort(key=datelist1.index)print("有 %s 个日期" % len(datelist))print("datelist", datelist)# 定义切图的大小(矩形框)size = 256# len(datelist)for img in range(3):print("正在分割:", tifs[img])in_ds = gdal.Open(tifDir + "\\" + tifs[img])  # 读取要切的原图width = in_ds.RasterXSize  # 获取数据宽度height = in_ds.RasterYSize  # 获取数据高度outbandsize = in_ds.RasterCount  # 获取数据波段数im_geotrans = in_ds.GetGeoTransform()  # 获取仿射矩阵信息im_proj = in_ds.GetProjection()  # 获取投影信息datatype = in_ds.GetRasterBand(1).DataTypeim_data = in_ds.ReadAsArray()  # 获取数据col_num = int(width / size)  # 宽度可以分成几块row_num = int(height / size)  # 高度可以分成几块if (width % size != 0):col_num += 1if (height % size != 0):row_num += 1# print("row_num:%d   col_num:%d" % (row_num, col_num))for i in range(row_num):  # 从高度下手!!! 可以分成几块!for j in range(col_num):offset_x = i * sizeoffset_y = j * size## 从每个波段中切需要的矩形框内的数据(注意读取的矩形框不能超过原图大小)b_ysize = min(width - offset_y, size)b_xsize = min(height - offset_x, size)# print("width:%d     height:%d    offset_x:%d    offset_y:%d     b_xsize:%d     b_ysize:%d" % (width, height, offset_x, offset_y, b_xsize, b_ysize))# print(im_data.shape)out_allband = im_data[:, offset_x:offset_x + b_xsize, offset_y:offset_y + b_ysize]# print(out_allband.shape)# 获取Tif的驱动,为创建切出来的图文件做准备gtif_driver = gdal.GetDriverByName("GTiff")file = outPath + "\\" + tifs[img][:-4] + "-" + str(offset_x).zfill(10) + "-" + str(offset_y).zfill(10) + ".tif"# 创建切出来的要存的文件out_ds = gtif_driver.Create(file, b_ysize, b_xsize, outbandsize, datatype)# print("create new tif file succeed")# 获取原图的原点坐标信息ori_transform = in_ds.GetGeoTransform()# if ori_transform:# print(ori_transform)# print("Origin = ({}, {})".format(ori_transform[0], ori_transform[3]))# print("Pixel Size = ({}, {})".format(ori_transform[1], ori_transform[5]))# 读取原图仿射变换参数值top_left_x = ori_transform[0]  # 左上角x坐标w_e_pixel_resolution = ori_transform[1]  # 东西方向像素分辨率top_left_y = ori_transform[3]  # 左上角y坐标n_s_pixel_resolution = ori_transform[5]  # 南北方向像素分辨率# 根据反射变换参数计算新图的原点坐标top_left_x = top_left_x + offset_y * w_e_pixel_resolutiontop_left_y = top_left_y + offset_x * n_s_pixel_resolution# 将计算后的值组装为一个元组,以方便设置dst_transform = (top_left_x, ori_transform[1], ori_transform[2], top_left_y, ori_transform[4], ori_transform[5])# 设置裁剪出来图的原点坐标out_ds.SetGeoTransform(dst_transform)# 设置SRS属性(投影信息)out_ds.SetProjection(in_ds.GetProjection())# 写入目标文件for ii in range(outbandsize):out_ds.GetRasterBand(ii + 1).WriteArray(out_allband[ii])# 将缓存写入磁盘out_ds.FlushCache()# print("FlushCache succeed")del out_ds# print(i/row_num)# self.progressBar.setValue(int(100*(i+1)/row_num))# self._signal.emit(int(100*(i+1)/row_num))  # 注意这里与_signal = pyqtSignal(str)中的类型相同self._signal.emit(int(100 * (img/3+(i + 1) / (row_num*3))) ) # 注意这里与_signal = pyqtSignal(str)中的类型相同class MyWindow(QtWidgets.QMainWindow, Ui_tile):def __init__(self):super(MyWindow, self).__init__()self.setupUi(self)self.maindata={}#绑定事件self.pushButton.clicked.connect(self.start_cacu)#打开文件夹self.menu.triggered[QAction].connect(self.wenjianjia)#选择文件夹act = QAction(self)  # 定义一个行为act.setIcon(QIcon('image/select.png'))  # 设置行为icon,act.triggered.connect(self.outdir)  # 绑定行为槽函数,这里槽函数为一个QMessageBox信息弹窗self.lineEdit_2.addAction(act, QLineEdit.TrailingPosition)  # 将该行为添加到lineEdit最右端# 数据列表添加点击事件self.listWidget.itemClicked.connect(self.itemClick)def outdir(self):if not os.path.exists(r"E:\pyimg\tif2csv"):self.maindata["outPath"] = QFileDialog.getExistingDirectory(None, "输出文件夹", "C:/")  # 返回选中的文件夹路径# QFileDialog.getOpenFileName()  # 返回选中的文件路径# QFileDialog.getOpenFileNames()  # 返回选中的多个文件路径# QFileDialog.getSaveFileName()  # 存储文件else:self.maindata["outPath"] = QFileDialog.getExistingDirectory(None, "输出文件夹", "E:\\pyimg\\tif2csv")  # 返回选中的文件夹路径self.lineEdit_2.setText((QtCore.QCoreApplication.translate("tile", self.maindata["outPath"])))print(self.maindata)def wenjianjia(self):if not os.path.exists(r"E:\pyimg\tif2csv"):self.maindata["tifDir"] = QFileDialog.getExistingDirectory(None, "选取文件夹", "C:/")  # 返回选中的文件夹路径else:self.maindata["tifDir"] = QFileDialog.getExistingDirectory(None, "选取文件夹", "E:\\pyimg\\tif2csv")  # 返回选中的文件夹路径# self.maindata["tifDir"]=QFileDialog.getExistingDirectory(None,"选取文件夹","E:/")  # 返回选中的文件夹路径print(self.maindata)self.maindata["tifs"] = [i for i in os.listdir(self.maindata["tifDir"]) if i.endswith(".tif")]# 数据列表框添加内容for img in self.maindata["tifs"]:self.listWidget.addItem(str(img))#数据列表框添加点击事件def itemClick(self, item):print(item.text() + " clicked!")QMessageBox.information(self, "ListWidget", "你选择了:" + item.text())#计算函数def start_cacu(self):#子窗体self.child = childWindow()self.child.pushButton.setVisible(False)self.child.show()self.maindata["分块大小"]=self.lineEdit.text()# 创建线程self.thread = Runthread(self.maindata)# 连接信号self.thread._signal.connect(self.call_backlog)  # 进程连接回传到GUI的事件self.child.stop_thread.connect(self.thread.terminate)# 开始线程self.thread.start()# 将线程的参数传入进度条事件def call_backlog(self, msg):self.child.progressBar.setValue(int(msg))if(msg==100):self.child.pushButton.setVisible(True)# 重写closeEvent方法,关闭窗口时触发def closeEvent(self, QCloseEvent):reply = QtWidgets.QMessageBox.question(self, '分块程序', "是否要退出程序?",QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,QtWidgets.QMessageBox.No)if reply == QtWidgets.QMessageBox.Yes:QCloseEvent.accept()else:QCloseEvent.ignore()class childWindow(QDialog,Ui_Dialog):stop_thread = pyqtSignal()  # 定义关闭子线程的信号def __init__(self):super(childWindow, self).__init__()self.setupUi(self)# self.pushButton.clicked.connect(self.btn1)self.pushButton.clicked.connect(self.accept)self.pushButton_2.clicked.connect(self.accept)#窗口关闭就关闭线程def closeEvent(self, event):self.stop_thread.emit()if __name__ == '__main__':app = QtWidgets.QApplication(sys.argv)myWin = MyWindow()myWin.show()sys.exit(app.exec_())

【Python笔记】pyqt5进度条-多线程图像分块处理防止窗体卡顿相关推荐

  1. 安卓第三天笔记--通知-进度条-时期

    安卓第三天笔记--通知-进度条-时期 1.通知Notification 通知就是在是上方的状态栏弹出通知消息 <RelativeLayout xmlns:android="http:/ ...

  2. Python展示文件下载进度条

    Python展示文件下载进度条 前言 requests 思考 只需要安装一个库即可 大家好!我是晨晨

  3. Python progress - 文本进度条

    Python progress - 文本进度条 https://pypi.org/project/progress/ https://github.com/verigak/progress Proje ...

  4. Python 命令行进度条

    python 命令行进度条 实现简单的命令行进度条功能, 同时可以在进度条前后显示信息 github:https://github.com/Att100/ProgressBar-python PS:如 ...

  5. python进度条 pyqt_Python高级进阶#015 pyqt5进度条QProgressBar结合使用qbasictimer

    本期GUI界面,我们继续学习新的控件Qprogressbar. 知识回顾 1.滑动控件qslider 控件设置的关键:设置最大值.最小值,绝对范围. 2.核心类库QtCore,枚举类Qt 核心枚举类的 ...

  6. python图形化进度条代码_Python实现进度条和时间预估的示例代码

    一.前言 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识. 那么针对这三类人,我 ...

  7. python进度条先慢后快_tqdm学习-一个快速,可扩展的Python和CLI进度条

    参考:https://pypi.org/project/tqdm/ 1.安装: (base) userdeMacBook-Pro:~user$ conda activate deeplearning ...

  8. PyQt5 --- 进度条拖动点击视频播放

    最近学习pyqt5,做一个视频播放器,网上找了很多资料都没有关于python方面的视频进度条拖动点击的方法,几乎都是Qt的.对相关资料的查阅,发现开发过程其实差不多,为此做一下相关的总结. 一.UI的 ...

  9. 6行Python代码实现进度条效果(Progress、tqdm、alive-progress​​​​​​​和PySimpleGUI库)

    目录 1.Progress库 2.tqdm库 3.alive-progress库 4.PySimpleGUI库 在项目开发过程中加载.启动.下载项目难免会用到进度条,如何使用Python实现进度条呢? ...

最新文章

  1. request获取网页单选框的值
  2. 数字通信介绍(5)什么是MIMO?
  3. SAP云平台CloudFoundry环境里新建SAP UI5应用后,自动生成了哪些组件
  4. jzoj5057-[GDSOI2017模拟4.13]炮塔【网络流,最大权闭合图】
  5. 深度学习logit是什么?
  6. 图文并茂,带你梳理一下 OAuth2.0 概念和授权流程机制
  7. Python模块:配置文件解析器configparser
  8. 新建连接mysql编码选择_redhat5.432位安装mysql5.6.17数据库及创建数据库实例、配置编码...
  9. IDEA自带的数据库连接工具连接(DM)达梦数据库
  10. 微信外卖点餐系统开发教程
  11. 安卓手机Mqtt调试工具 ESP8266 mqtt服务器
  12. 第一篇博客--随便聊聊
  13. SP-API 修改货件api-修改货件sku个数坑分享
  14. matlab数据归一化(补充),matlab数据归一化(补充)
  15. 堡垒机的作用与选型经验
  16. 常用的电子邮箱排名,tom163.net收费邮箱介绍大全!
  17. 邮件代发、国外邮件代发、外贸邮件代发平台,送达率、打开率高的秘密
  18. Android多线程编程(一)- 线程基础
  19. 常见APP攻击方法 以及防御方法介绍(移动安全)
  20. HWiNFO32无法加载

热门文章

  1. SQL零基础入门学习(四)
  2. 做自媒体短视频,最简单的赚钱方法,就是做流量收益
  3. 考虑单用户计算机上的下列I O操作,操作系统概论自考2016年10月真题
  4. 抽水马桶工作原理演示
  5. 【第4章】网络安全体系与网络安全模型(信息安全工程师)
  6. 董卫凤:不服输的华丽转身(二)
  7. 在PyCharm中大型数据集indexing...加载缓慢的问题
  8. MX_Player_Pro_专业精简版AC3/DTS/EAC3 By.SOLDIER-就要应用网91apps.cn
  9. 编译go文件时内部包引用受限的问题(use of internal package /PATH/ not allowed)
  10. imageView图片放大缩小及旋转