分类目录编程

compose

    compose_version = '1.0.2'
    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.activity:activity-ktx:1.3.1'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.ui:ui-util:$compose_version"

Text()
Image(painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = “无障碍说明”)
//bitmap Bitmap ImageBitmap 位图 ImageVector矢量图 Painter painterResource()

https://github.com//google/accompanist
implementation ‘dev.chrisbanes.accompanist:accompanist-coil:0.6.2’
CoilImage(data = “”,contentDescription = “”)

Modifier

    Box() {

    }
    Column() {
        上下
    }
    Row() {
        左右
    }

springboot定时任务

1:
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz-jobs -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

2:
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

3.
 <!--http://www.hutool.cn/-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.5.1</version>
        </dependency>

QT network

网络模块介绍
类名 说明 中文
QAbstractNetworkCache The interface for cache implementations 缓存实现的接口
QNetworkCacheMetaData Cache information 缓存信息
QHstsPolicy Specifies that a host supports HTTP Strict Transport Security policy (HSTS) 指定主机支持HTTP严格传输安全策略(HSTS)
QHttpMultiPart Resembles a MIME multipart message to be sent over HTTP 类似于通过HTTP发送的MIME多部分消息
QHttpPart Holds a body part to be used inside a HTTP multipart MIME message 在HTTP多部分MIME消息中保存要使用的身体部分
QNetworkAccessManager Allows the application to send network requests and receive replies 允许应用程序发送网络请求并接收回复
QNetworkCookie Holds ne network cookie 保持网络cookie
QNetworkCookieJar Implements a simple jar of QNetworkCookie objects 实现一个简单的QNetworkCookie对象
QNetworkDiskCache Very basic disk cache 非常基本的磁盘缓存
QNetworkReply Contains the data and headers for a request sent with QNetworkAccessManager 包含使用QNetworkAccessManager发送的请求的数据和标题
QNetworkRequest Holds a request to be sent with QNetworkAccessManager 持有使用QNetworkAccessManager发送的请求
QNetworkConfigurationManager Manages the network configurations provided by the system 管理系统提供的网络配置
QNetworkConfiguration Abstraction of one or more access point configurations 抽象一个或多个接入点配置
QNetworkSession Control over the system’s access points and enables session management for cases when multiple clients access the same access point 控制系统的接入点,并为多个客户端访问同一接入点的情况启用会话管理
QAuthenticator Authentication object 认证对象
QDnsDomainNameRecord Stores information about a domain name record 存储有关域名记录的信息
QDnsHostAddressRecord Stores information about a host address record 存储有关主机地址记录的信息
QDnsLookup Represents a DNS lookup 表示DNS查找
QDnsMailExchangeRecord Stores information about a DNS MX record 存储有关DNS MX记录的信息
QDnsServiceRecord Stores information about a DNS SRV record 存储有关DNS SRV记录的信息
QDnsTextRecord Stores information about a DNS TXT record 存储有关DNS TXT记录的信息
QHostAddress IP address IP地址
QHostInfo Static functions for host name lookups 用于主机名查找的静态函数
QNetworkDatagram The data and metadata of a UDP datagram UDP数据报的数据和元数据
QNetworkAddressEntry Stores one IP address supported by a network interface, along with its associated netmask and broadcast address 存储网络接口支持的一个IP地址及其关联的网络掩码和广播地址
QNetworkInterface Listing of the host’s IP addresses and network interfaces 列出主机的IP地址和网络接口
QNetworkProxy Network layer proxy 网络层代理
QNetworkProxyFactory Fine-grained proxy selection 细粒度代理选择
QNetworkProxyQuery Used to query the proxy settings for a socket 用于查询套接字的代理设置
QAbstractSocket The base functionality common to all socket types 所有套接字类型通用的基本功能
QLocalServer Local socket based server 本地套接字服务器
QLocalSocket Local socket 本地套接字
QSctpServer SCTP-based server 基于SCTP的服务器
QSctpSocket SCTP socket SCTP套接字
QTcpServer TCP-based server 基于TCP的服务器
QTcpSocket TCP socket TCP 套接字
QUdpSocket UDP socket UDP 套接字
QSslCertificate Convenient API for an X509 certificate 简单的X509证书API
QSslCertificateExtension API for accessing the extensions of an X509 certificate 用于访问X509证书扩展名的API
QSslCipher Represents an SSL cryptographic cipher 表示SSL加密密码
QSslConfiguration Holds the configuration and state of an SSL connection 保持SSL连接的配置和状态
QSslDiffieHellmanParameters Interface for Diffie-Hellman parameters for servers 服务器的Diffie-Hellman参数接口
QSslEllipticCurve Represents an elliptic curve for use by elliptic-curve cipher algorithms 表示椭圆曲线密码算法使用的椭圆曲线
QSslError SSL error SSL错误
QSslKey Interface for private and public keys 私钥和公钥的接口
QSslPreSharedKeyAuthenticator Authentication data for pre shared keys (PSK) ciphersuites 用于预共享密钥(PSK)密码套件的认证数据
QSslSocket SSL encrypted socket for both clients and servers 用于客户端和服务器的SSL加密套接字

vue使用说明

url参数获取

import Qs from 'qs'
// hash模式
// const query = Qs.parse(location.hash.substring(3))
// history模式
const query = Qs.parse(location.search.substring(1))
let autoId = query.id
// console.log('autoId ' + autoId)
Vue.prototype.autoId = autoId

    return {
      autoId: this.autoId,
      }

 <div>设备编号:{{autoId}}</div>

vue 点击打开新窗口

<el-button  type="primary" class="r" @click="getUrl">按钮</el-button>

methods中:
getUrl(){
  let routeData = this.$router.resolve({ path: '/test' });
  window.open(routeData.href, '_blank');
},

路由文件 router/index.js中:
{
  path: '/test',
  component: () => import('@/views/newPage/test'),
  hidden: true
},

Netty

<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.48.Final</version>
        </dependency>

NioEventLoop-->thread客服端接收客户端连接
Channel连接的封装-->Socket                       PipeLine逻辑处理链-->Logic Chain
ChanneHandler-->Logic逻辑处理链的处理   ByteBut数据流读写-->IO Bytes

BIO:一个线程负责连接,一请求一应答 阻塞同步
伪异步IO:线程池负责连接,M请求N应答 阻塞同步
NIO:缓冲区Buffer,通道Channel,多路复用器Selector 非阻塞同步
AIO:连接注册读写事件和回调函数,读写方法异步,主动通知程序 非阻塞异步

服务端启动
1. 创建服务端Channel
bind()用户代码入口->initAndRegister()初始化并注册->newChannel()创建ServerSocketChannel ->newSocket()通过JDK创建底层jdk channel->NioServerSocketChannelConfig()配制TCP参数类->AbstractNioChannel()->configureBlocking(false)阻塞模式:AbstractChannel()创建id,undafe,pipeline
1. 初始化服务端Channel
init()初始化入口->set ChannelOptions,ChannelAttrs->set ChildOptions,ChildAttrs->config handler配制服务端pipeline逻辑处理链->add ServerBootstrapAcceptor添加连接器
1. 注册事件轮寻器selector
AbstractChannel.register(channel)入口->this.eventLoop=eventLoop绑定线程->resgiter0()实际注册–doRegister()调用JDK底层注册:invokeHandlerAddIfNeeded()用户回调->fireChannelRegistered)传播事件
1. 端口绑定
AbstractUnsafe.bind()入口->doBind()->javaChannel().bind()JDK底层绑定->pipeline.fireChannelActive()事件传播->HeadContext.readIfIsAutoRead()


NioEventLoop
每次执行创建一个线程实体FastThreadLocalThread,线程命名规则nioEventLoop-1-xx
创建->new NioEventLoopGroup()线程组,默认2*cpu->new ThreadPerTaskExecutor)线程创建器->for(){newChild()}构造NioEventLoop->chooserFactory.newChooser()线程选择器

newChild()
保存x线程执行器ThreadPerTaskExecutor
创建一个MpscQueue
创建一个selector

启动->bind()->execute(task)入口->startThread()->doStartThread()创建线程->ThreadPerTaskExecutor.execute()->thread=Thread.currentThread()->NioEventLoop.run()启动->for(;;)->select()检查是否有IO事件->processSelectedKeys()处理io事件->runAllTasks()处理异步任务队列


新连接接入
检测新连接->创建NioSocketChannel->分配线程及注册selector->向selector注册读事件

processSwlectdKey(key,channel)入口->NioMessageUnsafe.read()->doReadMessages()循环while->javaChannel().accept()

new NioSocketChannel(parent,ch)入口->AbstractNioByteChannel(p,ch,op_read)->configureBlocking(false)&save op:-:create id,unsafe,pipeline->new NioSocketChannelConfig()->setTcpNoDelay(true)禁止Nagle算法

channel分类
NioServerSocketChannel
NioSocketChannel
Unsafe

head->ServerBootstrapAcceptor->Tail


pipeline
1. pipeline初始化
在创建Channel的时候创建,节点数据结构ChannelHandlerContext,两大哨兵head和tail
1. 添加删除ChannelHandler
注意顺序
1. 事件和异常的传播
inBound head->a1->b1->…->tail
在处理ByteBuf时不往下传播注意处理要释放资源,SimpleChannelInboundHandler已实现自动释放,都没有处理的在tail中会释放
outBound head<-a2<-b2<-…<-tail 异常触发链 b1->…->a2->b2->…->tail 最好在链最后添加异常处理器,没有处理过的在最后能一同处理


ByteBuf
内存与内存管理器的抽象
不同规格大小和不同类别的内存的分配策略
内存的回收过程

结构:discardable bytes |readable bytes|writable bytes
批针:0<=readerIndex<=writerIndex<=capacity<=maxCapacity
方法:read write set(在当前位置操作,不会移动指针) mark(保存指针),reset(复位指针)
分类:ByteBuf<-AbstratByteBuf<-
PooledHeapByteBuf:<-PooledUnsafeHeapByteBuf
PooledUnsafeDirectByteBUf:
PooledDirectByteBuf:
UnPooledHeapByteBuf:<-UnPooledUnsafeHeapByteBuf
UnPooledUnsafeDirectByteBUf:
UnPooledDirectByteBuf
Pooled从预先分配好的内存操作 UnPooled直接API分配内存
Unsafe可以通过内存直接拿到 非Unsafe没有依赖底层内存JDK
Heap堆上分配内存 Direct虚拟机外的内存中分配了一块缓冲区,不参与GC,手动释放
Direct Buffer创建和销毁的代价很高,所以要用在尽可能重用的地方。 比如周期长传输文件大采用direct buffer,不然一般情况下就直接用heap buffer 就好。

Thread -> PoolThreadCache(tinyCaheSize smallCacheSize normalCacheSize) -> Area
(SubPage)0–>tiny(N*16B共32种)<--512B-->small<–8K(page 512B,1K,2K,4K)–normal—16M(Chunk 8K,16K,32K)—>huge

释放:连续的内存区段加到缓存,标记连续的内存区段为未使用,ByteBuf加到对象池


解码 ByteToMessageDecoder
累加字节流->调用子类的decode方法解析->解析的ByteBuf向下传播

基于固定长度 FixedLengthFrameDecoder:n长度
基本行解码 LineBasedFrameDecoder:\n,\r\n换行结束符,丢弃和非丢弃模式
基于分隔符 DelimiterBasedFrameDecoder 先行处理,找到最小分隔符,解码
基于长度域 LengthFieldBasedFrameDecoder lengthFieldOffset:2偏移lengthFieldLength:2长度


编码 writeAndFlush
从tail节点往前传播-逐个调用channelHandler的write方法->逐个调用channelHandler的flush方法

模拟百万连接
突破局部文件限制和全局文件限制

Server 8000~8100 Client 1025~65535
ulimit -n
sudo vi /etc/security/limits.conf 增加
* hard nofile 1000000
* soft nofile 1000000

cat /proc/sys/fs/file-max
临时使用,重启回到10000
sudo -s
echo 100000 > /proc/sys/fs/file-max
exit
持久使用
/etc/sysctl.conf 增加
fs.file-max=1000000
sudo sysctl -p /etc/sysctl.conf 后重启

业务优化
1. 在单个业务中使用线程池
1. 给handler指定使用JDK的线程池,做不到内存共享

C++

发展

C 面像过程 ->1979 C 带类的C->1983 C++面像对象OOP->C++98 STL标准库-> 2011 C++11 Boost库 -> 14->17->20 每三年一版
三大特性:封装 继承 多态
强大的抽象封装能力
高性能
低功耗
语法相对复杂,学习曲线较陡
注意开发规范,否则代码难维护
开发成本高

.cpp编译 -> .asm -> 链接.obj -> .exe
qt自带gcc windows
xocde glang
g++
源码.c -E预处理.i -S编译.s -c汇编.o gcc 链接 -o 指定输出文件名
一步完成 gcc -o a.exe a.c

教程

  1. https://www.runoob.com/cplusplus/cpp-tutorial.html
    char 1 -128~127|0~255
    shor int 2 -32768~32767|0-65535
    long int 4 -21247483648~2147483647|0~4294967295
    int 4 -21247483648~2147483647|0~4294967295
    float 4 3.4e+/-38
    double 8 1.7e+/-308
    long double 8 1.7e+/-308
    boolr 1 true/false
    wchart_t 2

C++ keywords: https://en.cppreference.com/w/cpp/keyword
定义常量 #define(宏替换) const(建议)
前缀0x十六进制 0八进制 L’x’宽字符 后缀U符号 L long
\转义字符 \ \’ \” \? \a 警报铃声 \b 退格键 \f 换页符 \n 换行符 \r 回车 \t 水平制表符 \v 垂直制表符 \ooo 一到三位的八进制数 \xhh… 一个或多个数字十六进制数

逻辑运算&& || ! 位运算 & ^ | ~ << >>(对有符号的数,尽可能不要使用右移运算)
sizeof(), Condition ? X:Y, , . , ->, Cast(不建议使用),&(取变量地址),*(指向变量)

补码(两种计算方式) 大小端

注释: // /* */

typedef struct{
short Sunday=0;
….
}Week;

默认成员权限公开的
struct A{
}
默认成员权限私有的
class Trace{
public:
virtual double Area() const=0; //多态,子类方法实现不一致时加virtual,const=0表示简单实现,虚的
}
typedef enum __COLOR{
RED,
}color;

union Score{
}
定义常量 #define const
声明 enum color{red,gree}; color color1;

注意结构体数据对齐问题32位CPU4字节
连续分配修改编译选项:
V C++: #pragma pack(n)
g++: attribute(aligned(n)) attribute(packed)

int arr[2] = {1,2}; arr[2] =5;int * p =arr;*(p+2)=5;
int len = sizeof(arr)/sizeof(arr[0]);
差一错误, (]左闭右开,
循环时尽可能满足”空间局部性”
新型数组vector(面向对象方式的动态数组)
字符串是以空字符(‘\0′)结束的字符数组,在声明时应预留一个额外的元素
双引号是字符串,单引号是一个字
char c1=0; ->0x00 char c2=’\0′; ->0x00 char c3=’0’;->0x30
UTF-8:1byte,兼容ASCII码,效率高,变长(不方便内部随机访问),无字节序问题
UTF-16:BE/LE 2bytes 定长(不方便内部随机访问),有字节序问题
UTF-32:BE/LE 4bytes 定长(不方便内部随机访问),有字节序问题
windows的文件可能有BOM,在其它平台使用可去掉

指针表示方法T,存贮地址,间接访问值的操作t,指针自身也有地址t,&t
char ch=’a’; char* cp=&ch;
表达式 左值 右值
&ch 非法 ch的地址
*cp ch的地址 ch的值=a
*cp+1 非法 ch的值+1=b
*(cp+1) ch的地址+1 ch的地址+1的值 注意内存溢出

char s[] = ‘hello’; //数组s不可变,s[index]的值可以变
char* P1 = s;
char* p= “hello”; //指针p可变,p[index]的值是否可变取决于指区间的存储区域是否可变
float* P=&F;
指针指向的内容P = 内容F <- 内容地址&F
int
a[4];批针的数组,数组中的每个内容是指针
int(b)[4]; 数组的指针,指针指向的是一个数组
指向指针的指针 int** c=&P1;
指针确保初始化并赋值,小心意外发生
int
a = NULL;不指向任何东西时的状态,指针不用时置NULL,使用前先判断是否为NULL,nullptr(新)
定义函数指针: typedef void(*FuncPtr)(); FuncPtr funcPtr;

const 常量,修饰不充许修改,先看左侧最近的部分,没有则看右侧
char const* s; const char *; 内容不可变
char* const s; 指针不可变
char const* const s; 指什及内容都不可变

全局初始化区GVAR
全局末初始化区bss
代码区text
堆 heap-队列 先进先出 ,整个程序范围内new,malloc建立,注意delete,free释放,
栈 stack 先进后出,函数体内,语句块{},windows默认大小1M,linux8/10M,ulimit -s查看

内存分配 地址低–>高
代码–>数据(GVAR–>常量–>BSS–> 堆cd )–> 空闲内存 <–栈cc <–系统保留

资源管理方案RAII,依托栈和析构函数管理所有资源,智能指针代表std:auto_ptr(C++11废弃,17删除),销毁时管理的对象也自动deldete,会发生所有权转移
unique_ptr(局限较大),专属所有权,不支持复制和赋值,可以使用std::move()进行控制权的转移
auto w=std:make_unique< int >(10); *(w.get());
auto i = unique_ptr< int>(new int(10));
boost:shared_ptr,引用计数共享一个对象,引用计数为0时没有被使用,可以进行析构销毁,防止循环引用
weak_ptr,观察者模式与shared_ptr共同工作,只对shared_ptr进行引用,不计数,shared_ptr销毁时也一同销毁.

引用是一种特殊的指针,不充许修改的指针,int x=1;int& rx=x;相当于小名,别名

string.h 字符串常用的操作,尽量使用安全的API
底层操作有风险时在预处理器定义#define _CRT_SECURE_NO_WARNINGS,关闭安全警告C4996
strlen(s) 返回字符串的长度,不包含’\0′
strlen_s()
strcmp(s1,s2) 相同返回0,s1<s2返回小于0,否则大于0,自左向右以ASCII值比较
strcpy(s1,s2) 字符串s2拷贝复制到s1,注意s1空间长度
strcpy_s(s1,STR_LEN_NUM,s2)
strnpy(s1,s2,n)字符串s2前n个字符拷贝复制到s1,注意s1空间长度
strnpy_s(s1,STR_LEN_NUM,s2,n)
strcat(s1,s2) 字符串s2拼接到s1,注意s1空间长度
strcat_s(s1,STR_LEN_NUM,s2)
strchr(s1,ch) 查找s1中字符ch的第一次出现位置
strstr(s1,s2) 查找s1中字符串s2的第一次出现位置

string(新)namespace std 对性能要求不是特别高的可以使用
string s; string s=”hello”; string s (“hello”); string s= string(“hello”);
s.length() s.size() s.capacity() == != > >= < <=(比较原则同老版)
转为C风格的字符串const char* c_str = s.c_str();
随机访问某个字符 s[0] == “h”;
字符拷贝 string s2 = s;
连接 +, += string s3 = s+s2; s += s2;

if(p !=NULL){
….
}else if(…){
….
}else{
….
}

switch(){
case: xxx:
{…
break;}
default:
break;
}
while(..){…}
do{…}while(..);
for (…;..;..){…}

重载时函数另一种指针方式调用,每个函数都有一个入口地址
int(p)(int); 定义指针函数,与test函数相对应,数据类型(指针变量名)(参数表)
p=test; 指向test函数
int result = p(1); 调用test函数
注意:int
p(int); //是函数,返回的是一个指针

命名空间
namespace coust{
int test(int);
}
using namespace coust
coust::test(1)

VC++ 调作约定设置影响传参(默认/Gd)
优化-内联函数的扩展->/Ob1
inline int Xxxx(){} 内联过于复杂可能失效

传统的 printf,scanf,getch,gets..坑多可移植性差,不可编程
C++I/O流,可编程,简化编程iostream.h,fstream.h
ios<--istream<--cin
                    <--ifstream
                    |<--iostream <--fstream
    <--ostream<--ofstream
                    <--cout,cerr,clog

streambuf<--strstreambuf
                <--filebuf

IO标准缓存模式:按块(文件),按行(\n),不缓存
#include <iostream> //流
#include <string.h> //使用字符串
#include <string> //使用新字符串
#include <assert> //断言
#include<vector> //动态数组
#include<list> //列表
#include<queue> //队列
#include<stack> //栈
#include<map> //map
#include<algorithm> //算法
#include<memory> //内存
#include <math.h> //数学
vector<int> vec={1,2};
vec.push_back(3);vec.capacity/size(容量/已存贮的个数)
vec.insert(--vec.end(),4);
vec.pop_back();vec.erase(vec.end()-1);

避免同一个文件被include多次
#ifndef _SOMEFILE_H
#define _SOMEFILE_H
…通过宏来防止,可移植性好,无法防止宏名重复,不易排错
#endif //_SOMEFILE_H

#pragma once 通过编译器来防止,易排错,可移植性不好

浅拷贝:只拷贝指针地址,易引发多次释放
深拷贝:拷贝指针指向重新分配堆内存,浪费空间,但不会导致多次释放
写时复制优化策略
引用计数
C++新标准的移动语义

void* NULL nullptr

//C定义
#define NULL ((void *) 0)
//C++定义
#ifndef NULL
    #ifdef _cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif
//C++11定义
nullptr->(void *)0 ,NULL ->0;

类型转换
隐式转换: double f = 1.0/2;
显式转换: (类型说明符)(表达式)
C类型转换时任意类型之间都可以转换,编译器无法判断其正确性,难于错误定位
C++:const_cast用于转换指针或引用,去掉类型的const属性
reinterpret_cast重新解释类型,很危险操作,不检查指向内容,也不检查指针类型本身,但要转换前后的类型所占用内存大小一致,否则引发编译错误
static_cast用于基本转换,有继承关系对象和类指针之间的转换,由程序员确保转换是安全的
dynamic_cast 只能用于含有虚函数的类,必须用在多态体系中,向下转换时如有非法情况对于指针返回NULL


编程思想

设计模式:面向对象可复用的常见23种,反模式,企业应用构架模式…
创建型:结构型:行为型
单列模式-思路有一个私有构造函数,无法通过new直接实例化,包含一个静态私有成员变量instance和静态公有方法instance(),将构造与析构私有化
观察者模式-订阅,解耦
适配器模式(Adapter)-1使用多重继承,接口继承方式.2组合的方式

泛型编程思想
更加直接抽象,静态期多态,将算法 与特定类型,结构剥离,尽可能代码复用 template


STL
空间配制器allocator
容器 序列式string vector list deque 关联式map set multimap multiset
适配器stack queue priority_queue
仿函数greater less …
算法find swap reverse sort merge…
迭代器iterator const_iterator reverse_iterator const_reverse_iterator

for_each()
map<string,double> sts;
sts[“lim”]=99.9; //可修改值
sts.insert(pair<string,double>(“zs”,100.0));
sts.insert(map<string,double>::value_type(“lx”,96.8));
iter =sts.begin();
注意迭代器erase时失效问题,sts.erase(iter++);iter =sts.erase(iter);iter=sts.find(“zs”);sts.erase(iter); int n= sts.erase(‘”zs”);
sts.erase(sts.begin(),sts.end());


引入C
extern “C”{
#include “libavformat/avformat.h”
}

显性包函
#pragma comment(lib,”avformat.lib”)
附加目录
属性-常规:输入-附加依赖项


UI

  1. Duilib
  2. clayui
  3. libuiDK windows
  4. QT IDE->Qt Creator
    https://www.qt.io/
  5. wxWidgets库

网络
1. Linux下的Muduo

  1. BOOST的ASIO库和非boost库版的asio
    http://think-async.com/
    是一个异步IO库,封装了对Socket的常用操作,简化了基于socket程序的开发。支持跨平台。 注:要配置Boost库,还要熟悉Boost,还是麻烦;

  2. libev
    是一个C语言写的,只支持linux系统的库

  3. libuv
    linux下用libev实现,Windows下用IOCP实现;
  4. Libevent
    是一个C语言写的网络库, 官方主要支持的是类linux 操作系统, 最新的版本添加了对windows的IOCP的支持。由于IOCP是异步IO,与linux下的POLL模型,EPOLL模型,还有freebsd的KQUEUE等这些同步模型在用法上完全不一致,所以使用方法也不一样,就好比ACE中的Reactor和Proactor模式一样, 使用起来需要转变思路。如果对性能没有特别的要求, 那么使用libevent中的select模型来实现跨平台的操作, select模型可以横跨windows, linux, unix,solaris等系统。
  5. ACE库
    http://www.cs.wustl.edu/~schmidt/ACE.html
    是一个大型的中间件产品,代码20万行左右,过于宏大,一堆的设计模式,架构了一层又一层,使用的时候, 要根据情况,看你从那一层来进行使用。支持跨平台。注:除非特别需要,否则不建议;
  6. Qt有nerwork

  7. POCO
    POCO C++ Libraries 提供一套 C++ 的类库用以开发基于网络的可移植的应用程序,功能涉及线程、线程同步、文件系统访问、流操作、共享库和类加载、套接字以及网络协议包括:HTTP、 FTP、SMTP 等;其本身还包含一个 HTTP 服务器,提供 XML 的解析和 SQL 数据库的访问接口。POCO库的模块化、高效的设计及实现使得POCO特别适合嵌入式开发。在嵌入式开发领域,由于C++既适合底层(设备I/O、中断处理等)和高层面向对象开发,越来越流行。
    http://pocoproject.org/

  8. libcurl
    libcurl是免费的轻量级的客户端网络库,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet, TFTP. 支持SSL, HTTP POST, HTTP PUT, FTP上传, HTTP form上传,代理,cookies, 用户名与密码认证。
    如果你开发的是客户端,libcurl是一个不错的选择。
    http://curl.haxx.se/libcurl/

  9. c++ sockets library
    封装了sockets C API的C++类库。支持SSL, IPv6, tcp 和 udp sockets, sctp sockets, http协议, 高度可定制的错误处理。
    http://www.alhem.net/Sockets/

  10. C++ Socket Class for Windows ,http://www.adp-gmbh.ch/win/misc/sockets.html;
    注:这个文章的文件不可以下载自己复制 保存 h 和 cpp文件;
    觉得很不错,也很简单,例子很明了; 不过有一个小小的缺点,只收发字符串,而且接收函数中的判断也有点不好;如果要用这个库传输文件等数据,需要 自己重载 收发函数,不过也很简单;

  11. SimpleSockets,
    http://sockets.carrierlabs.com/index.html
    跨平台,支持 TCP ,UDP;注:这个编译简单而且用起来也简单

scikit-learn机器学习

from sklearn import metrics

评分函数评估模型性能

对分类器评分
1. metrics.accuracy_score(y_true,y_pred) 准确率
1. metrics.precision_score(y_true,y_pred) 精确率
1. metrics.recall_score(y_true,y_pred) 召回率(敏感率)

对回归器评分
1. metrics.mean_squared_error(y_true,y_pred) 均方差
1. metrics.explained_variance_score(y_true,y_pred) 可释方差
1. metrics.r2_score(y_true,y_pred) R方值


k-NN算法

k邻近算法 一个数据点很可能与它邻近的点属于同类

# 1. 生成训练数据
train_data, labels = generate_data(11)
# 分离标签数据
blue = train_data[labels.ravel() == 0]
red = train_data[labels.ravel() == 1]
# 画出所有点
plot_data(blue, red)

# 2. 训练分类器
# 创建分类器
knn = cv2.ml.KNearest_create()
# 传入训练数据 成功返回True
knn.train(train_data, cv2.ml.ROW_SAMPLE, labels)

# 3. 预测新数据点的类别
# 生成新的点
newcomer, _ = generate_data(1)
# 绘制新的点
plt.plot(newcomer[0, 0], newcomer[0, 1], 'go', markersize=14)
plt.show()
# 根据最近邻数据点的标签预测新数据点的标签
ret, results, neighbor, dist = knn.findNearest(newcomer, k=3)
print('Predicted label: \t', results)
print('Neighbor label: \t', neighbor)
print('Distance to Neighbor: ', dist)

回归模型预测连续后果

  1. 线性回归, 通过特征的线性组合描述目标变量 如房价预测
    linreg = linear_model.LinearRegression()
    正侧化-降低过拟合过程,
    L1-Lasso回归 linreg = linear_model.Lasso()
    L2-ridge回归 linreg = linear_model.Ridge() /linear_model.RidgeRegression()
  2. 逻辑回归 用于目标的分类模型,把任意输入的实值x转为0~1区间的一个预测值,比如判定物品的种类
    linreg = cv2.ml.LogisticRegression_create()

特征工程

特征选择,特征提取

  1. 数据预处理
    数据格式化,数据清理,数据采样

    1. 特征标准化
      每个点减去所有数据的平均值再除以方差
      x_scaled = preprocessing.scale(x)
      x_scaled.mean(axis=0) 每行均值近似为0 x_scaled.std(axis=0) 每行方差为1
    2. 特征归一化
      L1范数(曼哈顿距离) l1=preprocessing.normalize(X,norm=’l1′)
      L2范数(欧氏距离) l2=preprocessing.normalize(X,norm=’l2′)
    3. 特征缩放在一定范围,一般0~1内
      min_max_scaler = preprocessing.MinMaxScaler() or MinMaxScaler(feature_range(-10,10))
      X_min_max = min_max_scaler.fit_transform(x)
    4. 特征二值化
      binarizer = preprocessing.Binarizer(threshold=0.5)
    5. 缺失数据处理
      mean将nan值换为指定坐标元素的平均值,默认axis=0
      median将nan值换为指定坐标元素的中值,默认axis=0
      most_frequest将nan值换为指定坐标元素中出现频率最高值,默认axis=0
      imp = preprocessing.Imputer(strategy=’mean’)
      x2= imp.fit_transform(x)
  2. 理解降维
    1. 主要成分分析PCA
      特征向量x和y组合成一个特征矩阵X
      x=np.vstack((x,y)).T
      矩阵X上计算PCA,mu投影前减去的平均值eig协方差矩阵的特征向量
      mu, eig = cv2.PCACompute(X,np.array([]))
      旋转投影数据
      x2=cv2.PACAProject(X,mu,eig)
    2. 独立成分分析ICA
      ica=decomposition.FastICA()
      x2=ica.fit_transform(x)
    3. 非负矩阵分解NMF
      nmf = decomposition.NMF()
      x2=nmf.fit_transform(x)
  3. 类别变量表示 类别特征(离散特征)
    独热编码 form sklearn.feature_extraction import DictVectorizer
    vec = DictVectorizer(aparse=False,dtype=int) or aparse=True稀疏矩阵紧凑表示
    vec.fit_transform(data)
    查看特征的顺序表
    vec.get_feature_names()
    某些算法如决策树,本身可以处理类别特征,不再需要使用独热编码

  4. 文本特征表示

    1. 单词计数 缺点:频繁出现的单词赋予过大权重
      form sklearn.feature_extraction.text import CountVectorizer
      vec = CountVectorizer()
      x = vec.fit_transform(data) 将特征矩X保存为一个稀疏矩阵
      x.toarray() 稀疏矩阵转换为常规数组
      vec.get_feature_names() 查看特征名字
      1.词频-逆文档频率TF-IDF 衡量单词在整个数据中出现的频率计算权重
      form sklearn.feature_extraction.text import TfidfVectorizer
      vec = TfidfVectorizer()
      x = vec.fit_transform(data) 将特征矩X保存为一个稀疏矩阵
      x.toarray() 稀疏矩阵转换为常规数组
  5. 图像表示
    1.使用色彩空间

    1. RGB,openCV中是BGR
      img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    2. HSV / HLS /LAB / YUV
      cv2.COLOR_BGR2HSV …

    2.图像角点检测

    1. Harris角点检测(仅灰度图像) corners=cv2.cornerHarris(img_gray,blockSize,Ksize,k)
    2. Shi-Tomasi角点检测 cv2.goodFeaturesToTrack

    3.尺度不度特征变换SIFT
    sift = cv2.xfeatures2d.SIFT_create()

    1. kp = sift.detect(img_bgr) 关键点
      关键点可视化
      img_kp = np.zeros_like(img_bgr)
      img_kp = cv2.drawkeypoints(img_rgb,kp,img_kp,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
      plt.show()
      计算关键点的特征值
      kp,des=sift.compute(img_bgr,kp) des的每个关键点有128个特征值
    2. 一步检测关键点并计算出特征描述符
      kp2,des2=sift.detectAndCompute(img_bgr,None)
      可以比较des与des2是否相等 print(np.allclose(des,des2))

    4.加速键状特征SURF
    与SIFT一样使用,且商业使用需要授权,比SIFT能得到更多特征,速度更快
    surf = cv2.xfeatures2d.SURF_create()

    5.cv2.ORB 开源代替SIFT,SURF方案
    使用FAST关键点检测子和BRIEF描述符


决策树

决策树是一个简单有效的监督学习算法
1. 数据预处理
得到训练集和测试集
1. 构建决策树
dtree=cv2.ml.dtree_create()
1. 训练决策树
dtree.train=(X_train,cv2.ml.ROW_SAMPLE,y_train)
1. 预测新数据点标签类别
y_pred=dtree.predict(x_test)
1. 检测算法性能-准确率
metrics.accuracy_score(y_test,dtree.predict(X_test)) 测试样本
metrics.accuracy_score(y_train,dtree.predict(X_train)) 训练数据

  1. 可视化训练决策树
    from sklearn import tree
    构造一个空的决策树
    dtc = tree.DecisionTreeClassifier(class_weigth=None,criterion=’gini’ ,max_depth=None,max_features=None,max_leaf_nodes=None,min_impurity_split=1e-07,min_samples_leaf=1,min_samples_split=2,min_weight_fraction_leaf=0.0,presort=False,random_state=None,splitter=’best’)
    fit训练决策树
    dtc.fit(X_train,y_train)
    DecisionTreeClassifier()
    测试准确率
    dtc.score(X_train,y_train)
    dtc.score(X_test,y_test)
    生成决策树文件.Pdf
    $conda install graphviz
    with open(‘tree.dot’,’w’): f=tree.export_graphviz(clf,out_file=f)
    $dot -Tpng tree.dot -o tree.png
    特征重要性评分
    dtc.feature_importances_
    决策规则
    criterion=’gini’ 基尼不纯度,目标是最小化分类错误的概率
    criterion=’entropy’ 信息增益,计算熵,选最低的,完美为0
    控制树的复杂度,避免过拟合,使用预剪枝和后剪枝
    max_depth控制最大深度
    max_leaf_nodes 最多叶结点数量
    min_samples_split 最小数据点数量持续对决策树进行分割
    更复杂的场景使用随机森林

线性回归不能使用gini,entropy,作为代替mse方差缩减,计算真实值和预测值的均方误差 mae计算真实值和预测值的平均绝对值差


支持向量机 SVM

是一种二分化模型,把无法线性分隔的数据映射到高维空间后再找到分类器最优的线性分类器,是一种基于关键点的分类算法,支持向量是离分类器最近的那些点.机器是指分类器,离分类器最近的点到分类器的距离称为间隔,希望间隔尽可能大,就会更准确,也称最大边缘分类器
1. opencv
生成用于后续训练的空分类器模型
svm = cv2.ml.SVM_create()
训练结果 = svm.train(训练数据,训练数据排列格式,训练数据的标签)
训练数据排列格式 cv2.ml.ROW_SAMPLE 按行 cv2.ml.COL_SAMPLE 按列
(返回值,返回结果) = svm.predict(测试数据)
参数调整:setType()设置类别 setKernel()设置核类型 setC()设置支持向量机的参数C(惩罚系数,对误差的宽容度,默认0)
1. sk-learn库
生成可以控制大小和复杂度的随机数据集
make_classification生成随机的n类分类问题,make_regression随机的回归问题,
X, y = datasets.make_classification(n_samples=100, n_features=2,n_redundant=0, n_classes=2,random_state=7816)
方向梯度直方图HOG,是一个图像的特征描述符,常用于人物人类,基本思想对像的局部形状和外观可以使用边缘方向的分布来表示,特别适合纹理丰富的数据.
hog = cv2.HOGDescriptor(win_size, block_size, block_stride, cell_size, num_bins)
调用hog.compute构建样本
X_pos.append(hog.compute(img, (64, 64)))

  1. LIBSVM

贝叶斯学习

一个事件的发生概率可以基于条件的先验知识进行估计,可以用于数据分类,分类正确概率估计.
判别模型,生成模型

# 使用正态贝叶斯分类器
model_norm = cv2.ml.NormalBayesClassifier_create()
# 训练
model_norm.train(X_train, cv2.ml.ROW_SAMPLE, y_train)
# 预测测试
_, y_pred = model_norm.predict(X_test)
# 预测测试评分
print(metrics.accuracy_score(y_test, y_pred))

# 使用朴素贝叶斯分类器
model_naive = naive_bayes.GaussianNB()
# 训练分类器
model_naive.fit(X_train, y_train)
GaussianNB(priors=None)
# 对分类器打分
print('GaussianNB score:', model_naive.score(X_test, y_test))
# 显示决策边界
plot_decision_boundary(model_norm, X, y)
plt.show()
# 预测测试数据,返回y_proba真正概率
yprob = model_naive.predict_proba(X_test)
print(yprob.round(2))

# 使用完整数据训练,需要更复杂的方法,sklearn中的朴素贝叶斯分类器可以处理稀疏矩阵
model_naive = naive_bayes.MultinomialNB()
model_naive.fit(X_train, y_train)

# 使用n-gram提升结果,考虑单词的顺序,但对于更长的文本无法有效的评估权重
counts = feature_extraction.text.CountVectorizer(ngram_range=(1, 2))
X = counts.fit_transform(data['text'].values)
# 分隔
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.2, random_state=42)
# 训练数据
model_naive = naive_bayes.MultinomialNB()
model_naive.fit(X_train, y_train)
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)

# 使用TD-IDF提升结果 词频-逆文档频率
tfidf = feature_extraction.text.TfidfTransformer()
X_new = tfidf.fit_transform(X)
X_train, X_test, y_train, y_test = ms.train_test_split(X_new, y, test_size=0.2, random_state=42)
model_naive = naive_bayes.MultinomialNB()
model_naive.fit(X_train, y_train)

非监督学习

降维,因子分析,聚类分析,评估方式使用手动检查,可以作为预处理或特征提取的步骤.
retval,bestLabels,centers = cv2.kmeans(data,K,bestLables,criteria,attempts,flags)
retval 距离值,返回每个点到相应中心距离的平方和,较高紧凑度表明所有点更靠近它们的聚类中心
bestLabels 各个数据点的最终分类标签(索引)
centers 每个分类的中心点数据
data 待处理的数据集合,np.float32类型,每个特征单独一列中
K 要分出簇的个数,常见2,表示2分类
bestLables 各个数据点的最终分类标签(索引),实际中设为None
criteria 算法迭代的终止条件,达到最大循环数目和指定精度阀值时终止,由3个参数构成type,max_iter,eps
type: cv2.TEEM_CRITERIA_EPS 精度满足 MAX_ITER 迭代次数超过阀值max_iter时停止 _EPS+MAX_ITER两个任意一个满足停止
max_iter 最大迭代次数
eps 精确度的阀值
attempts 使用不用的初始值多次(attempts次)偿试
flags 选择初始中心点的方法,主要有3种cv2.KMEANS_RANDOM_CENTERS 随机 cv2.KMEANS_PP_CENTERS基于中心算法 cv2.KMEANS_USE_INITIAL_LABELS 使用用户输入的数据作为第一次分类的中心点,需要多次偿试时后续使用随机或半随机值作为第一次分类中心点

迭代方法,k均值聚类期望最大化 , 高斯混合模型GMM

局限性
无法保证全局最优解(常常让算法在多个初始状态运行)
必须知道聚类个数(肘部法则,轮廓分析,高斯混合模型GMM使用贝叶斯信息准则获得正确数量,具有噪声的基于密度聚类DBSCAN,邻近传播算法)
决策边界是线性的(sklearn谱聚类SpectralClustering)
处理大数据时非常慢(sklearn谱聚类cluster.MiniBatchKMeans)

应用
压缩色彩空间 虽丢失一些细节,介仍可以清楚被识别,另一个方法使用双边滤波器
进行图像分类
字类识别
组织成层次树(c++API 快速最近邻逼近搜索函数cv::flann:hierarchicalClustering sklern自行实现cluster.AgglomerativeClustering)

# 创建4个不同的聚类,一共300个数据点
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=1.0, random_state=10)
# 算法迭代的终止条件
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# 选择初始中心点的方法
flags = cv2.KMEANS_RANDOM_CENTERS
# 聚类分析 指定聚类4,算法初始随机选择尝试次数10
compactness, labels, centers = cv2.kmeans(X.astype(np.float32), 4, None, criteria, 10, flags)

深度学习

人工神经网络 Google-DeepMind Facebook-DeepFace, Keras
McCulloch-Pitts神经元:本质上是一个线性的二元分类器,一般需要训练数据,代价函数,学习规则
感知器:只有当数据是线性可分,且学习率足够小的情况下,感知学习规则才可以保证收敛于最优解
把感知器应用到线性不可分的数据上时,测试结果失败,不存在一条直线可以完美分割
多层感知器MLP,万能逼近特性,给它足够的神经元和层,基本上可以学习任意的输入-输出函数
梯度下降:陷入局部最小值,解决方法可以添加噪声
使用反向传播训练多层感知器,用于估计神经网络中代价函数梯度, 链式法则

# 创建MLP分类器
mlp = cv2.ml.ANN_MLP_create()
# 第一层两个神经元
n_input = 2
# 单个隐藏层8个神经元
n_hidden = 8
# 最后一层两个神经元
n_output = 2
mlp.setLayerSizes(np.array([n_input, n_hidden, n_output]))

# 定制MLP分类器
# 定义网络中每个神经元的激活函数,可以使用自定或openCV
mlp.setActivationFunction(cv2.ml.ANN_MLP_SIGMOID_SYM, 2.5, 1.0)
# 定义一个合适的训练方法
mlp.setTrainMethod(cv2.ml.ANN_MLP_BACKPROP)
# 设置训练过程的终止条件
term_mode = cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS
term_max_iter = 300
term_eps = 0.01
mlp.setTermCriteria((term_mode, term_max_iter, term_eps))

# openCV提供激活函数
# cv2.ml.ANN_MLP_IDENTITY 线性激活函数f(x)=x
# cv2.ml.ANN_MLP_SIGMOID_SYM 对称的sigmoid双曲正切
# cv2.ml.ANN_GAUSSIAN 高斯函数 贝尔曲线

# 训练方法
# cv2.ml.ANN_MLP_BACKPROP 反向传播算法,通过mlp.setBackpropMomentumScale 和 mlp.setBackpropWeightScale设置额外的比例因子
# cv2.ml.ANN_MLP_RPROP Rprop算法 通过mlp.setRpropDW0, mlp.setRpropDWMax, mlp.setRpropDWMin, mlp.setRpropDWMinus,  \
#                              mlp.setRpropDWPlus设置额外的参数

# 训练MLP分类器
mlp.train(X, cv2.ml.ROW_SAMPLE, y)
# 预测目标标签
_, y_hat = mlp.predict(X)
# 测量准确率
print(accuracy_score(y_hat.round(), y))


深度学习,人工神经网络开源学习框架
谷歌 TensorFlow
微软 Cognitive Toolkit CNTK
加州大学伯克利分校 Caffe
蒙特利尔大学 Theano
Torch 基于Lua编程语言
Keras 定位一个接口


不同的算法组合

装袋方法(Bagging)
提升方法(Boosting)
随机森林(Random Forest)
自适应提升(AdaBoost)

合适的模型

选择正确的模型就是在偏差和方差之间找一个平衡

交叉验证
常用k折交叉验证,k是用户指定的数字(一般5或10),数据被分成大小差不多相等的k个部分,叫作折,使用k-1折用于训练,另一折用于测试,过程重复进行k次迭代,每次选择不同的折进行测试.
比把数据集分割为训练集和测试集更加稳定和全面

留一法交叉验证

自举
通过使用替代的方法来抽取样本

评估结果’
T检验 两个数据样本是否来自于相同的平均值或者期望值的潜在分布,返回参数p来接受或者驳回一个虚假设,p在0~1内,p=0.05表示这个虚假设仅在100次中正确5次
配对卡方检验 可以用在对对的数据上,来确定两个样本之间是否有任何差异

数据分类:
训练集: 用于构建模型
验证集: 用于选择模型的参数
测试集: 用于评估最终模型的性能

网格搜索结合交叉验证 GridSearchCV
网格搜索嵌套交叉验证
F值(计算精准率和召回率的调和平均值) 公式 2(精准率X召回率)/(精准率+召回率)
设置作业点 PR曲线工具
回归指标:
1. 均方误差 sklearn.metrics.mean_squared_error
1. 可释方差sklearn.metrics.explained_variance_score
1. R2值 sklearn.metrics.r2_score 大部分应用,使用默认的R2就够了
管道 Pipeline


如何解决问题

  1. 问题分类
    1. 按输入分类: 数据已标记,监督学习,通过环境交互来优化,强化学习,没有被标记,非监督学习
    2. 按输出分类: 输出的是数字,回归问题,输出是一个类,分类问题
  2. 找到可用的算法
    可参见速查表 http://aka.ms/MLCheatSheet
  3. 原型构建(实现所有适用的算法)
    1. 使用最少的特征工程,临时应急地实现多个算法
    2. 理想情况下,可以设置一个机器学习管道,使用一组精心准备的指标评测
    3. 特征工程 很重要
    4. 优化超参数

构建自己的估计器

  1. ClassifierMixin if you are writing a classifier (will provide a basic score method) 写一个分类器时
  2. RegressorMixin if you are writing a regressor (will provide a basic score method) 写一个回归器时
  3. ClusterMixin if you are writing a clustering algorithm (will provide a basic fit_predict method) 写一个聚类算法时
  4. TransformerMixin if you are writing a transformer (will provide a basic fit_predict method) 写一个转换器时

    importing BaseEstimator and ClassifierMixin
    class MyClassifier(BaseEstimator, ClassifierMixin):

常用数据集

  1. scikit-learn 内置数据样集
  2. scikit-learn 外部服务载入 mldata.org 参考http://scikit-learn.org/stable/datasets/index.html
  3. Kaggle http://www.kaggle.com 经常比赛,提供一个特定要优化的指标
  4. OpenML http://www.openml.org
  5. 加州大学欧文分校 http://archive.ics.uci.edu/ml/index.php

pysimplegui

https://pysimplegui.readthedocs.io/en/latest/

pip install pysimplegui
pip3 install pysimplegui

sudo apt-get install python3-tk


import PySimpleGUI as sg
print(sg)
print(sg.version)

Popup(args=*<1 or N object>,
    title=None,
    button_color=None,
    background_color=None,
    text_color=None,
    button_type=0,
    auto_close=False,
    auto_close_duration=None,
    custom_text=(None, None),
    non_blocking=False,
    icon=None,
    line_width=None,
    font=None,
    no_titlebar=False,
    grab_anywhere=False,
    keep_on_top=False,
    location=(None, None),
    any_key_closes=False,
    image=None,
    modal=True)

sg.popup('popup')  # Shows OK button
sg.popup_ok('popup_ok')  # Shows OK button
sg.popup_yes_no('popup_yes_no')  # Shows Yes and No buttons
sg.popup_cancel('popup_cancel')  # Shows Cancelled button
sg.popup_ok_cancel('popup_ok_cancel')  # Shows OK and Cancel buttons
sg.popup_error('popup_error')  # Shows red error button
sg.popup_timed('popup_timed')  # Automatically closes
sg.popup_auto_close('popup_auto_close')  # Same as PopupTimed

popup_scrolled(args=*<1 or N object>,
    title=None,
    button_color=None,
    background_color=None,
    text_color=None,
    yes_no=False,
    auto_close=False,
    auto_close_duration=None,
    size=(None, None),
    location=(None, None),
    non_blocking=False,
    no_titlebar=False,
    grab_anywhere=False,
    keep_on_top=False,
    font=None,
    image=None,
    modal=True)
sg.popup_scrolled(my_text)
sg.popup_scrolled(my_text, size=(80, None))

popup_no_wait(args=*<1 or N object>,
    title=None,
    button_type=0,
    button_color=None,
    background_color=None,
    text_color=None,
    auto_close=False,
    auto_close_duration=None,
    non_blocking=True,
    icon=None,
    line_width=None,
    font=None,
    no_titlebar=False,
    grab_anywhere=False,
    keep_on_top=False,
    location=(None, None),
    image=None,
    modal=False)

popup_get_text(message,
    title=None,
    default_text="",
    password_char="",
    size=(None, None),
    button_color=None,
    background_color=None,
    text_color=None,
    icon=None,
    font=None,
    no_titlebar=False,
    grab_anywhere=False,
    keep_on_top=False,
    location=(None, None),
    image=None,
    modal=True)
text = sg.popup_get_text('Title', 'Please input something')
sg.popup('Results', 'The value returned from PopupGetText', text)

popup_get_file(message,
    title=None,
    default_path="",
    default_extension="",
    save_as=False,
    multiple_files=False,
    file_types=(('ALL Files', '*.*'),),
    no_window=False,
    size=(None, None),
    button_color=None,
    background_color=None,
    text_color=None,
    icon=None,
    font=None,
    no_titlebar=False,
    grab_anywhere=False,
    keep_on_top=False,
    location=(None, None),
    initial_folder=None,
    image=None,
    modal=True)

popup_get_folder(message,
    title=None,
    default_path="",
    no_window=False,
    size=(None, None),
    button_color=None,
    background_color=None,
    text_color=None,
    icon=None,
    font=None,
    no_titlebar=False,
    grab_anywhere=False,
    keep_on_top=False,
    location=(None, None),
    initial_folder=None,
    image=None,
    modal=True)

popup_animated(image_source,
    message=None,
    background_color=None,
    text_color=None,
    font=None,
    no_titlebar=True,
    grab_anywhere=True,
    keep_on_top=True,
    location=(None, None),
    alpha_channel=None,
    time_between_frames=0,
    transparent_color=None,
    title="",
    icon=None)

one_line_progress_meter(title,
    current_value,
    max_value,
    key="OK for 1 meter",
    args=*<1 or N object>,
    orientation="v",
    bar_color=(None, None),
    button_color=None,
    size=(20, 20),
    border_width=None,
    grab_anywhere=False,
    no_titlebar=False)
for i in range(1,10000):
    sg.one_line_progress_meter('My Meter', i+1, 10000, 'key','Optional message')

Debug Output(easy_print = Print = eprint)
for i in range(100):
    sg.Print(i)

sg.theme('Dark Blue 3')  # please make your windows colorful
layout = [ [sg.Text('Enter a Number')],
           [sg.Input()],
           [sg.OK()] ],
           [sg.InputText(), sg.FileBrowse()],
           [sg.Submit(), sg.Cancel()]]

window = sg.Window('Enter a number example', layout)
event, values = window.read()

使用菜单
# ------ Menu Definition ------ #
menu_def = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']],
            ['&Edit', ['Paste', ['Special', 'Normal', ], 'Undo'], ],
            ['&Help', '&About...'], ]
layout = [
    [sg.Menu(menu_def, tearoff=True)],

    # 定义右键菜单
    right_click_menu = ['Unused', ['Right::_Right_', '!&Click', '&Menu', 'E&xit', 'Properties']]
    # 定义布局
    layout = [[sg.Menu(menu_def, tearoff=False, pad=(20,1))],
               # 底部菜单
              [sg.ButtonMenu('ButtonMenu',key='-BMENU-', menu_def=menu_def[0])],]
    # 定义 Window
    window = sg.Window("Windows-like program",layout,
                       default_element_size=(12, 1),
                       grab_anywhere=True, # 非阻塞
                       right_click_menu=right_click_menu, # 添加右键菜单
                       default_button_element_size=(12, 1)
                      )
'Right::_Right_' 是指定该菜单的 Key 的方式。!禁用

Theme Name
There are 130 themes available. You can preview these themes by calling theme_previewer() which will create a LARGE window displaying all of the color themes available. Default is Dark Blue 3
Dark Color #
or
Light Color #
DarkAmber
    # print(sg.ListOfLookAndFeelValues())
    # ['SystemDefault', 'Reddit', 'Topanga', 'GreenTan', 'Dark', 'LightGreen', 'Dark2', 'Black', 'Tan', 'TanBlue',
    # 'DarkTanBlue', 'DarkAmber', 'DarkBlue', 'Reds', 'Green', 'BluePurple', 'Purple', 'BlueMono', 'GreenMono',
    # 'BrownBlue', 'BrightColors', 'NeutralBlue', 'Kayak', 'SandyBeach', 'TealMono']
sg.theme()窗口样式
sg.theme('BluePurple')
要查看您的PySimpleGUI版本的上述预览,请进行以下调用以生成所有可用主题的预览:
sg.theme_previewer()
如果您想在系统上看到一个窗口,如上面的主题预览屏幕截图,那么进行此调用,您将看到相同的窗口:
import PySimpleGUI as sg
sg.preview_all_look_and_feel_themes()
您还可以通过致电获取主题名称列表 theme_list
import PySimpleGUI as sg
theme_name_list = sg.theme_list()


Making your window modal
To make a Modal Wio=ndow you have 2 options.
    Set the moodel=True parameter in your Window calls.
    Call the method Window.make_modal() to chance a window from non-modal to modal. There is no modal to non-modal. Don't see the need for one. If one comes up, sure!
MPORTANT - Many of the Window methods require you to either call Window.read or Window.Finalize (or set finalize=True in your Window call) before you call the method. This is because these 2 calls are what actually creates the window using the underlying GUI Framework. Prior to one of those calls, the methods are likely to crash as they will not yet have their underlying widgets created.

"Elements" are the building blocks used to create windows. Some GUI APIs use the term "Widget" to describe these graphic elements.
    Text
    Single Line Input
    Buttons including these types:
        File Browse
        Folder Browse
        Calendar picker
        Date Chooser
        Read window
        Close window ("Button" & all shortcut buttons)
        Realtime
    Checkboxes
    Radio Buttons
    Listbox
    Slider
    Multi-line Text Input/Output
    Multi-line Text Output (not on tkinter version)
    Scroll-able Output
    Vertical Separator
    Progress Bar
    Option Menu
    Menu
    ButtonMenu
    Frame
    Column
    Graph
    Image
    Table
    Tree
    Tab, TabGroup
    StatusBar
    Pane
    Stretch (Qt only)
    Sizer (plain PySimpleGUI only)

Text Element | T == Txt == Text
Window.FindElement(key) shortened to Window[key]
window['-MULTILINE KEY-'].print('My variables are', a, b, c)     # Routed to your multiline element
Text Input Element | InputText == Input == In
Combo Element | Combo == InputCombo == DropDown == Drop
layout = [[sg.Listbox(values=['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(30, 6))]]
layout = [[sg.Slider(range=(1,500),default_value=222,size=(20,15),orientation='horizontal',font=('Helvetica', 12))]]
layout =  [[sg.Radio('My first Radio!', "RADIO1", default=True),sg.Radio('My second radio!', "RADIO1")]]
Checkbox Element | CBox == CB == Check
layout =  [[sg.Checkbox('My first Checkbox!', default=True), sg.Checkbox('My second Checkbox!')]]
layout =  [[sg.Spin([i for i in range(1,11)], initial_value=1), sg.Text('Volume level')]]
layout = [[sg.Image(r'C:\PySimpleGUI\Logos\PySimpleGUI_Logo_320.png')],]
Button Element
    Button= ReadButton = RButton = ReadFormButton (Use Button, others are old methods)
    CloseButton = CButton
    RealtimeButton
    DummyButton
    layout =  [[sg.Button('Ok'), sg.Button('Cancel')]] layout =  [[sg.Ok(), sg.Cancel()]]
Button Element Shortcuts
    OK
    Ok
    Submit
    Cancel
    Yes
    No
    Exit
    Quit
    Help
    Save
    SaveAs
    Open
Chooser" Buttons
These buttons are used to show dialog boxes that choose something like a filename, date, color, etc.. that are filled into an InputText Element (or some other "target".... see below regarding targets)
    CalendarButton
    ColorChooserButton
    FileBrowse
    FilesBrowse
    FileSaveAs
    FolderBrowse
he code for the entire window could be:
layout = [[sg.T('Source Folder')],
              [sg.In()],
              [sg.FolderBrowse(target=(-1, 0)), sg.OK()]]
or if using keys, then the code would be:
layout = [[sg.T('Source Folder')],
              [sg.In(key='input')],
              [sg.FolderBrowse(target='input'), sg.OK()]]
sg.Button('Restart Song', button_color=(sg.theme_background_color(), sg.theme_background_color()),
               image_filename=image_restart, image_size=(50, 50), image_subsample=2, border_width=0)
VerticalSeparator(pad=None)
sg.OneLineProgressMeter('My Meter', i+1, 1000,  'key', 'Optional message')
Output(size=(80,20))


Qt Designer

https://github.com/nngogol/PySimpleGUIDesigner
pip install PySimpleGUIDesigner

Use GUI(by default):
PySimpleGUIDesigner

Use CLI:
PySimpleGUIDesigner -xml “~/folder1/test.ui” -ob “somegroupBox”

#removing (if installed) PySimpleGUIDesigner: 源码安装
pip uninstall -y PySimpleGUIDesigner

mkdir psgdesigner
cd psgdesigner
git clone https://github.com/nngogol/PySimpleGUIDesigner
python3 -m PySimpleGUIDesigner

python3 main.py –xmlfile=”~/folder1/test.ui” –objname=”somegroupBox”
#a bit shorter command:
python3 main.py -xml “~/folder1/test.ui” -ob “somegroupBox”

macOS Catalina上python调用摄像头权限问题

  1. xcode
    1)打开Xcode,新建项目,选择macOS,App。
    2)完善项目信息:
    Product Name: pycharm
    Organization Identifier: com.jetbrains
    Bundle identifier: com.jetbrains.pycharm
    Language: Swift
    User Interface: Storyboard
    3)打开Info.plist文件 ,添加Privacy – Camera Usage Description,属性为:Give me my camera access!
    4)打开AppDelegate.swift文件,导入库新增:
    import AVKit
    5)applicationDidFinishLaunching() 函数中,添加代码:
    AVCaptureDevice.requestAccess(for: .video) { _ in }

然后运行项目,OK允许

  1. Iterm2
    系统当前 shell
    $ cat /etc/shells
    当前使用的shell
    echo $SHELL
    切换到zsh
    chsh -s /bin/zsh

bash的配置文件是 -/.bash_profile
zsh的配置文件是-/.zshrc

安装iTerm2
iTerm2下载地址:https://www.iterm2.com/downloads.html
brew cask install iterm2

安装oh my zsh
通过curl安装:
sh -c “$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)”
或通过wget安装:
sh -c “$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)

‘/Applications/IntelliJ IDEA.app/Contents/MacOS/idea’