一.PyQt5简介

PyQt5是一个用于创建图形用户界面(GUI)应用程序的跨平台工具集,它将Qt库(广泛用于C++编程语言中创建丰富的GUI应用程序)的功能包装给Python使用者。PyQt5是由Riverbank Computing开发的,并且可以在所有主流操作系统上运行,包含Windows、macOS和Linux。

PyQt5包括了超过620个类和6000个函数和方法。这个框架支持包括SQL数据库、线程、Unicode、正则表达式、网络编程等高级功能。除了GUI功能外,PyQt5还允许用户访问Qt的模型/视图架构和QML(Qt Modeling Language),这是一种专门为创建动态和自定义用户界面而设计的语言。

二.环境搭建

1.终端使用pip安装PyQt5库

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple PyQt5

2.如果出现Could not build wheels for PyQt5_sip, which is required to install pyproject.toml-based projects报错信息

3.先安装 Visual Studio 后再安装PyQt5即可,终端执行如下指令

wget https://aka.ms/vs/17/release/vs_BuildTools.exe -o vs_BuildTools.exe ; cmd /c vs_BuildTools.exe

勾选C++/CLI后安装就行

三.基本用法

1.PyQt5常见的模块

QApplication 这个类管理GUI应用程序的控制流和主要设置,并且是每个PyQt5应用程序中必须有的部分
QWidget 所有用户界面对象的基类。当你想创建一个自定义的窗口时,你会使用或者继承这个类
QLabel 用于展示文本或图片的类
QtCore  其他模块使用的核心非 GUI 类
QAction 用于处理菜单栏、工具栏或快捷键等的动作。
QtSql 使用 SQL 进行数据库集成的类
QtXml 处理 XML 的类
QSlider 滑动条,让用户通过滑动选择一个数值。

2.一个简单的窗口创建

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QWidget, QLabel, QMessageBox, QApplication def windows():
# 创建一个 QApplication 类的应用程序对象
app = QApplication(sys.argv)
# 基于QWidget类声明窗口
w = QWidget()
# 添加一个QLabel对象,并将标签添加“helloworld”文本。
b = QLabel(w)
b.setText("Hello World!")
# 设置文本控件在窗口中的位置(x,y)
b.move(50, 50)
# 设置label控件的长和宽
b.resize(100,20)
# 设置字体样式大小
font = QFont()
font.setFamily("Arial") # 字体样式,中文英文都可(“楷体”)
font.setPointSize(20) # 字体大小
b.setFont(font)
# 通过 setGeometry() 方法定义窗口的大小和位置(x,y,w,h)
w.setGeometry(100, 100, 500, 1000)
# 设置窗口标题
w.setWindowTitle("PyQt5") # 显示窗口
w.show()
# 进入应用程序的主循环app.exec_()方法(窗口一直显示)
sys.exit(app.exec_()) if __name__ == '__main__':
windows()

备注写的很详细了,这里就不一一介绍每行代码的意思了。

3.窗口icon设置

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QWidget, QApplication # 导入尽量用具体类,不用* class Window(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.initUI()
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle("PyQt5") # 设置icon
def initUI(self):
self.setWindowIcon(QIcon('./2.jpg')) # 设置窗口左上角icon def main():
app = QApplication(sys.argv)
ex = Window()
ex.show()
sys.exit(app.exec_()) if __name__ == '__main__':
main()

上述代码中,我们在initUI函数中,调用父类setWindowIcon()方法去设置窗口icon,在Window类中初始化时去调用initUI函数来实现设置icon。

4.QLabel控件

    def qlabel(self):
font = QFont()
font.setFamily("Arial")
font.setPointSize(16)
label = QLabel(self)
label.setText("Hello World") # 设置文本
label.setFont(font) # 设置文本字体类型及大小
label.move(50, 20) # 控件在窗口的位置

这里和如上写法一致,在Window类中写一个qlabel函数,里面去调用QLabel,再在Window类中初始化时调用这个函数即可(使用QLabel模块时需提前导入该模块),我们来看下结果。

5.tips信息提示框

    def tips(self):
# 创建一个按钮控件
btn = QPushButton('Button', self)
# 设置文本字体及大小
btn.setFont(QFont('SansSerif', 50))
# 设置tips
btn.setToolTip('This is a widget')
# 设置按钮在窗口的位置
btn.move(100, 100)

效果如下,鼠标悬浮在button上时,会出现tips信息弹框。

6.关闭二次确定弹框

主动关闭窗口(即点击窗口右上角X),弹出二次确定弹框,提示是否关闭。

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QWidget, QApplication, QMessageBox, QDesktopWidget # 导入尽量用具体类,不用* class Window(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.initUI()
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle("PyQt5")
self.center() # 设置icon
def initUI(self):
self.setWindowIcon(QIcon('./2.jpg')) def closeEvent(self, event): # 关闭二次确定弹框
reply = QMessageBox.question(self, '是否关闭',
"Are you sure to quit?", QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes:
event.accept() # 关闭窗口
else:
event.ignore() # 不关闭 def center(self): # 设置窗口居中
qt = self.frameGeometry() # 获取需要操作的窗口位置,长宽(即设置的setGeometry)
cp = QDesktopWidget().availableGeometry().center() # 获取电脑分辨率
qt.moveCenter(cp) # 获取电脑中间位置
self.move(qt.topLeft()) # 将窗口移动到中间位置 def main():
app = QApplication(sys.argv)
ex = Window()
ex.show()
sys.exit(app.exec_()) if __name__ == '__main__':
main()

上述代码中重写了父类中的closeEvent方法,通过QMessageBox.question()来获取用户行为,event.accept()来确定关闭窗口。

7.关闭窗口事件

    def clos(self):
qbtn = QPushButton('Quit', self) # 创建一个按钮
qbtn.clicked.connect(QCoreApplication.instance().quit) # 回调关闭事件
qbtn.setToolTip("点击关闭窗口") # tips提示
qbtn.move(0, 0)

如下图效果,鼠标点击Quit按钮后窗口关闭,其效果和关闭按钮X一致。

8.菜单栏和工具栏

QMainWindow用于创建主应用程序窗口的类。它是 QWidget 的一个子类,提供了创建具有菜单栏、工具栏、状态栏等的主窗口所需的功能。

1)状态栏

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication class Example(QMainWindow): def __init__(self):
super().__init__()
self.initUI() def initUI(self):
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle('Statusbar')
self.statusBar().showMessage("状态栏") # 设置状态栏 if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

状态栏的设置很简单,通过调用QMainWindow的statusBar()方法创建状态栏,showMessage()来设置状态栏显示的文本。

2)菜单栏

    def bar(self):
action = QAction(QIcon('./2.jpg'), '登录', self) # 创建QAction实例
action.setShortcut('Ctrl+a') # 设置快捷键操作
action.setStatusTip('登录') # 状态栏提示,窗口的左下角出现,鼠标悬停在选项上会出现
action.triggered.connect(qApp.quit) # 点击事件后回调的方法(qApp.quit关闭窗口) menubar = self.menuBar() # 创建一个菜单栏
menu = menubar.addMenu('File') # 设置菜单栏tab menu.addAction(action) # 关联事件

用过menuBar()创建一个菜单栏,并添加addMenu()tab项,通过addAction()添加QAction行为动作,具体效果如下。

triggered.connect(qApp.quit)设置了触发动作后回调事件,即点击登录选项或快捷键Ctrl+A时会触发qApp.quit关闭窗口。上诉中我们只创建了一个菜单栏并只绑定了一个QAction如果想要多个菜单栏多个动作,可以创建多个addMenu(),下面看下具体实例。

   def bar(self):
action = QAction(QIcon('./2.jpg'), '登录', self) # 创建QAction实例
action.setShortcut('Ctrl+a') # 设置快捷键操作
action.setStatusTip('登录') # 状态栏提示,窗口的左下角出现,鼠标悬停在选项上会出现
action.triggered.connect(qApp.quit) # 点击事件后回调的方法(qApp.quit关闭窗口) action1 = QAction(QIcon('./2.jpg'), '登录', self) # 创建QAction实例
action1.setShortcut('Ctrl+a') # 设置快捷键操作
action1.setStatusTip('退出') # 状态栏提示,窗口的左下角出现,鼠标悬停在选项上会出现
action1.triggered.connect(qApp.quit) # 点击事件后回调的方法(qApp.quit关闭窗口) menubar = self.menuBar() # 创建一个菜单栏
menu = menubar.addMenu('File') # 设置菜单栏tab
menubar1 = self.menuBar() # 创建一个菜单栏
menu1 = menubar1.addMenu('File1') # 设置菜单栏tab menu.addAction(action) # 关联事件
menu.addAction(action1) # 关联事件

3)子菜单栏

上面我们只是实现了一级菜单栏,那么在需求中要求创建二级,三级或者多级菜单,此时就需要用到QMenu()来创建下拉菜单栏了,我们先来看下二级菜单栏的创建。

    # 创建子菜单
def bar_z(self):
menubar = self.menuBar() # 创建菜单栏
menu = menubar.addMenu('File') # 设置菜单栏tab newmenu = QMenu('一级下拉框', self) # 创建一个下拉菜单
impAct = QAction('二级目录', self) # 设置一个动作
impAct.triggered.connect(self.btn) # 点击事件后回调的方法
newmenu.addAction(impAct) # 添加动作到下菜单中 newact = QAction('一级目录', self) # 创建动作 menu.addAction(newact) # 添加动作到菜单栏
menu.addMenu(newmenu) # 添加下拉菜单到菜单栏 def btn(self):
# 创建一个按钮控件
btn = QPushButton('Button', self)
# btn.setGeometry(100, 100, 80, 30)
btn.move(100, 100)
btn.setToolTip("button")
btn.show()

如果我们想创建三级目录甚至更多级的目录,可以创建多个下拉菜单栏,并通过addMenu()添加进去,下面看下具体实现。

# 创建子菜单
def bar_z(self):
menubar = self.menuBar() # 创建菜单栏
menu = menubar.addMenu('File') # 设置菜单栏tab newmenu1 = QMenu('二级下拉框', self) # 创建一个下拉菜单
impAct1 = QAction('三级目录', self) # 设置一个动作
impAct1.triggered.connect(self.btn) # 点击事件后回调的方法
newmenu1.addAction(impAct1) # 添加动作到下菜单中 newmenu = QMenu('一级下拉框', self) # 创建一个下拉菜单
impAct = QAction('二级目录', self) # 设置一个动作
impAct.triggered.connect(self.btn) # 点击事件后回调的方法
newmenu.addAction(impAct) # 添加动作到下菜单中
newmenu.addMenu(newmenu1) # 添加下拉菜单栏到二级菜单下 newact = QAction('一级目录', self) # 创建动作 menu.addAction(newact) # 添加动作到菜单栏
menu.addMenu(newmenu) # 添加下拉菜单到菜单栏

4)带复选框的菜单

    def bar_checkable(self):
menubar = self.menuBar()
bar_menu = menubar.addMenu('View') # 添加菜单栏
statact = QAction('复选框', self, checkable=True) # 创建一个可以勾选的动作
statact.setStatusTip('View statusbar')
statact.setChecked(True) # 设置默认选中
statact.triggered.connect(self.menu)
bar_menu.addAction(statact)
def menu(self, state):
if state:
print("勾选后执行的事件") # 勾选了
else:
print("取消勾选执行的事件") # 取消勾选

QAction()中,checkable=True表示可以勾选的动作。

5)右键栏

鼠标悬浮再窗口上,右击打开的菜单栏,此功能需要重写父类中contextMenuEvent()方法,看下代码演示。

    def contextMenuEvent(self, event):
rightmenu = QMenu(self) # 创建一个下拉菜单
# 添加动作
d = rightmenu.addAction("打印")
q = rightmenu.addAction("退出")
ture = rightmenu.addAction("确定")
action = rightmenu.exec_(self.mapToGlobal(event.pos())) # exec_()显示菜单。获取动作行为
if action == d:
self.btn()
elif action == q:
qApp.quit() # 关闭窗口
else:
print("无确定内容")

6)工具栏

工具栏可以理解为是多个动作的集合,可以将多个QAction()添加展示出来。

    def bar_tool(self):  # 多个动作集合
action = QAction("工具1",self)
action2 = QAction("工具2",self)
action.setStatusTip("点击退出")
action.triggered.connect(qApp.quit)
toolbat = self.addToolBar("工具栏") # 创建一个工具栏
toolbat.addAction(action) # 将动作添加到工具栏
toolbat.addAction(action2) # 将动作添加到工具栏

7)主窗口显示

这个就不做过多介绍,在初始__init__中调用上诉几种方法即可,默认菜单栏在最顶部,添加的动作会更加调用的先后从左到右排列,工具栏默认在菜单栏下发,这里只看下效果截图。

9.页面布局

1)坐标布局

import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QLabel, QApplication, QWidget class Example(QWidget): def __init__(self):
super().__init__()
self.initUI() def initUI(self):
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle('Statusbar')
q1 = QLabel("quit", self)
q2 = QLabel("quit2", self)
q3 = QLabel("quit3", self)
q1.move(20, 20) # 坐标布局
q2.move(20, 80) # 坐标布局
q3.move(20, 140) # 坐标布局 if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

坐标布局

上述中通过move(x, y)方法来设置qlable的位置

2)界面比例布局

import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QPushButton, QHBoxLayout, QWidget class Example(QWidget): def __init__(self):
super().__init__()
self.initUI()
self.button() def initUI(self):
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle('Statusbar') def button(self): # 比例布局
ok = QPushButton("ok") # 创建三个按钮
cancel = QPushButton("cancel")
cancel1 = QPushButton("cancel1") hbox1 = QHBoxLayout() # 创建一个水平布局
hbox1.addWidget(ok) # 添加按钮到水平布局中
hbox1.addStretch(1) # 设置水平比例间距 hbox1.addWidget(cancel) # 添加按钮到水平布局中
hbox1.addStretch(1) # 设置水平比例间距
hbox1.addWidget(cancel1)
hbox1.addStretch(6) self.setLayout(hbox1) # 添加到布局器 if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

水平布局


上面代码中通过QHBoxLayout() 创建一个水平布局,addWidget()将按钮添加到布局中,再通过addStretch()来设置比例间距,可以看到设置的比例为1:1:6

import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QPushButton, QHBoxLayout, QVBoxLayout, QWidget class Example(QWidget): def __init__(self):
super().__init__()
self.initUI()
self.button() def initUI(self):
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle('Statusbar') def button(self): # 比例布局
ok = QPushButton("ok") # 创建三个按钮
cancel = QPushButton("cancel")
cancel1 = QPushButton("cancel1") hbox = QHBoxLayout() # 创建一个水平布局
hbox.addStretch(1) # 设置水平比例间距(只设置一个stretch,会将按钮挤到最右侧。若stretch写在addWidget下面,则按钮会被寄到最左侧)
hbox.addWidget(ok) # 添加按钮到水平布局中
hbox.addWidget(cancel) vbox = QVBoxLayout() # 创建一个垂直布局
vbox.addStretch(1) # 设置垂直比例间距(只设置一个stretch,会将按钮挤到最下面。若stretch写在addlayout下面,则按钮会被寄到最下面)
vbox.addLayout(hbox) # 将刚刚创建的水平布局添加到垂直布局中 self.setLayout(vbox) # 将垂直布局加到布局器中(按钮位于页面右下角) if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

垂直布局

3)栅格化布局

import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QGridLayout class Example(QWidget): def __init__(self):
super().__init__()
self.initUI()
self.Grid() def initUI(self):
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle('Statusbar') def Grid(self): # 栅格化的按钮
grid = QGridLayout() # 创建一个栅格化布局
name = ["7", "8", "9", "/",
"4", "5", "6", "x",
"1", "2", "3", "-",
"清除", "0", ".", "="]
# 列表推导式
pos = [(x, y) for x in range(4) for y in range(4)]
for names, p in zip(name, pos): # 同时迭代两个序列
button = QPushButton(names) # 创建按钮
grid.setSpacing(10) # 设置各个单元格之间的间距
grid.addWidget(button, *p) # 添加到栅格化布局中
self.setLayout(grid) # 将栅格化布局加到布局器 if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

栅格化布局

效果图

栅格化布局理论上也是通过坐标来定位的,通过列表推导式可到得到几个坐标(0,0)(0,1)(0,2)(1,0)(1,1)(1,2)..........,然后再通过坐标去逐个添加。

4)实例

import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QLabel, QApplication,QWidget, QGridLayout, \
QLineEdit, QTextEdit class Example(QWidget): def __init__(self):
super().__init__()
self.initUI()
self.input() def initUI(self):
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle('Statusbar') def input(self):
grid = QGridLayout() # 设置标签
title = QLabel("title")
Author = QLabel("Author")
Review = QLabel("Review") # 设置输入框
titleEdit = QLineEdit() # 行编辑
authorEdit = QLineEdit()
reviewEdit = QTextEdit() # 文版编辑 grid.setSpacing(10) # 设置间距 grid.addWidget(title, 0, 0)
grid.addWidget(titleEdit, 0, 1)
grid.addWidget(Author, 1, 0)
grid.addWidget(authorEdit, 1, 1)
grid.addWidget(Review, 2, 0)
grid.addWidget(reviewEdit, 2, 1) self.setLayout(grid) if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

实例

上述中实例通过QGridLayout()来将QLabel(), QLineEdit(行编辑)  ,QTextEdit(文版编辑) 进行的整合使用,下面看下结果。

四.实例

以一个简单计算器功能为例,先来看下代码实现和效果展示

import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QGridLayout, \
QLineEdit class Example(QWidget): def __init__(self):
super().__init__()
self.initUI()
self.Grid() def initUI(self):
self.setGeometry(100, 100, 500, 500)
self.setWindowTitle('Statusbar') def Grid(self): # 栅格化的按钮
grid = QGridLayout()
hbox = QLineEdit()
grid.addWidget(hbox, 0, 0, 1, 4)
name = [
"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"清除", "0", ".", "="]
# 列表推导式
pos = [(x, y) for x in range(1,5) for y in range(4)]
for names, p in zip(name, pos): # 同时迭代两个序列
if names == "":
continue
elif names == "hbox":
grid.addWidget(hbox, *p)
else:
button = QPushButton(names)
grid.addWidget(button, *p)
button.clicked.connect(lambda checked, btn_text=names: on_button_clicked(btn_text))
grid.setSpacing(10) # 设置各个单元格之间的间距 self.setLayout(grid) def on_button_clicked(btn_text):
try:
if btn_text == "清除":
hbox.clear()
elif btn_text == "=":
str_num = eval(hbox.text())
hbox.clear()
hbox.insert(str(str_num))
else:
hbox.insert(btn_text)
except:
hbox.insert("error") if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

计算器

使用addWidget将输入框添加到栅格化布局中,后面无个参数分别表示:(添加对象,x位置,y位置,占据的单元格高度,占据的单元格宽度)。

grid.addWidget(hbox, 0, 0, 1, 4)

QLineEdit()几个常用的方法

        hbox = QLineEdit()
hbox.setText("默认文案") # 设置默认文案
hbox.setPlaceholderText("暗文") # 当输入框内容为空时显示该文案
hbox.insert("243") # 添加
print(hbox.text()) # 获取框内容
hbox.clear() # 清空

五.打包

可参考:https://www.cnblogs.com/lihongtaoya/p/17349911.html

文章来源:https://www.cnblogs.com/lihongtaoya/ ,请勿转载

PyQt5 GUI编程的更多相关文章

  1. 用 eric6 与 PyQt5 实现python的极速GUI编程(系列01)--Hello world!

    [题记] 我是一个菜鸟,这个系列是我的学习笔记. PyQt5 出来有一段时间了, PyQt5 较之 PyQt4 有一些变化,而网上流传的几乎都是 PyQt4 的教程,照搬的话大多会出错. eric6 ...

  2. Python gui编程pyQt5安装步骤t

    Python gui编程pyQt5安装步骤         pip install PyQt5 Pip3 install PyQt5               https://riverbankco ...

  3. Python gui编程pyQt5安装步骤

    Python gui编程pyQt5安装步骤 =============================== -m PyQt5.uic.pyuic  $FileName$ -o $FileNameWit ...

  4. 用 eric6 与 PyQt5 实现python的极速GUI编程(35篇PyQT和200多篇Python)

    [题记] 我是一个菜鸟,这个系列是我的学习笔记. PyQt5 出来有一段时间了, PyQt5 较之 PyQt4 有一些变化,而网上流传的几乎都是 PyQt4 的教程,照搬的话大多会出错. eric6 ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. 1.JAVA之GUI编程概述

          下列内容为本人看毕向东老师java视频教程学习笔记! JAVA GUI图形用户界面编程: Windows 操作系统提供两种操作方式:                             ...

  7. 2.JAVA之GUI编程布局

    布局管理器 容器中的组件排放方式,就是布局 常见的布局管理器: **************************************************** 1.FlowLayout(流式 ...

  8. 3.JAVA之GUI编程Frame窗口

    创建图形化界面思路: 1.创建frame窗体: 2.对窗体进行基本设置: 比如大小.位置.布局 3.定义组件: 4.将组件通过add方法添加到窗体中: 5.让窗体显示,通过setVisible(tur ...

  9. 4.JAVA之GUI编程事件监听机制

    事件监听机制的特点: 1.事件源 2.事件 3.监听器 4.事件处理 事件源:就是awt包或者swing包中的那些图形用户界面组件.(如:按钮) 事件:每一个事件源都有自己特点有的对应事件和共性事件. ...

  10. 5.JAVA之GUI编程窗体事件

    我们回顾下第三篇时的内容: 在3.JAVA之GUI编程Frame窗口中窗体是无法直接关闭的,想要关闭须进程管理器结束进程方式关掉. 现在我们就来解决下这个问题. ******************* ...

随机推荐

  1. 欢迎加入 DotNet NB 交流学习群

    目录 起因 创建群组 群成员 技术交流 社区推广 社区前辈 欢迎加入 起因 自从2019年参加 .NET Conf China 大会之后,我创办了一个公众号 DotNet NB,内容主要是 关于 .N ...

  2. CF1878C Vasilije in Cacak 题解

    题目传送门 简化题意 有 \(t\) 组询问,每次询问是否能从 \(1 \sim n\) 中选择 \(k\) 个数使得它们的和为 \(x\). 解法 考虑临界情况,从 \(1 \sim n\) 中选择 ...

  3. 49从零开始用Rust编写nginx,我竟然在同一个端口上绑定了多少IP

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 负载均衡, 静态文件服务器,websocket代理,四层TCP/UDP转发,内网穿透等,会将实 ...

  4. NC15033 小G有一个大树

    题目链接 题目 题目描述 小G想要把自己家院子里的橘子树搬到家门口(QAQ..就当小G是大力水手吧) 可是小G是个平衡性灰常灰常差的人,他想找到一个这个橘子树的平衡点. 怎么描述这棵树呢...就把它看 ...

  5. 走出人生的舒适区,告别 CRUD

    ​舒适区(Comfort zone),指的是一个人所处的一种环境的状态,和习惯的行动,人会在这种安乐窝的状态中感到舒适并且缺乏危机感. 工作中的舒适区 很多人工作也每天很累很辛苦,程序员每天都在加班加 ...

  6. aspell命令

    aspell命令 aspell命令是一个交互式拼写检查器,其会扫描指定的文件或任何标准输入的文件,检查拼写错误,并允许交互式地纠正单词. 语法 aspell [options] command 参数 ...

  7. CF1398C Good Subarrays(写给我们萌新团体)

    Good Subarrays 传送门: Good Subarrays - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路 暴力!!!!! 一如既往的暴力!!! 复杂度O(n^2) ...

  8. r0capture 原理分析

    r0capture 是比较好用的抓包工具 仅限安卓平台,测试安卓7.8.9.10.11.12 可用 : 无视所有证书校验或绑定,不用考虑任何证书的事情: 通杀TCP/IP四层模型中的应用层中的全部协议 ...

  9. less变量书写及样式混入

    定义变量 定义混入样式 变量及混入样式使用 样式文件中   ~@代表src

  10. 使用TLP对Linux系统进行充电保护

    https://zhuanlan.zhihu.com/p/65546444 TLP:一个可以延长 Linux 笔记本电池寿命的高级电源管理工具 https://blog.csdn.net/zxw781 ...