Python桌面应用之XX学院水卡报表查询系统(Tkinter+cx_Oracle)
一、功能样式
Python桌面应用之XX学院水卡报表查询系统功能:
连接Oracle数据库,查询XX学院水卡操作总明细报表,汇总数据报表,个人明细报表,进行预览并且支持导出报表
1.总明细报表样式
2.汇总明细样式
3.个人明细样式
4.导出报表样式
5.错误提示样式
二、核心点
1. 安装cx_Oracle:使用cx_Oracle三方库连接Oracle,该库使用的python版本略低,可以在[https://cx-oracle.readthedocs.io/en/latest/](https://cx-oracle.readthedocs.io/en/latest/进行查询,安装前先确定:python版本、Orale客户端版本(要不都是64位,要不都是32位),安装cx_Oracle的版本位数是跟python的位数相关的。
使用代码进行测试
import cx_Oracle
# 账户 密码 ip:1521/实例名
conn = cx_Oracle.connect('system','Yxq123456','127.0.0.1:1521/ecard'
# 挂载数据库连接游标
self.cursor = conn.cursor()
print('连接数据库成功!')
2. 多参数查询Sql: sql语句使用:参数名
来定义参数,多参数使用cursor.execute(sql,(参数1,参数2)).fetchall()
来查询
sql = "select a.outid ,a.name ,b.opfare,b.opdt,b.dscrp from base_customers a,rec_cust_acc b where a.customerid = b. customerid and b.opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and b.opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') order by b.opdt desc"
preopdt=self.pretimeInput.get()
nextopdt=self.nexttimeInput.get()
data = self.cursor.execute(sql,(preopdt,nextopdt)).fetchall()
**3. Treeview表格组件的使用:**这里使用了三个报表,其实可以将打开的Treeview做成一个表格class类,要使用的时候直接生成要使用的对象,传入该对象的大小,heading标题,data数据即可。
# 明细查询def Consumedetail(self):self.consumedetail = tk.Tk()self.consumedetail.title('XX学院明细查询')self.consumedetail.geometry("1000x600")# 加载滚动条scrollBar = tk.Scrollbar(self.consumedetail)scrollBar.pack(side = tk.RIGHT,fill = tk.Y)self.tree = ttk.Treeview(self.consumedetail, columns=('outid', 'name', 'opfare', 'opdt','dscrp'), show="headings", displaycolumns="#all",yscrollcommand = scrollBar.set)self.tree.pack()self.tree.heading('outid', text="学号", anchor=tk.W)self.tree.heading('name', text="姓名", anchor=tk.W)self.tree.heading('opfare', text="交易金额", anchor=tk.W)self.tree.heading('opdt', text="交易日期", anchor=tk.W)self.tree.heading('dscrp', text="交易类型", anchor=tk.W)# 设置关联scrollBar.config(command = self.tree.yview)# 每次打开清空页面for item in self.tree.get_children():self.consumedetail.tree.delete(item)sql = "select a.outid ,a.name ,b.opfare,b.opdt,b.dscrp from base_customers a,rec_cust_acc b where a.customerid = b. customerid and b.opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and b.opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') order by b.opdt desc"preopdt=self.pretimeInput.get()nextopdt=self.nexttimeInput.get()data = self.cursor.execute(sql,(preopdt,nextopdt)).fetchall()# print(data)# data = [['2013090101','张三','100','2023-10-19','PC存款']]for itm in data:self.tree.insert("",tk.END,values=itm)self.tree.pack(padx=10,pady=10, fill=tk.BOTH,expand=1)exportbtn = tk.Button(self.consumedetail,text='导出',width=8,command=self.export).pack()
4. 导出数据自定义文件名:报表里面导出数据,其实使用遍历treeview组件数据,在进行整理后写入csv文件,自定义文件名是使用filedialog.asksaveasfilename
来打开文件框,里面的文件类型使用参数filetypes
,输入文件名后获取名称生成文件。这里导出的文件就只是csv文件,如果需要其他文件类型,可以自行导入其他三方库。
def export(self):# 导出export # 打开文件夹选择对话框# 更新标签文本# print(folder_path)list = []columns = []# 获取表格内容idfor row_id in self.tree.get_children():list.append(self.tree.item(row_id)['values'])print(len(self.tree.get_children())) # 通过第一行获取列数生成标题# print(self.tree.item)if len(self.tree.get_children()) != 0:print('ok')folder_path = filedialog.asksaveasfilename(title='请选择一个文件',filetypes=[("CSV", ".csv")]) for i in range(0,len(self.tree.item('I001')['values'])):columns.append(self.tree.heading(column=i)['text'])# 导出csvwith open(f'{folder_path}.csv','w',newline='') as csvfile:fieldnames = columnswriter = csv.writer(csvfile)writer.writerow(fieldnames)writer.writerows(list)else:messagebox.showwarning("提示", "没有数据,无法导出")return
5.遍历Treeview表格数据与标题:获取Treeview里面的数据与标题,这里现获取id值,然后通过item获取[‘values’]值,获取标题这里先遍历了第一行有多少数据,然后使用self.tree.heading(column=i)['text']
来获取标题。
# 获取表格内容id
for row_id in self.tree.get_children():list.append(self.tree.item(row_id)['values'])
# 通过第一行获取列数生成标题
for i in range(0,len(self.tree.item('I001')['values'])):columns.append(self.tree.heading(column=i)['text'])
三、完整代码
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import cx_Oracle
import time
import csv
from tkinter import filedialog# mainapp
class mainApp(object):def __init__(self,parent,**kwargs):self.root = parentcurrent_timestamp = time.time()# 将时间戳转换为本地时间的struct_time对象local_time = time.localtime(current_timestamp)# 使用strftime()方法将struct_time对象格式化为指定的时间字符串 # 挂在self时间self.pretime = time.strftime("%Y-%m-%d 00:00:00", local_time)self.nexttime = time.strftime("%Y-%m-%d %H:%M:%S", local_time)conn = cx_Oracle.connect('system','Yxq123456','127.0.0.1:1521/ecard')# conn = cx_Oracle.connect('ccense','XCXY123*','127.0.0.1:1521/ecard')# 挂载数据库连接游标self.cursor = conn.cursor()print('连接数据库成功!')self.root.config(**kwargs)self.root.title('XX学院')self.root.resizable(False, False)self.create_widgets()# 获取屏幕尺寸screen_width = self.root.winfo_screenwidth()screen_height = self.root.winfo_screenheight()# 确定窗口位置,并设置大小x_coordinate = (screen_width / 2) - 300 # 300是窗口的宽度y_coordinate = (screen_height / 2) - 200 # 200是窗口的高度self.root.geometry('650x400+{}+{}'.format(int(x_coordinate), int(y_coordinate)))# self.root.geometry("600x400")# 创建UIdef create_widgets(self):self.titleLab = tk.Label(self.root,text='XX学院水卡报表管理系统',font=("kaiti",18)).place(x=190,y=30)self.outidLab = tk.Label(self.root,text='学号:').place(x=80,y=100)self.outidInput = tk.Entry(self.root, width=20)self.outidInput.place(x=130,y=100)# 姓名# 学号self.nameLab = tk.Label(self.root,text='姓名:').place(x=380,y=100)self.nameInput = tk.Entry(self.root,width=20)self.nameInput.place(x=430,y=100)# 起始时间self.mustLabel1 = tk.Label(self.root,text='*',font=('Arial', 16),fg = 'red').place(x=45,y=160)self.pretimeLab = tk.Label(self.root,text='起始时间:').place(x=55,y=160)self.pretimeInput = tk.Entry(self.root, width=20)self.pretimeInput.place(x=130,y=160)self.pretimeInput.insert(0,self.pretime)# 终始时间self.mustLabel2 = tk.Label(self.root,text='*',font=('Arial', 16),fg = 'red').place(x=350,y=160)self.nexttimeLab = tk.Label(self.root,text='终止时间:').place(x=360,y=160)self.nexttimeInput = tk.Entry(self.root,width=20)self.nexttimeInput.place(x=430,y=160)self.nexttimeInput.insert(0,self.nexttime)self.consumeBtn = tk.Button(self.root,text='明细查询',command=self.Consumedetail,width=10).place(x=130,y=260)self.sumBtn = tk.Button(root,text='汇总查询',command=self.sumDetail,width=10).place(x=300,y=260)self.personBtn = tk.Button(root,text='个人查询',command=self.personDetail,width=10).place(x=480,y=260)# 明细查询def Consumedetail(self):self.consumedetail = tk.Tk()self.consumedetail.title('XX学院明细查询')self.consumedetail.geometry("1000x600")# 加载滚动条scrollBar = tk.Scrollbar(self.consumedetail)scrollBar.pack(side = tk.RIGHT,fill = tk.Y)self.tree = ttk.Treeview(self.consumedetail, columns=('outid', 'name', 'opfare', 'opdt','dscrp'), show="headings", displaycolumns="#all",yscrollcommand = scrollBar.set)self.tree.pack()self.tree.heading('outid', text="学号", anchor=tk.W)self.tree.heading('name', text="姓名", anchor=tk.W)self.tree.heading('opfare', text="交易金额", anchor=tk.W)self.tree.heading('opdt', text="交易日期", anchor=tk.W)self.tree.heading('dscrp', text="交易类型", anchor=tk.W)# 设置关联scrollBar.config(command = self.tree.yview)# 每次打开清空页面for item in self.tree.get_children():self.consumedetail.tree.delete(item)sql = "select a.outid ,a.name ,b.opfare,b.opdt,b.dscrp from base_customers a,rec_cust_acc b where a.customerid = b. customerid and b.opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and b.opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') order by b.opdt desc"preopdt=self.pretimeInput.get()nextopdt=self.nexttimeInput.get()data = self.cursor.execute(sql,(preopdt,nextopdt)).fetchall()# print(data)# data = [['2013090101','张三','100','2023-10-19','PC存款']]for itm in data:self.tree.insert("",tk.END,values=itm)self.tree.pack(padx=10,pady=10, fill=tk.BOTH,expand=1)exportbtn = tk.Button(self.consumedetail,text='导出',width=8,command=self.export).pack()# 汇总查询def sumDetail(self):sql = "select sum(opfare),count(acccode),dscrp from rec_cust_acc where opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') group by dscrp"self.sumtail = tk.Tk()self.sumtail.title('XX学院汇总查询')self.sumtail.geometry("800x600")# 加载滚动条# exportbtn = Button(sumtail,text='导出',width=8,command=export).pack()scrollBar = tk.Scrollbar(self.sumtail)scrollBar.pack(side = tk.RIGHT,fill = tk.Y)self.tree = ttk.Treeview(self.sumtail, columns=('sum', 'count', 'dscrp'), show="headings", displaycolumns="#all",yscrollcommand = scrollBar.set)self.tree.pack()self.tree.heading('sum', text="总金额", anchor=tk.W)self.tree.heading('count', text="总次数", anchor=tk.W)self.tree.heading('dscrp', text="交易类型", anchor=tk.W)# 设置关联scrollBar.config(command = self.tree.yview)# 每次打开清空页面for item in self.tree.get_children():self.tree.delete(item)# sql = "select a.outid ,a.name ,b.opfare,b.opdt,b.dscrp from base_customers a,rec_cust_acc b where a.customerid = b. customerid and b.opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and b.opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') order by b.opdt desc"preopdt=self.pretimeInput.get()nextopdt=self.nexttimeInput.get()data = self.cursor.execute(sql,(preopdt,nextopdt)).fetchall()# print(data)for itm in data:self.tree.insert("",tk.END,values=itm)self.tree.pack(padx=10,pady=10, fill=tk.BOTH,expand=1)exportbtn = tk.Button(self.sumtail,text='导出',width=8,command=self.export).pack()# 个人明细def personDetail(self):if(self.outidInput.get()):print('outid not is null')sql="select a.outid ,a.name ,b.opfare,b.oddfare,b.opdt,b.dscrp from base_customers a,rec_cust_acc b where a.customerid = b. customerid and b.opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and b.opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') and a.outid = :outid order by b.opdt desc"outidname = self.outidInput.get()elif(self.nameInput.get()):sql="select a.outid ,a.name ,b.opfare,b.oddfare,b.opdt,b.dscrp from base_customers a,rec_cust_acc b where a.customerid = b. customerid and b.opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and b.opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') and a.name like :name order by b.opdt desc"outidname = self.nameInput.get()else:messagebox.showwarning("提示", "请输入学号或者姓名!")returnself.persontail = tk.Tk()self.persontail.title('XX学院个人查询')self.persontail.geometry("1200x600")# 加载滚动条# exportbtn = Button(persontail,text='导出',width=8,command=export).pack()scrollBar = tk.Scrollbar(self.persontail)scrollBar.pack(side = tk.RIGHT,fill = tk.Y)self.tree = ttk.Treeview(self.persontail, columns=('outid', 'name', 'opfare','oddfare', 'opdt','dscrp'), show="headings", displaycolumns="#all",yscrollcommand = scrollBar.set)self.tree.pack()self.tree.heading('outid', text="学号", anchor=tk.W)self.tree.heading('name', text="姓名", anchor=tk.W)self.tree.heading('opfare', text="交易金额", anchor=tk.W)self.tree.heading('oddfare', text="账户余额", anchor=tk.W)self.tree.heading('opdt', text="交易日期", anchor=tk.W)self.tree.heading('dscrp', text="交易类型", anchor=tk.W)# 设置关联scrollBar.config(command = self.tree.yview)# 每次打开清空页面for item in self.tree.get_children():self.tree.delete(item)# sql = "select a.outid ,a.name ,b.opfare,b.opdt,b.dscrp from base_customers a,rec_cust_acc b where a.customerid = b. customerid and b.opdt >= to_date(:preopdt,'yyyy-MM-dd HH24:mi:ss') and b.opdt <= to_date(:nextopdt,'yyyy-MM-dd HH24:mi:ss') order by b.opdt desc"preopdt=self.pretimeInput.get()nextopdt=self.nexttimeInput.get()# print(outidname)data = self.cursor.execute(sql,(preopdt,nextopdt,outidname)).fetchall()# print(data)for itm in data:self.tree.insert("",tk.END,values=itm)self.tree.pack(padx=10,pady=10, fill=tk.BOTH,expand=1)def export():# 导出export # 打开文件夹选择对话框folder_path = filedialog.asksaveasfilename(title='请选择一个文件',filetypes=[("CSV", ".csv")]) # 更新标签文本print(folder_path)list = []for row_id in self.tree.get_children():list.append(self.tree.item(row_id)['values'])with open(f'{folder_path}.csv','w',newline='') as csvfile:fieldnames = ['学号', '姓名', '交易金额','账户余额','交易日期','交易类型']writer = csv.writer(csvfile)writer.writerow(fieldnames)writer.writerows(list)exportbtn = tk.Button(self.persontail,text='导出',width=8,command=self.export).pack()def export(self):# 导出export # 打开文件夹选择对话框# 更新标签文本# print(folder_path)list = []columns = []# 获取表格内容idfor row_id in self.tree.get_children():list.append(self.tree.item(row_id)['values'])print(len(self.tree.get_children())) # 通过第一行获取列数生成标题# print(self.tree.item)if len(self.tree.get_children()) != 0:print('ok')folder_path = filedialog.asksaveasfilename(title='请选择一个文件',filetypes=[("CSV", ".csv")]) for i in range(0,len(self.tree.item('I001')['values'])):columns.append(self.tree.heading(column=i)['text'])# 导出csvwith open(f'{folder_path}.csv','w',newline='') as csvfile:fieldnames = columnswriter = csv.writer(csvfile)writer.writerow(fieldnames)writer.writerows(list)else:messagebox.showwarning("提示", "没有数据,无法导出")returnif __name__ == "__main__":root = tk.Tk()app = mainApp(root)root.mainloop()
相关文章:

Python桌面应用之XX学院水卡报表查询系统(Tkinter+cx_Oracle)
一、功能样式 Python桌面应用之XX学院水卡报表查询系统功能: 连接Oracle数据库,查询XX学院水卡操作总明细报表,汇总数据报表,个人明细报表,进行预览并且支持导出报表 1.总明细报表样式 2.汇总明细样式 3.个人明细…...

ubuntu 中使用Qt连接MMSQl,报错libqsqlodbc.so: undefined symbol: SQLAllocHandle
Qt4.8.7的源码编译出来的libqsqlodbc.so,在使用时报错libqsqlodbc.so: undefined symbol: SQLAllocHandle,需要在编译libqsqlodbc.so 的项目pro文件加上LIBS -L/usr/local/lib -lodbc。 这里的路径根据自己的实际情况填写。 编辑: 使用uni…...
笔试,猴子吃香蕉,多线程写法
package demo;import java.util.concurrent.CountDownLatch;/*** description: 猴子吃香蕉* author: wxm* create: 2023-10-23 14:01**/ public class Main {public static void main(String[] args) throws InterruptedException {Monkey[] m new Monkey[3];Resource r new …...

安装docker ,更换docker版本
docker dockerd & containerd Dockerd(Docker 守护进程)在其底层使用 Containerd 来管理容器。Containerd 是一个开源的容器运行时管理器,由 Docker 公司于2017年开发并开源,它负责实际的容器生命周期管理。 以下是 Docker 守…...

英语小作文写作模板及步骤(1)
...

编写hello驱动程序
hello的驱动编写 编写驱动程序的步骤 1.确定主设备号,也可以让内核分配 2.定义自己的 file_operations 结构体 3.实现对应的 drv_open/drv_read/drv_write 等函数,填入 file_operations 结构 体 4.把 file_operations 结构体告诉内核:regist…...
ZYNQ中断例程
GPIO 中断系统初始化流程: 第一步:初始化 cpu 的异常处理功能 第二步:初始化中断控制器 第三步:向 CPU 注册异常处理回调函数; 第四步:将中断控制器中的对应中断 ID 的中断与中断控制器相连接 第五步:设置 …...

常用linux命令 linux_cmd_sheet
查看文件大小 ls -al 显示每个文件的kb大小 查看系统日志 dmesg -T | tail 在 top 命令中,RES 和 VIRT(或者 total-vm)是用来表示进程内存使用的两个不同指标,它们之间有以下区别: RES(Resident Set Size…...

【proteus】8086 写一个汇编程序并调试
参考书籍:微机原理与接口技术——基于8086和Proteus仿真(第3版)p103-105,p119-122. 参考程序是p70,例4-1 在上一篇的基础上: 创建项目和汇编文件 写一个汇编程序并编译 双击8086的元件图: …...
大数据之LibrA数据库常见术语(四)
Failover 指当某个节点出现故障时,自动切换到备节点上的过程。反之,从备节点上切换回来的过程称为Failback。 Freeze 在事务ID耗尽时由AutoVacuum Worker进程自动执行的操作。FusionInsight LibrA会把事务ID记在行头,在一个事务取得一行时&…...
Docker基础知识
文章目录 Docker Docker 一次构建,处处运行,类似于JVM 虚拟机是软件硬件(需要Hypervisors实现硬件资源虚拟化): 资源占用大启动慢(虚拟机是分钟级,Docker是秒级)冗余步骤多 sha2…...
swoole 是什么?
Swoole是一个为PHP用C和C编写的基于事件的高性能异步& 协程并行网络通信引擎; 使 PHP 开发人员可以编写高性能的协程 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IO…...
我想要一个勋章
目录 一、背景二、过程三、总结 一、背景 十年前结缘,也许是冥冥中自有天注定,注定要给自己多加一个今天的节日。 二、过程 一个勋章,一个有意义的标志。 一个勋章,一个时间轮上的帧。 一个勋章,一个二进制的节点。…...

微信小程序设计之主体文件app-json-pages
一、新建一个项目 首先,下载微信小程序开发工具,具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后,注册小程序账号,具体注册方法,可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…...

C语言-面试题实现有序序列合并
要求: a.输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。 数据范围: 1≤n,m≤1000 1≤n,m≤1000 , 序列中的值满足 0≤val≤30000 输入描述: 1.输入包含三行, 2.第一行包含两个正整数n, m&am…...

Android12 启动页适配
印象中,在2022年末接到了一个针对Android12启动页适配的需求,当时也使用了一些适配方案,也写了一个Demo,但是最终没有付诸适配行动;当然并不是适配失败,而是根据官方适配方案适配后太丑了… 1024纪念文章&a…...

【微服务保护】初识 Sentinel —— 探索微服务雪崩问题的解决方案,Sentinel 的安装部署以及将 Sentinel 集成到微服务项目
文章目录 前言一、雪崩问题及其解决方案1.1 什么是雪崩问题1.2 雪崩问题的原因1.3 解决雪崩问题的方法1.4 总结 二、初识 Sentinel 框架2.1 什么是 Sentinel2.2 Sentinel 和 Hystrix 的对比 三、Sentinel 的安装部署四、集成 Sentinel 到微服务 前言 微服务架构在现代软件开发…...
20231023 比赛总结
比赛链接 反思 A 花了很长时间,幸亏没怎么调就对了,以后还是应该先看其他题的 括号匹配题的套路感觉没有掌握透,感觉无非就是单调栈,哈希,折线图 B 感觉比 T 1 T1 T1 简单 C 正解还是很妙的,但 68…...

Vite创建vue3+ts+pinia+vant项目起步流程
pnpm介绍&安装 本质上他是一个包管理工具,和npm/yarn没有区别,主要优势在于 包安装速度极快磁盘空间利用效率高 安装: npm i pnpm -g使用: npm命令pnpm等效npm installpnpm installnpm i axiospnpm add axiosnpm i webpa…...

JVM 类的加载子系统
文章目录 类的加载过程加载阶段链接阶段初始化 类的加载器测试代码中获取对应的加载器获取加载器加载的路径不同类对应的加载器自定义加载器自定义加载器的方式 获取类的加载器的方式双亲委派机制双亲委派机制的好处 Java 的 SPI 机制1. 接口定义2. 具体实现3. 配置 META-INF/s…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...