pyqt5 自定义控件_PyQt5学习笔记(十六)Pyinstaller打包与SQLite数据库

终于到了最后一章了QAQ,第一次写4万字以上的笔记分享,最近也在忙科创和CV的比赛,所以笔记会显得比较粗糙。其实吧分享这个笔记很大一部分是为了让自己记得更牢,网上翻阅自己的笔记也方便,如果有讲解注释不清楚的地方欢迎评论留言(秋梨膏)。当然本蒟蒻也会时不时地在以后的时间更新完善这些已经完成的笔记。

以下内容涉及到SQLite数据库和requests爬虫库的使用,有时间我也会做相关方面的笔记哒(`・ω・´)。以下只是初步使用。


使用Pyinstaller打包PyQt5应用

Pyinstaller部分同学想必用过,这是一个在命令行下使用的、将脚本代码转成可执行文件的python第三方库。如果想要使得我们做出来的GUI脱离于python解释器而让操作系统直接执行的话,我们可以使用Pyinstaller库来封装我们的GUI的脚本程序。这样不同python、没有python依赖库的用户也可以方便运行程序。

这里直接讲windows下可行的方法,安装完pyinstaller后,打开命令行,一路cd到需要打包的python文件的目录下。或者也可以在需要打包的python文件的目录下按住“Shift”+鼠标右键,打开“PowerShell“

5de1555c49a32b8f6b57ef7b9dfd8d34.png

点开后,就会有和windows的命令行几乎一样的页面。

下面我们对draft.py文件打包生成可执行文件,那么只要输入以下指令:

pyinstaller -Fw "draft.py"

16d242d3d6a5366a9edcfebe8634e0ca.png

打开目录,你会发现多了两个文件夹builddist,打开dist文件夹,里面就是可以直接运行的可执行文件了:

1d6b80270177ba284b65f898e44bcfa5.png

如果要修改图标,比如要给文件“SevenDigitDrawV2.py“附上”curve.ico“的图标,则输入命令:

pyinstaller -i curve.ico -Fw "draft.py"

需要说明的是,打包完的可执行文件会很大(笔者的这个小小的画板exe就有37MB),这是因为它将所有python的依赖库都包括进去了,即你装的第三方库越多,打包出来的文件越大。


操作SQLite数据库

许多桌面应用都有访问本地数据库或者远程数据库的需求,下面就讲讲其中的一种SQLite。SQLite是一种轻量级的跨平台数据库,因此很常用。

PyQt5中提供了操控SQLite数据库的API。

  • QSqlDatabase.addDatabase():创建一个通用数据库,参数填入“QSQLITE”表示创建SQLite数据库

我们现在python文件的目录下创建一个文件夹"db"。

import sys
from PyQt5.QtSql import *
​
def createDB():# 创建一个通用数据库对象,参数"QSQLITE"代表通用数据库为SQLite数据库类型db = QSqlDatabase.addDatabase("QSQLITE")# 指定SQLite数据库的文件名db.setDatabaseName("./db/database.db")if not db.open():print("无法建立与数据库的连接")return False# 创建查询功能query = QSqlQuery()# 执行创建表格的指令query.exec('create table people(id int primary key,name varchar(10),address varchar(50))')# 执行往表格中插入数据的指令query.exec('insert into people values(1, "Kirigaya", "GitHub")')db.close()return True
​
if __name__ == '__main__':createDB()

通过DB Browser for SQLite打开"./db/database.db",点击"Browser Data"浏览数据:

9c3cc06d78992cbab7a30c25e2220871.png
我们创建的表格和数据条已经在里面了

建议使用DB Browser for SQLite来打开数据库进行操作,网上可以下载到。


通过可视化的方式对SQLite数据库进行增、删、改、查操作

此处我们使用之前讲过的QTableView控件来展示二维数据。之前你可能会觉得QTableView控件不常用,因为与QTableWidget相比,QTableView需要创建一个model,设置模型代表的表格的尺寸、属性,再在模型上添加数据,再将model与view关联,最后将view作为控件添加到窗口上才能显示出我们model代表的表格的样式与数据,看起来比较繁琐,没有QTableWidget那样直观和方便。

但是当我们想将数据库中的数据在GUI上可视化时,QTableView就变得很常用了,因为

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
​
def initializeModel(model):# 设置表格名称model.setTable("people")# 设置编辑策略model.setEditStrategy(QSqlTableModel.OnFieldChange)# 调用select方法model.select()# 设置表格头model.setHeaderData(0, Qt.Horizontal, "ID")model.setHeaderData(1, Qt.Horizontal, "姓名")model.setHeaderData(2, Qt.Horizontal, "地址")
​
def createView(title, model):view = QTableView()view.setModel(model)view.setWindowTitle(title)return view
​
def findrow(i):delrow = i.row()print("选中第{}行".format(delrow))
​
def addrow():# 在model.rowCount()行后插入1行,并返回插入的行所在行数ret = model.insertRows(model.rowCount(), 1)print("添加第{}行".format(ret))
​
if __name__ == '__main__':app = QApplication(sys.argv)db = QSqlDatabase.addDatabase("QSQLITE")# 设置数据库名字(路径)db.setDatabaseName("./db/database.db")
​# 创建一个数据库的表格模型,QSqlTableModel()会自动关联到db上model = QSqlTableModel()delrow = -1# 初始化这个表格模型(函数在上面)initializeModel(model)
​# 根据model创建QTableView对象view = createView("展示数据", model)view.clicked.connect(findrow)
​window = QDialog()layout = QVBoxLayout()layout.addWidget(view)addBtn = QPushButton("添加一行")addBtn.clicked.connect(addrow)
​delBtn = QPushButton("删除一行")# 下面view.currentIndex().row()表示view中被选中的单元格对象所在行数delBtn.clicked.connect(lambda : model.removeRow(view.currentIndex().row()))
​layout.addWidget(addBtn)layout.addWidget(delBtn)window.setLayout(layout)
​window.setWindowTitle("Database Demo")window.resize(550, 400)window.show()
​sys.exit(app.exec_())

运行效果:

483af8756dd99a5de922e02231ddb85a.png
因为数据库路径设置的是我们之前创建的数据库,所以一打开就已经有数据了

分页显示数据

如果数据量很大,那么看起来会很不方便,一页上只能显示几条数据。事实上,不仅是在GUI中,许多网页也会有这种效果:

8e418c5075ee589c4b6563f47b66490d.png

通过两个按钮控件“前一页”和“后一页”和一个QLineEdit控件可供任意页面的跳转,用户就可以在有限的UI中浏览整个数据库中对的数据(emm,事实上,这不就是一般数据库的基本功能吗?)

下面,我们完成这个实例。

我们先将整个窗口的布局和控件设置一下:

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
​
class DataGrid(QWidget):def __init__(self):super().__init__()self.setWindowTitle("分页查询例子")self.resize(820, 420)self.initUI()
​def initUI(self):# 创建窗口(自定义方法)self.createWindow()
​
​# 添加窗口上的控件和布局def createWindow(self):# 添加相关的布局与控件hbox1 = QHBoxLayout()# 向前翻页的按钮self.prevButton = QPushButton("前一页")# 向后翻页的按钮self.nextButton = QPushButton("后一页")# 直接跳转到指定页数的按钮和输入想要跳转至的页数的输入框self.switchPageButton = QPushButton("Go")self.switchPageLineEdit = QLineEdit()self.switchPageLineEdit.setFixedWidth(40)
​switchPage = QLabel("转到第")page = QLabel("页")
​# 添加我们的控件hbox1.addWidget(self.prevButton)hbox1.addWidget(self.nextButton)hbox1.addWidget(switchPage)hbox1.addWidget(self.switchPageLineEdit)hbox1.addWidget(page)hbox1.addWidget(self.switchPageButton)# 通过添加间隔控件使得上面的控件全部被挤到左边去hbox1.addWidget(QSplitter())
​# 下面这个布局置于最底端,当做当前页面的状态hbox2 = QHBoxLayout()# 创建显示总也是的labelself.totalPageLabel = QLabel()self.totalPageLabel.setFixedWidth(70)# 创建显示当前页数的labelself.currentPageLabel = QLabel()self.currentPageLabel.setFixedWidth(100)# 创建显示总记录数的labelself.totalRecordLabel = QLabel()self.totalRecordLabel.setFixedWidth(70)
​hbox2.addWidget(self.totalPageLabel)hbox2.addWidget(self.currentPageLabel)# 通过添加间隔控件使得上面的控件(totalPageLabel和currentPageLabel)在左边,下面的控件(totalRecordLabel)在右边hbox2.addWidget(QSplitter())hbox2.addWidget(self.totalRecordLabel)
​# 设置表格属性self.tabelView = QTableView()# 表格宽度自适应调整self.tabelView.resizeRowsToContents()self.tabelView.resizeColumnsToContents()
​# 创建主布局,并将hbox1,表格和hbox2装入mainLayout = QVBoxLayout(self)mainLayout.addLayout(hbox1)mainLayout.addWidget(self.tabelView)mainLayout.addLayout(hbox2)self.setLayout(mainLayout)if __name__ == '__main__':app = QApplication(sys.argv)main = DataGrid()main.show()sys.exit(app.exec_())

运行效果:

7b7c5e7598eede5801fd107a6f19e003.png

然后我们手动创建26条数据,并且设置查询模型和QTableView控件,并将查询模型和QTableView控件关联起来,就可以在中间空白区域显示数据了。

完成了布局和控件之后,我们还需要为控件添加槽函数,一通操作后,总体的代码如下(有点杂,不好写,所以我就将注释全部打在上面了(`・ω・´))

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
​
class DataGrid(QWidget):def __init__(self):super().__init__()self.setWindowTitle("分页查询例子")self.resize(820, 420)# 手动创建表格与数据(自定义方法)self.createTableAndInit()
​# 当前页self.currentPage = 0# 总页数self.totalPage = 0# 总记录数self.totalRecordCount = 0# 每页显示的记录数self.PageRecordCount = 6
​self.initUI()
​def initUI(self):# 创建窗口(自定义方法)self.createWindow()# 设置表格(自定义方法)self.setTableView()
​
​# 创建一个SQLite数据库对象,并打开指定路径上的数据库文件def createTableAndInit(self):self.db = QSqlDatabase.addDatabase("QSQLITE")self.db.setDatabaseName("./db/database.db")if not self.db.open():return False
​# 申明数据库的查询对象query = QSqlQuery()# 创建表query.exec("create table student(id int primary key, name vchar, sex vchar, age int, major vchar)")# 手动添加记录(嫌累也可以在数据库查询中添加)query.exec("insert into student values(1, 'AA', '男', 20, '计算机')")query.exec("insert into student values(2, 'AB', '女', 20, '计算机')")query.exec("insert into student values(3, 'AC', '男', 20, '计算机')")query.exec("insert into student values(4, 'AD', '女', 20, '计算机')")query.exec("insert into student values(5, 'AE', '男', 20, '计算机')")query.exec("insert into student values(6, 'AF', '女', 20, '计算机')")query.exec("insert into student values(7, 'AG', '男', 20, '计算机')")query.exec("insert into student values(8, 'AH', '女', 20, '计算机')")query.exec("insert into student values(9, 'AI', '男', 20, '计算机')")query.exec("insert into student values(10, 'AJ', '女', 20, '计算机')")query.exec("insert into student values(11, 'AK', '男', 20, '计算机')")query.exec("insert into student values(12, 'AL', '女', 20, '计算机')")query.exec("insert into student values(13, 'AM', '男', 20, '计算机')")query.exec("insert into student values(14, 'AN', '女', 20, '计算机')")query.exec("insert into student values(15, 'AO', '男', 20, '计算机')")query.exec("insert into student values(16, 'AP', '女', 20, '计算机')")query.exec("insert into student values(17, 'AQ', '男', 20, '计算机')")query.exec("insert into student values(18, 'AR', '女', 20, '计算机')")query.exec("insert into student values(19, 'AS', '男', 20, '计算机')")query.exec("insert into student values(20, 'AT', '女', 20, '计算机')")query.exec("insert into student values(21, 'AU', '男', 20, '计算机')")query.exec("insert into student values(22, 'AV', '女', 20, '计算机')")query.exec("insert into student values(23, 'AW', '男', 20, '计算机')")query.exec("insert into student values(24, 'AX', '女', 20, '计算机')")query.exec("insert into student values(25, 'AY', '男', 20, '计算机')")query.exec("insert into student values(26, 'Az', '女', 20, '计算机')")
​return True
​# 添加窗口上的控件和布局def createWindow(self):# 添加相关的布局与控件hbox1 = QHBoxLayout()# 向前翻页的按钮self.prevButton = QPushButton("前一页")# 向后翻页的按钮self.nextButton = QPushButton("后一页")# 直接跳转到指定页数的按钮和输入想要跳转至的页数的输入框self.switchPageButton = QPushButton("Go")self.switchPageLineEdit = QLineEdit()self.switchPageLineEdit.setFixedWidth(40)
​switchPage = QLabel("转到第")page = QLabel("页")
​# 绑定信号和槽self.prevButton.clicked.connect(self.onPrevButton)self.nextButton.clicked.connect(self.onNextButton)self.switchPageButton.clicked.connect(self.onSwitchPageButtonClick)
​# 添加我们的控件hbox1.addWidget(self.prevButton)hbox1.addWidget(self.nextButton)hbox1.addWidget(switchPage)hbox1.addWidget(self.switchPageLineEdit)hbox1.addWidget(page)hbox1.addWidget(self.switchPageButton)# 通过添加间隔控件使得上面的控件全部被挤到左边去hbox1.addWidget(QSplitter())
​# 下面这个布局置于最底端,当做当前页面的状态hbox2 = QHBoxLayout()# 创建显示总也是的labelself.totalPageLabel = QLabel()self.totalPageLabel.setFixedWidth(70)# 创建显示当前页数的labelself.currentPageLabel = QLabel()self.currentPageLabel.setFixedWidth(100)# 创建显示总记录数的labelself.totalRecordLabel = QLabel()self.totalRecordLabel.setFixedWidth(70)
​hbox2.addWidget(self.totalPageLabel)hbox2.addWidget(self.currentPageLabel)# 通过添加间隔控件使得上面的控件(totalPageLabel和currentPageLabel)在左边,下面的控件(totalRecordLabel)在右边hbox2.addWidget(QSplitter())hbox2.addWidget(self.totalRecordLabel)
​# 设置表格属性self.tabelView = QTableView()# 表格宽度自适应调整self.tabelView.resizeRowsToContents()self.tabelView.resizeColumnsToContents()
​# 创建主布局,并将hbox1,表格和hbox2装入mainLayout = QVBoxLayout(self)mainLayout.addLayout(hbox1)mainLayout.addWidget(self.tabelView)mainLayout.addLayout(hbox2)self.setLayout(mainLayout)
​def setTableView(self):# 声明查询模型self.queryModel = QSqlQueryModel(self)# 设置当前页self.currentPage = 1# 获取总记录数self.totalRecordCount = self.getTotalRecordCount()# 获取总页数self.totalPage = self.getPageCount()# 刷新状态(也就是更新hbox2中各控件显示的值)self.updateStatus()# 设置总页数文本self.setTotalPageLabel()# 设置总记录数self.setTotalRecordLabel()
​# 记录查询(0代表从第1条开始查),从第一条往后查询6条self.recordQuery(0)# 将数据库中的model和tabelView关联# 这样数据库中的数据就可以直接显示在tableView代表的表格上了self.tabelView.setModel(self.queryModel)
​# 得到记录数def getTotalRecordCount(self):# 设置查询模型,获得一个查询所有数据的查询模型self.queryModel.setQuery("select * from student")# 通过模型的rowCount()方法得到数据条数rowCount = self.queryModel.rowCount()return rowCount
​# 得到页数def getPageCount(self):# 实际得到的页数应该是:总的记录数 / 每页能够容纳下的记录条数,再向上取整# 下面就是通过判断来达到向上取整
​if self.totalRecordCount % self.PageRecordCount == 0:return int(self.totalRecordCount / self.PageRecordCount)else:return int(self.totalRecordCount / self.PageRecordCount + 1)
​
​# 记录查询函数(显示limitIndex到limitIndex+5的6条数据)def recordQuery(self, limitIndex):# 查询语句,从limitIndex开始往后查询6条szQuery = ("select * from student limit %d,%d" % (limitIndex, self.PageRecordCount))# 对查询模型使用set方法来设置模型self.queryModel.setQuery(szQuery)
​# 刷新状态def updateStatus(self):szCurrentText = ("当前第%d页" % self.currentPage)# 这是更新显示当前页数的labelself.currentPageLabel.setText(szCurrentText)
​# 设置按钮是否可用# 如果当前在第一页,那么“向前一页”的按钮不可用if self.currentPage == 1:self.prevButton.setEnabled(False)self.nextButton.setEnabled(True)# 如果当前在最后一页,那么“向后一页”的按钮不可用elif self.currentPage == self.totalPage:self.prevButton.setEnabled(True)self.nextButton.setEnabled(False)# 如果当前在既不在第一页,也不在最后一页,那么两个按钮都可用else:self.prevButton.setEnabled(True)self.nextButton.setEnabled(True)
​# 设置显示总页数def setTotalPageLabel(self):szTotalPageText = ("共%d页" % self.totalPage)self.totalPageLabel.setText(szTotalPageText)
​# 设置显示总记录数def setTotalRecordLabel(self):szTotalRecordText = ("共%d条" % self.totalRecordCount)self.totalRecordLabel.setText(szTotalRecordText)
​# 跳转到前一页的按钮按下的槽函数def onPrevButton(self):# 计算上一页第一条数据的索引# 注意我们的当前页数是从1开始的,而数据索引是从0开始的limitIndex = (self.currentPage - 2) * self.PageRecordCount# 设置查询模型(显示上一页的6条数据)self.recordQuery(limitIndex)# 记录当前页数的变量也需要变self.currentPage -= 1# 刷新状态self.updateStatus()
​# 跳转到后一页的按钮按下的槽函数def onNextButton(self):# 如法炮制limitIndex = self.currentPage * self.PageRecordCountself.recordQuery(limitIndex)self.currentPage += 1self.updateStatus()
​# 转到指定页面的按钮按下的槽函数def onSwitchPageButtonClick(self):# 得到输入的字符串szText = self.switchPageLineEdit.text()
​# 得到页数pageIndex = int(szText)# 判断是否有指定页数if pageIndex > self.totalPage or pageIndex < 1:QMessageBox.information(self, "提示", "没有指定的页面,请重新输入")return
​# 得到查询起始行号limitIndex = (pageIndex - 1) * self.PageRecordCount
​# 设置查询模型self.recordQuery(limitIndex)# 设置当前页self.currentPage = pageIndex# 刷新状态self.update()
​
​
if __name__ == '__main__':app = QApplication(sys.argv)main = DataGrid()main.show()sys.exit(app.exec_())

运行效果:

8e418c5075ee589c4b6563f47b66490d.png

实战项目:天气信息查询

最后我们完成一个查询北京、天津、上海三地的天气查询的小GUI。

基本思路是先通过PyQt5搭建基本的布局和控件,然后为了获取三地的天气信息,我们需要使用Python中的Requests库,这是一个超级轻量的python爬虫库,可以静态爬取指定url的数据流(这不是重点啦),反正将爬取的数据setText()在我们的控件上就行了。至于怎么使用requests库爬取,读者可以搜索MOOC上北京理工大学的requests课程。

最后我们搭建主循环,在其中设置窗口的QSS样式。

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import requests
import sys
​
​
class QueryWeather(QWidget):# 构造函数后面三个参数决定默认的图像生成的宽度,高度和清晰度(每英寸像素点数)def __init__(self, parent=None):super(QueryWeather, self).__init__(parent)self.setWindowTitle("查询城市天气")# 设置固定的窗口大小self.setFixedSize(800, 600)# 设置透明度self.setWindowOpacity(0.98)# 城市编码self.cityName2Code = {"北京":"101010100", "天津":"101030100", "上海":"101020100"}
​self.initUI()
​# 搭建窗口,你也可以根据自己的喜好搭建,这里只是参考def initUI(self):mainVbox = QVBoxLayout()vbox = QVBoxLayout()hbox1 = QHBoxLayout()hbox2 = QHBoxLayout()self.cityLabel = QLabel("城市")self.cityLabel.setAlignment(Qt.AlignCenter)self.cityLabel.setFixedSize(100, 50)self.cityComboBox = QComboBox()self.cityComboBox.setFixedSize(200, 35)self.cityComboBox.addItems(["北京","天津","上海"])self.weatherInfoText = QTextBrowser()self.weatherInfoText.setFixedSize(750, 300)self.weatherInfoText.setAlignment(Qt.AlignCenter)hbox1.addWidget(self.cityLabel)hbox1.addWidget(self.cityComboBox)hbox1.addWidget(QSplitter())hbox2.addWidget(self.weatherInfoText)vbox.addLayout(hbox1)vbox.addLayout(hbox2)
​buttonHBox = QHBoxLayout()self.queryButton = QPushButton("查询")self.queryButton.setFixedSize(150, 40)self.queryButton.setProperty("name", "queryButton")self.clearButton = QPushButton("清空")self.clearButton.setFixedSize(150, 40)self.clearButton.setProperty("name", "clearButton")buttonHBox.addStretch(1)buttonHBox.addWidget(self.queryButton)buttonHBox.addStretch(1)buttonHBox.addWidget(self.clearButton)buttonHBox.addStretch(1)
​mainVbox.addLayout(vbox)mainVbox.addStretch(1)mainVbox.addLayout(buttonHBox)
​self.setLayout(mainVbox)self.queryButton.clicked.connect(self.queryWeather)self.clearButton.clicked.connect(self.clearWeather)
​
​def queryWeather(self):cityName = self.cityComboBox.currentText()# 获取城市对应我们要爬取的页面中的编码cityCode = self.cityName2Code[cityName]
​# 爬取页面内容,返回response对象(json数据)rep = requests.get("http://www.weather.com.cn/data/sk/" + cityCode + ".html")# 设置response对象的编码rep.encoding = "utf-8"print(rep.json())
​# 获取json数据中的键值对,就是我们需要的信息msg1 = "城市: {}".format(rep.json()["weatherinfo"]["city"] + "n")msg2 = "风向: {}".format(rep.json()["weatherinfo"]["WD"] + "n")msg3 = "温度: {}".format(rep.json()["weatherinfo"]["temp"] + "n")msg4 = "风力: {}".format(rep.json()["weatherinfo"]["WS"] + "n")msg5 = "湿度: {}".format(rep.json()["weatherinfo"]["SD"] + "n")result = msg1 + msg2 + msg3 + msg4 + msg5self.weatherInfoText.setText(result)
​def clearWeather(self):# 因为setText方法本来就是覆盖写,那我们将全文信息设置成一个空格就可以达到清空页面信息的效果self.weatherInfoText.setText(" ")
​
if __name__ == '__main__':app = QApplication(sys.argv)main = QueryWeather()# QSS样式表字符串style = '''QLabel{font-size:30px;}QComboBox{font-size:30px;}QPushButton[name="queryButton"]{background-color:#938FD9;color:#2f4f4f;font-size:25px;}QPushButton[name="clearButton"]{background-color:#C0C0C0;font-size:25px;}QTextBrowser{font-size:40px;color:#00CED1;}'''main.setStyleSheet(style)main.show()sys.exit(app.exec_())

运行效果:

9bb7474c429c2ca1cb571c7075cab173.png

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

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

相关文章

依赖第三方库时出现的问题:Manifest merger failed : uses-sdk:minSdkVersion 15 cannot be smaller than version 16

导入第三方库时出现了sdk版本不兼容问题 为我们app的module所支持的sdk最低版本与依赖module的sdk最低版本不一致 把15--》16即可

Linux基本目录结构

上一步我们已经搭建好实验环境了&#xff0c;这一节就来实际操作一下&#xff0c;到底什么是CentOS&#xff0c;到底什么是Linux操作系统&#xff0c;写什么&#xff0c;如何去做&#xff0c;如何去打开&#xff0c;下面我们带着这些疑惑展开这一节 1.打开终端&#xff0c;有些…

解决:VMware DHCP Service 服务无法启动

今天在布置项目的时候发现VMware DHCP Service 服务无法启动&#xff0c;连网络也连接不了 解决办法是 搞定 解决后验证Linux又可以连接上网络了

bmp文件格式_一次性解决CAD转换成BMP格式图片的问题

关于BMP格式图片&#xff0c;可能很多小伙伴都遇到得比较多&#xff0c;但在这里还是稍微解释一下吧。它是Windows操作系统中的标准图像文件格式&#xff0c;大家都知道BMP格式的图片都非常大&#xff0c;那是因为它没有经过任何压缩。当然&#xff0c;关于BMP文件当中蕴含着哪…

Linux如何配置网络IP地址

首先&#xff0c;脑子思路一定要清晰我们为什么要配置ip地址&#xff0c;我们的电脑一般是一个物理网卡&#xff0c;那么按照正常情况&#xff0c;我们的虚拟机里的Linux是和windows共享同一个物理网卡的&#xff0c;所以很正常&#xff0c;一个物理网卡不可能仅仅只有一个ip地…

shell 字典_腾讯T4周末不陪对象,就为了手打这份shell编程笔记

这个周末&#xff0c;为了某些原因&#xff0c;我把shell编程的一些基础知识进行了相应的整理&#xff0c;这里分享给大家&#xff0c;大家在看的时候&#xff0c;有什么问题可以在下方评论区给我留言呀&#xff0c;欢迎转发自己纯手打&#xff0c;原创不易&#xff0c;谢谢支持…

Linux如何从普通用户切换到root用户

第一步&#xff1a;打开终端 pwd&#xff1a;Print Working Directory &#xff08;查看当前路径&#xff09; 默认安装完成之后并不知道root用户的密码&#xff0c;那么如何应用root权限呢&#xff1f; (1)sudo 命令 这样输入当前管理员用户密码就可以得到超级用户的权限…

css盒子模型_说说css盒子模型

什么是盒模型引用MDN官方的解释&#xff1a;当对一个文档进行布局&#xff08;lay out&#xff09;的时候&#xff0c;浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型&#xff08;CSS basic box model&#xff09;&#xff0c;将所有元素表示为一个个矩形的盒子&#xff0…

基于IPP库将FFT函数封装为C++类库并导出为dll(固定接口支持更新)

dll导出C++类的方式 C++类通常有3中导出方式,具体可以参考这篇博客: Dll导出C++类的3种方式 简单来总结一下: 一、纯C语言方式,类似显式传递this指针 缺点 调用创建对象函数的时候编译器无法判断类型是否匹配需要手动调用Release函数,一旦忘记则会造成内存泄露如果导出…

Linux中实现远程登录Xshell和Xftp

1.磨刀不误砍柴工 百度网盘&#xff1a;https://pan.baidu.com/s/1c8YKhKAu_KO52Uw2MSc7WA 提取码&#xff1a;q000 &#xff08;转自https://blog.csdn.net/qq_45260767/article/details/105972350的链接&#xff09; 去百度网盘下载并提取这两个压缩包&#xff08;Xshell…

javaee 中文帮助文档_从中游公司跳槽阿里必知:K8s、Nginx、Redis、微服务面试文档...

前言随着时代的进步和发展&#xff0c;无论哪份工作都不能因循守旧&#xff0c;不去创新或者去吸收新的知识&#xff0c;尤其是Java开发的工作者&#xff0c;在十几年之前&#xff0c;很多人都已经掌握了Java的很多知识&#xff0c;但是如今如果只会SSM的小伙伴&#xff0c;已经…

Linux下安装VIM编辑器,以及简单的VIM指令操作

根据你的Linux版本&#xff0c;输入对应的如下命令&#xff0c;如果是centos系统&#xff0c;故而输入 yum -y install vim* ubuntu 系统输入命令&#xff1a;sudo apt-get install vim-gtkcentos 系统输入命令&#xff1a;yum -y install vim*这时候我们就已经安装好vim了&am…

idea 编译spring_Spring 源码阅读环境的搭建

" 前言本文记录了 Spring 源码环境的搭建方式&#xff0c;以及踩过的那些坑&#xff01;​当前版本&#xff1a;5.3.2-SNAPSHOT。环境准备GitJDK master 分支需要 JDK 115.2.x 分支&#xff0c; JDK8 即可Gradle 6.5.1IDEA 最新 &#xff08;2020.2.3&#xff09;Spring 源…

来自百度的一篇如何关闭Centos7的防火墙以及如何永久关闭防火墙的指令教学【转载】

转载&#xff1a;来自百度的一篇如何关闭Centos7的防火墙以及如何永久关闭防火墙的指令教学 使用命令&#xff1a;systemctl status firewalld.service 查看防火墙状态 2 执行后可以看到绿色字样标注的“active&#xff08;running&#xff09;”&#xff0c;说明防火墙是开…

Linux的Xshell连接Centos7能Ping通但无法连接问题[ssh(d)+firewall(d)]【转载转载转载】

一 方案与思路 0 xshell客户端监测是否能够ping通目标服务器。 前提&#xff1a;知晓目标服务器IP地址 Linux: ifconfig -aWindows: ipconfig -a1 利用firewall工具&#xff0c;检查是否已开启ssh的22端口。若无&#xff0c;则&#xff1a;开启22端口2 利用sshd工具&#xff0…

dubbo web工程示例_分布式开发-Zooker+dubbo入门-Demo

作者&#xff1a;知了堂-刘阳1.什么是SOA架构SOA 是Service-Oriented Architecture的首字母简称&#xff0c;它是一个面向服务的架构模式&#xff08;俗称&#xff1a;分布式&#xff1b;面服务的分布式&#xff09;为什么互联网项目会采用SOA架构呢&#xff1f;随着互联网的发…

Linux如何避免每次开启 CentOS 时,都要手动开启 sshd 服务,防止连接不上Xshell

避免每次开启 CentOS 时&#xff0c;都要手动开启 sshd 服务&#xff0c;可以将 sshd 服务添加至自启动列表中&#xff0c; 输入 systemctl enable sshd.service 可以通过输入&#xff1a;查看是否开启了sshd 服务自启动 systemctl list-unit-files | grep sshd

380免费云存储_三款功能强大的云盘软件,完全替代百度云与腾讯云

众所周知&#xff01;百度云是百度旗下良心产品之一&#xff0c;有免费版&#xff0c;但是免费版限速太厉害&#xff0c;让很多免费用户都难以接受&#xff0c;其次就是腾讯云&#xff0c;腾讯云也是腾讯旗下的良心产品之一&#xff0c;但是两个产品都不是很完美&#xff0c;那…

centos右上角wired图标消失有效解决方案【转载】

突然之间就发现centos7的右上角的网络连接不见了&#xff0c;卧槽&#xff0c;这么神奇的吗&#xff1f;然后又无意中在网上浏览了这个方法&#xff0c;简单又好用 最近在学习Linux配置nginx时&#xff0c;左上角的wired图标突然没了&#xff0c;很神奇。然后在网上按着很多博客…

mysql 关联查询_mysql数据库调优(二)

第五、查询优化1、查询慢的原因&#xff1a;网络因素、CPU、IO、上下文切换、系统调用、生成统计信息、锁等待时间等2、优化数据库访问&#xff1a;查询性能地下的原因是访问的数据太多&#xff0c;某些查询不可避免的需要筛选大量的数据&#xff0c;可以通过减少访问数据量的方…