PHP+MySQL实现简单的登录注册

1、登录界面denglu.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>登录页面</title> <script type="text/javascript"> //检查用户名是否填写 function checkName(){ var name = document.getElementById("add_name").value; var spanNode = document.getElementById("user_name"); if (name != "") { spanNode.innerHTML = "已填".fontcolor("green"); return true; }else{ spanNode.innerHTML = "用户名不能为空!".fontcolor("red"); return false; } } //检查密码是否填写 function checkPassword(){ var password = document.getElementById("add_password").value; var spanNode = document.getElementById("user_password"); if (password != "") { spanNode.innerHTML = "已填".fontcolor("green"); return true; }else{ spanNode.innerHTML = "请输入密码!".fontcolor("red"); return false; } } //点击登录时进行检查 function checkForm(){ var name = checkName(); var password = checkPassword(); if (name && password) { return true; }else{ return false; } } </script> </head> <style type="

MySQL分页查询的实现方式及性能优化技巧

1. 前言 MySQL 的分页查询在我们的开发过程中还是很常见的,比如一些后台管理系统,我们一般会有查询订单列表页、商品列表页等。 示例: SELECT&nbsp;*&nbsp; FROM&nbsp; `goods`&nbsp;&nbsp; order&nbsp; by&nbsp;create_time&nbsp;&nbsp; limit&nbsp; 0, 10; 在了解order by和limit的工作原理之前,我们首先回顾下 MySQL 的执行流程和索引结构。 注: 下面没有特别说明默认 MySQL 的引擎为 InnoDB 为讲述方便使用&nbsp;select *&nbsp;,生产环境不建议使用 1.1. 执行流程 MySQL 可以分为 Server 层和存储引擎层两部分,对于这个就不展开讲了。只需要知道一条 SQL 语句是从客户端发起请求到 Server 层,Server 层处理之后选出成本最低的执行计划去存储引擎层进行数据查询,查询出来的数据返回给 Server 层处理,最后返回给客户端。(存储引擎层根据扫描区间定位拿到数据给到 Server 层,剩下的过滤、排序、分页等操作是在 Server 层载进行处理的)。 1.2 索引结构 InnoDB 存储引擎的索引是一颗 B+ 树,只有主键索引树会存储全部的行记录数据,二级索引只会存储该记录对应的主键 id。所以我们使用二级索引查询数据时,如果查询的字段在二级索引没办法完全覆盖,则需要回表。 2. order by 工作原理 &nbsp; 准备工作 创建一张商品表,并且给价格字段设置索引 插入测试数据 2.1 索引扫描排序 EXPLAIN&nbsp; SELECT&nbsp;*&nbsp; FROM&nbsp;goods&nbsp; where&nbsp;price&nbsp;>&nbsp; 10&nbsp; and&nbsp;price&nbsp;<&nbsp; 13&nbsp; ORDER&nbsp; BY&nbsp;price; 我们发现这条 sql 使用了索引 idx_price,索引结构如下:

uniapp H5 JSSDK自定义分享微信内容

JSSDK使用步骤 1.微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名” 在开发期间,后端会有一个测试公众号,在上面可以配置本地ip地址,方便开发期间测试 2.引入jssdk包 安装包 npm install jweixin-module --save``` 在对应页面引用 import jweixin from 'weixin-js-sdk' const onWxPrepay = (res : Order.WxpayData) => { uni.hideLoading() //通过config接口注入权限验证配置 jweixin.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,线上环境需要改为false appId: res.appId, // 必填,公众号的唯一标识 timestamp: res.timestamp, // 必填,生成签名的时间戳 nonceStr: res.nonceStr, // 必填,生成签名的随机串 signature: res.paySign, jsApiList: ['chooseWXPay'], // 必填,需要使用的JS接口列表 }) jweixin.ready(() => { jweixin.chooseWXPay({ appId: res.appId, // 必填,公众号的唯一标识 timestamp: res.timestamp, nonceStr: res.nonceStr, // 支付签名随机串,不长于 32 位 package: res.prepayId, // 统一支付接口返回的prepay_id参数值 signType: 'RSA', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign: res.

02丨数据结构原理:Hash表的时间复杂度为什么是O(1)?

要了解 Hash 表,需要先从数组说起。 数组 数组是最常用的数据结构,创建数组必须要内存中一块连续的空间,并且数组中必须存放相同的数据类型。比如我们创建一个长度为 10,数据类型为整型的数组,在内存中的地址是从 1000 开始,那么它在内存中的存储格式如下。 由于每个整型数据占据 4 个字节的内存空间,因此整个数组的内存空间地址是 1000~1039,根据这个,我们就可以轻易算出数组中每个数据的内存下标地址。利用这个特性,我们只要知道了数组下标,也就是数据在数组中的位置,比如下标 2,就可以计算得到这个数据在内存中的位置 1008,从而对这个位置的数据 241 进行快速读写访问,时间复杂度为 O(1)。 随机快速读写是数组的一个重要特性,但是要随机访问数据,必须知道数据在数组中的下标。如果我们只是知道数据的值,想要在数组中找到这个值,那么就只能遍历整个数组,时间复杂度为 O(N)。 链表 不同于数组必须要连续的内存空间,链表可以使用零散的内存空间存储数据。不过,因为链表在内存中的数据不是连续的,所以链表中的每个数据元素都必须包含一个指向下一个数据元素的内存地址指针。如下图,链表的每个元素包含两部分,一部分是数据,一部分是指向下一个元素的地址指针。最后一个元素指向 null,表示链表到此为止。 因为链表是不连续存储的,要想在链表中查找一个数据,只能遍历链表,所以链表的查找复杂度总是 O(N)。 但是正因为链表是不连续存储的,所以在链表中插入或者删除一个数据是非常容易的,只要找到要插入(删除)的位置,修改链表指针就可以了。如图,想在 b 和 c 之间插入一个元素 x,只需要将 b 指向 c 的指针修改为指向 x,然后将 x 的指针指向 c 就可以了。 相比在链表中轻易插入、删除一个元素这种简单的操作,如果我们要想在数组中插入、删除一个数据,就会改变数组连续内存空间的大小,需要重新分配内存空间,这样要复杂得多。 Hash 表 前面说过,对数组中的数据进行快速访问必须要通过数组的下标,时间复杂度为 O(1)。如果只知道数据或者数据中的部分内容,想在数组中找到这个数据,还是需要遍历数组,时间复杂度为 O(N)。 事实上,知道部分数据查找完整数据的需求在软件开发中会经常用到,比如知道了商品 ID,想要查找完整的商品信息;知道了词条名称,想要查找百科词条中的详细信息等。 这类场景就需要用到 Hash 表这种数据结构。Hash 表中数据以 Key、Value 的方式存储,上面例子中,商品 ID 和词条名称就是 Key,商品信息和词条详细信息就是 Value。存储的时候将 Key、Value 写入 Hash 表,读取的时候,只需要提供 Key,就可以快速查找到 Value。 Hash 表的物理存储其实是一个数组,如果我们能够根据 Key 计算出数组下标,那么就可以快速在数组中查找到需要的 Key 和 Value。许多编程语言支持获得任意对象的 HashCode,比如 Java 语言中 HashCode 方法包含在根对象 Object 中,其返回值是一个 Int。我们可以利用这个 Int 类型的 HashCode 计算数组下标。最简单的方法就是余数法,使用 Hash 表的数组长度对 HashCode 求余, 余数即为 Hash 表数组的下标,使用这个下标就可以直接访问得到 Hash 表中存储的 Key、Value。

uniapp H5 微信网页授权

uniapp H5 微信网页授权 官方文档上已经写的很明白了 这里就简单记录下要注意的地方 背景 H5项目需要用户微信支付 微信支付要拿到微信用户的openid 而openid则需要进行微信授权拿到 用户同意授权,获取code 这一步需要前端直接打开一个链接,连接中携带着需要的参数,这里链接参考官方链接 1.授权方式scope 静默授权:snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid) 非静默授权:snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 ) 2.回调地址redirect_uri 前提:回调地址的域名需要在公众号上进行配置,正式的域名,需要进行备案的,所以在测试期间,后端会有一个测试公众号,上面可以配置本地的域名,比如:192.168.xx.xx,配置的时候不需要加http。 回调地址就是用户同意授权之后会跳转的页面,页面链接会携带我们需要拿到的code参数 3.appid appid要在关联的公众号里面拿到,测试公众号的appid和正式公众号的appid不一致,建议写在全局,方便修改 获取appid const appid = import.meta.env.VITE_APP_ID const redirect = encodeURIComponent( `${window.location.origin}/fx/pages/my/index` ) const openUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid} &redirect_uri=${redirect}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect` window.open(openUrl) 授权成功获取code 上面参数配置成功的话,这一步就很简单了,回调地址后会跟着code参数, 注意:如果是直接在微信浏览器里面打开链接,在右上角点击复制链接后面是没有code的,其实是有code的,但复制链接就是没有,可能是微信这里做了限制,直接在页面上打印出来就是有了,拿到code之后调用后端接口就可以了 onLoad(async (options) => { login_code.value = options.code if (login_code.value) { //业务逻辑处理 getLogin() } })

【Spiffo】防傻防呆Tips——解决fdisk编辑磁盘分区后lsblk列表内不更新内容问题

斯皮福这周写教程文案时重做SD卡启动盘随手摸了一张我以为空的SD卡来使用,经过fdisk软件编辑后输入lsblk发现其中没有新增的分区内容,于是开始寻找原因。 最后得知必须先释放全部分区后新增才能刷新出新增内容。 以下为示例: 错误操作部分 可见只删除了前两个部分,我以为后面是空的 正确操作 删除最后两个部分 总结,fdisk编辑分区如果不删干净再编辑就不能更新分区列表

Cocos 进度条物体跟随效果

话不多说上代码,记录一下初学cocos解决的问题,实用小功能。 import { _decorator, Button, Component, Node, ProgressBarComponent, Sprite, UITransform, Vec3 } from 'cc'; const { ccclass, property } = _decorator; @ccclass('game_scene1') export class game_scene1 extends Component { @property({ type: Button }) back: Button = null; //返回按钮 @property({ type: Sprite }) loading: Sprite = null; //进度条 @property({ type: Node }) pen: Node = null; //毛笔移动 onLoad() { this.back.node.on(Button.EventType.CLICK, this.backMain, this); } start() { } update(deltaTime: number) { this.LoadingMove(deltaTime); this.PenMove(); } backMain() { //返回主页面 console.

使用Yak搭建Log4j漏洞检测工具

作者:@望川师傅 Yak是什么 Yak 是一门 Web 安全研发领域垂直语言。专为安全而生,致力于安全能力融合的语言。内置多种网络安全模块。 总之Yak是整合了当前多种安全工具和开源项目,让安全从业人员无需安装复杂的依赖,就能上手工作。可以使安全从业人员快速进行安全检测和脚本编写。 官网地址:https://www.yaklang.io/ Github地址:yaklang/yakit: Cyber Security ALL-IN-ONE Platform (http://github.com) 由于本人接触这门语言时间不长,下面用Yak写一个简单的Log4j的检查工具。 Log4j漏洞 Log4j2 是一款 Java 日志记录框架。在Java开发中应用广泛。 2021年11月下旬由一名中国工程师、阿里云安全团队的 陈兆军(音译)发现Log4j2存着JNDI注入漏洞。并提交Apache官方。 该漏洞被称为:「互联网正在着火」「过去十年最严重的漏洞」「现代计算机历史上最大漏洞」「难以想到哪家公司不受影响」! 漏洞利用流程如下: 搭建漏洞利用环境 由于Log4j漏洞的影响很多DNSLog平台纷纷屏蔽了LADP协议。所以为了方便起见,自己搭一个LADP环境,用于漏洞的检验 yum 安装相关包 Go yum install -y openldap openldap-clients openldap-servers 复制一个默认配置到指定目录下,并授权,这一步一定要做,然后再启动服务,不然生产密码时会报错 Go cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG 授权给ldap用户,此用户yum安装时便会自动创建 Go chown -R ldap. /var/lib/ldap/DB_CONFIG 启动服务,先启动服务,配置后面再进行修改 Gosystemctl start slapd systemctl enable slapd 查看状态,正常启动则ok Go systemctl status slapd 在slapd.conf中加一行: Go loglevel 4095 在/etc/rsyslog.conf 中加入ldap日志文档: Go local4.* /var/log/ldap.log 创建日志文件 Go touch /var/log/ldap.

Cocos 距离判断和小兵的攻击判定

最近在学习cocos 和ts 遇到的问题和如何解决问题都会发表博客记录一下。 距离判断 let j = new Vec2(this.target.position.x - this.node.position.x, this.target.position.y - this.node.position.y); let dis = Math.sqrt(j.x * j.x + j.y * j.y) 枚举的外部类型定义: @property({type:Enum(HitAction)}) //外部定义枚举类型 import { _decorator, Component, debug, Enum, find, Node, Vec2, Vec3 } from 'cc'; import { HitAction } from '../Struct/GameStruct'; const { ccclass, property } = _decorator; @ccclass('EnemyRole') export class EnemyRole extends Component { target: Node; //目标 speed: number = 20; //速度 @property({type:Enum(HitAction)}) //外部定义枚举类型 hitAction: HitAction|null = null; canHit: boolean = true; start() { this.

Cocos3.4.2版本 获取手指滑动到的区域的Label文本并记录文本内容进行判定操作

import { _decorator, Component, Event, EventTouch, find, Input, input, Label, Node, Rect, sys, UITransform, Vec2, Vec3 } from 'cc'; import { JsonMgr } from '../Managers/JsonMgr'; import { strings } from '../Struct/GameStruct'; const { ccclass, property } = _decorator; ///用于获取手指滑动区域的文本并记录文本内容 @ccclass('Getstring') export class Getstring extends Component { label: Label; b:boolean=true; onLoad() { //name为需要找到的物体名称 let a=Getstring.Search(this.node,"name"); this.label=a.getComponent(Label); //this.label = this.node.getChildByName("name").getComponent(Label); input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this); input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this); //this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this) JsonMgr.getInstance().SetJsonOne(strings.InputTxt,""); //初始化数据 } start() { } update(deltaTime: number) { //input.

ELASTICSEARCH CLUSTER 集群搭建总结

ES集群特性总结: 1.高可用 对于所有集群来说都具备的一个高可用性,高可用性分为两种,一种是数据可用性,一种是服务 可用性。对于服务可用性来说,一个ES集群中可以存在多个ES NODE,每一个NODE对应一台服 务器,如果其中某一台因为某些元素出现了故障宕机,集群可以仍然使用剩余的NODE节点继续 提供服务,实现了服务高可用性;对于数据可用性来说,ES集群引入了副本(Replication)概 念,即创建INDEX的时候可以指定副本数量,以下图为例即是创建一个新的名为newindex的索 引,同时会为此索引创建两个分片及一份副本。需要注意的是,一旦创建索引,就无法更改其分 片数。同时由于引入了多台服务器,使得集群可以存储的数据量大幅上升,实现了高度数据可 用性。 PUT es ipaddress/hostnae:9200/newindex { "settings": { "index": { "number_of_shards": 2, "number_of_replicas": 1 } } } 2.近实时 从本质上来讲,ES也只是一种数据库,那么为什么在国内MYSQL等数据库占据主流的情况下还要使用ES呢,原因就是ES的数据读取速度。一台正常工作的ES服务器的读取速度可以保持在0.2毫秒之内,而即使你使用MYSQL在localhost进行少量的数据查询,由下图可见本地查询时间也基本上在40ms左右,由此对比可见ES速度之快。。 简单来说,ES之所以能达到这么快的速度,ES 是基于 Lucene 的全文检索引擎,它会使用分词器对数据进行分词后保存索引,擅长管理大量的索引数据,比如这么一个句子 “我的名字叫stefen zhen yu wang”, 在使用默认分词器的情况下ES会将这个句子分成{“我”,“的”,“名字”,“叫”,“stefen”,"zhen","yu","wang"},并且为每一个分好后的词保存一个索引,所以才能实现如此快速的查询。但是相对比MySQL来说,由于索引量过大,对于数据的更新操作来说,速度会慢很多。 3.安全性 ES内置了基于用户名和密码的认证方式,角色的访问控制,SSL加密访问等等,以保证数据传输过程以及存储的安全性。很值得一提的是,ES内置了一个elasticsearch-certutil工具,可以使用该工具去为集群生成对应的CA证书以及每个节点的签署证书的私钥。详细介绍可参考我另外一篇ES集成SSL证书。 集群基本配置 ES其实还有一个特性是易操作,其配置简单,例如本地的ES配置其实只是需要从官网把对应的压缩包下载下来然后启动对应的elasticsearch.bat文件,一个本地的单节点ES就已经启动好了,对于用户体验十分友好,在服务器上也是一样,只需要下载对应linux版本的tar包,解压缩执行运行,一台简单的ES服务器也就配置好了。对于集群配置来说也不会很复杂,只需要在在下载下来的elasticsearch包中的config目录下配置好elasticsearch.yml文件就行了。基本配置如下。 cluster.name: stefentestcluster node.name: es01 node.master: true network.host: 172.19.44.51 http.port: 9200 transport.tcp.port: 9300 discovery.seed_hosts: ["ipaddress1/hostname1", "ipaddress2/hostname2"] cluster.initial_master_nodes: ["ipadress1/hostname1", "ipadress2/hostname2"] yml配置详解: cluster.name:集群名字 node.name:当前这台服务器的节点名字 node.master:是否具备成为master主节点的资格,默认为false,一个ES服务集群只可以存在一个 master节点,master节点主要用于处理读写数据等操作,其他节点作为DATA节点,主要用于数据的存储。 network.host:当前ES服务器的IP地址或者是hostname http.port:ES端口号 transport.tcp.port:集群中每个ES几节点进行交互的TCP端口号 discovery.seed_hosts:这个配置就是ES集群中的所有服务器节点的IP地址或者hostname,只有配 置在其中的ES节点才能被加入集群。

scapy send()发包失败,OSError:[Errno 90] Messge too long

先说结论: scapy2.4.2-2.4.5版本是正常的,scapy2.5.0版本不行。 通过scapy发包的时候,出现上述问题。 问题排查: 经过分析代码,如果数据帧太多,需要对数据帧进行分片: 分片的大小一般为1500, 可以根据这个数值进行分片。 不过每个接口的分片大小不一定,可以进行设置。 比如,ifconfig eth3 mtu 10000. 分片的前提是,数据帧有payload(数据部分)且长度大于分片值才进行分片。 if pcap.haslayer("TCP") and pcap.haslayer("Raw") and len(pcap) > self.split_length: from scapy.all import * pcap_path = r"3.pcap" packages = rdpcap(pcap_path) print(packages[0].haslayer("Raw")) 0 print(packages[0].haslayer("TCP")) True print(packages[0]) Ether / IP / TCP 172.16.1.102:54728 > 172.16.1.103:microsoft_ds A / NBTSession / SMB2_Header / SMB2_Write_Request 问题原因;2.5.0在处理packages[0].haslayer(“Raw”)这块代码的时候存在问题。因为源pcap是有payload,但是返回为2.4.2版本处理这块代码的时候正常的。 注意:2.5.0对部分回放的包不支持,有些是支持,只是对haslayer(“Raw”)这块代码判断进行的变更。没有深入研究。 附录:变更历史 进入scapy github, 点击releases,就可以跳转下面的连接。 https://github.com/secdev/scapy/releases

LibSSH2简单入门-exec、sftp

LibSSH2简单入门-exec、sftp 1、libssh2官方地址:libssh2 libssh2的官方文档和官方示例代码非常的棒,基本可以直接参考 官方文档:libssh2 docs 官方示例:libssh2 examples 2、推荐阅读两个示例,基本可以完成对libssh2的理解和使用了 2.1、ssh2_exec.c 通过libssh2在远端机器上执行指令,并获取指令的返回值 /* Copyright (C) The libssh2 project and its contributors. * * Sample showing how to use libssh2 to execute a command remotely. * * The sample code has fixed values for host name, user name, password * and command to run. * * $ ./ssh2_exec 127.0.0.1 user password "uptime" * * SPDX-License-Identifier: BSD-3-Clause */ #include "libssh2_setup.h" #include <libssh2.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.

云服务器中jdk的安装与tomact的部署

1. jdk安装 1.1 新建一个文件夹存储压缩文件:mkdir -p /opt/softwoar/ 新建en文件夹存储解压后的文件:mkdir /opt/en 1.2 进入到 /opt/softwoar/文件夹把相关压缩文件拖进去即可 查看压缩文件夹 1.2 对压缩文件进行解压: 解压jdk压缩文件:tar -zxvf /opt/softwoar/jdk-17_linux-x64_bin.tar.gz -C /opt/en/ 解压tomact压缩文件夹:tar -zxvf /opt/softwoar/apache-tomcat-9.0.72.tar.gz -C /opt/en/ 1.3 配置jdk环境 1.3.1 编辑profile:vi /etc/profile 1.3.2 添加:export JAVA_HOME=(自己的解压后的jdk所在位置的绝对路径) export PATH=$JAVA_HOME/bin:$PATH 1.3.3 加载一下资源:source /etc/profile 1.3.4 jdk安装成功效果图:java -version 2.tomact部署 2.1 进入到tomact下的bin目录: 2.2 由于startup.sh是可执行文件。则直接执行即可: 2.3 此案例是用的阿里云服务器,则需要在阿里云添加对应端口的安全组此步骤省略 2.4 tomact部署成功效果图,注意:tomcat默认端口是8080。

Breakpad在Windows,Linux双平台编译、集成以及dump文件的分析

Breakpad在Windows,Linux双平台编译、集成以及dump文件的分析 1、Windows平台 Windows平台上非常好的参考文档: https://r12f.com/posts/google-breakpad-1-introduction-with-windows/ https://r12f.com/posts/google-breakpad-2-implementations-on-windows/ 1.1、源码下载及编译 平台:Win10 + Intel IDE:Visual Studio 2017 1.1.1、源码下载 github上的main分支一致编译不通过也没有gyp用于生成VS的sln。 当前我们使用github上breakpad的master分支即可 1.1.2、源码编译依赖 源码编译需要GYP生成VS打开的sln文件,GYP又依赖于python2.7.x版本 依赖关系:python2.7.x -> GYP -> Visual Studio;可顺序安装 详细请见:https://blog.csdn.net/zyhse/article/details/112577340博客 1.1.3、编译 breakpad只需要生成client中的项目,目录:breakpad-master\src\client\windows 该目录下可以看到breakpad_client.gyp文件(2023年后github main分支上已经没有该文件了) 使用安装好的GYP生成SLN(若gyp执行失败,大概率是python版本不对) gyp --no-circular-check "./breakpad_client.gyp" -Dwin_release_RuntimeLibrary=2 -Dwin_debug_RuntimeLibrary=3 使用vs2017打开调整为Release|x64编译 生成如上静态库 1.2、集成到现有代码中 breakpad集成到现有VS c++代码中非常的容易 1.2.1、包含头文件以及lib库 头文件:项目属性 -> C/C++ -> 附加包含目录 添加文件文件路径 lib库: 项目属性 -> 链接器 -> 常规 -> 附加库目录 添加库目录 ​ 项目属性 -> 链接器 -> 输入 -> 附加依赖项 添加 common.lib crash_generation_client.lib crash_generation_server.lib exception_handler.lib 或使用代码方式添加

【PyQt学习篇 · ⑩】:QAbstractButton的使用

文章目录 QAbstractButton简介子类化抽象类图标设置快捷键设置自动重复状态设置排他性点击设置点击有效区域可用信号 QAbstractButton简介 QAbstractButton 是一个抽象类,无法直接实例化,但它提供了很多在 PyQt 中使用按钮时常用的功能和特性。开发人员可以通过继承 QAbstractButton 类并实现自定义行为来创建自己的按钮类。 子类化抽象类 在 PyQt 中,可以通过子类化 QAbstractButton 的抽象类来创建自定义的按钮类。通过子类化,可以根据需要扩展和重写 QAbstractButton 的功能,并实现自定义的按钮行为。 如以下代码: btu = QAbstractButton(window) btu.setText('按钮') 结果: 当我们实例化一个QAbstractButton对象时发生错误,原因就是C++的抽象类无法直接被实例化,而应该去子类化一个类,也就是写一个继承自QAbstractButton的类才可以。 再看以下代码: class Btu(QAbstractButton): pass btu = Btu(window) btu.setText('按钮') 结果: 当我们想子类化抽象类时,必须要实现抽象类里面的所有抽象方法,即根据以上报错信息,我们必须要实现绘制事件paintEvent这样一个方法。 示例代码: from PyQt5.Qt import * import sys class Btu(QAbstractButton): def paintEvent(self, evt): # 1. 创建一个画家 painter = QPainter(self) # 2. 创建一支笔 QColor(RGB, 笔的宽度) pen = QPen(QColor(111, 100, 50), 3) # 3. 设置笔 painter.setPen(pen) # 4. 画家画 painter.

宝塔面板强制安装 MySQL8.0

宝塔面板强制安装 MySQL8.0 mysql 终于更新到 8.0,MySQL8.0 对比以往的版本有了很大的提升,但是要求的服务器配置也就变得越来越高。对于低配置服务器,在宝塔面板进行安装时,总会出现“至少需要 2 个 CPU 核心才能安装”或者“至少需要 XXX 内存才能安装”。但我们又想要体验 MySQL8.0 新版本,这时候该怎么办呢?只有强制在宝塔面板中安装 MySQL8.0。 低配置服务器在宝塔面板中安装 MySQL8.0 方法 远程连接到服务器中,进入/www/server/panel/install 并执行下面代码。 编译安装 MySQL8.0,请在远程控制台中输入下面脚本: SHELL 1 2 wget http://download.bt.cn/install/0/mysql.sh; bash mysql.sh install 5.7 极速安装 MySQL8.0,请在远程控制台中输入下面脚本 SHELL 1 2 wget http://download.bt.cn/install/1/mysql.sh; bash mysql.sh install 5.7 将 5.7 替换成你要安装的 mysql 版本。 请注意:如果你已经安装了数据库,上面的命令会卸载删除当前数据库及数据 这样低内存服务器在宝塔面板安装 Mysql8.0 就实现了!

vscode如何快速生成想要的vue格式代码

!+ tab键会生成标准的html格式代码 vue + tab键我也想让它生成我想要的格式代码,比方说经常用一些方法,生命周期,或者样式类型(less scss) 文件-> 首选项->配置用户代码片段 (点了之后可能会让github登录我的登录密码忘了就直接点了之后它显示了一个框) 然后找到vue.json { // Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and // description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are: // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.

ckeditor富文本编辑器的使用和图片上传,复制粘贴图片上传

项目开发需要用到在线编辑和图片上传,最终讨论使用ckeditor,原因就是其丰富的API。考虑到最新版本ckeditor5可能不够稳定,我们选择使用ckedtior4.9.2版本。官网链接:ckeditor官网 特别注意:下面截图中url中的/editor/upload/1?其中的 /1 是根据自己需求添加不同类型数据上传时候的区分,可以去掉,写成/editor/upload? 初始化ckeditor 第一步:下载ckeditor并引入js; <script src="/plugins/ckeditor/ckeditor.js" type="text/javascript"></script> <script src="/plugins/ckeditor/config.js" type="text/javascript"></script> 第二步:在html页面引入textarea标签; <!-- 富文本编辑器 --> <textarea name="content" id="editor"></textarea> 第三步:在js中初始化富文本编辑器; //初始换编辑器 var editor = CKEDITOR.replace(‘editor’, { filebrowserImageUploadUrl :“/picture/editor/upload/1”, removePlugins:‘elementspath,resize’, codeSnippet_theme: ‘zenburn’, height:‘600’ }); 注意:其中‘editor’必须跟第二步引入的textarea便签的id一致。filebrowserImageUploadUrl 是用来配置图片上传的; 做完这三步,富文本编辑器就可以基本使用。 但是,如果 进行图片上传,我们需要将图片单独上传到我们制定的服务器,然后返回url存储到数据库,这样处理图片才是最合理的。下面我们来说说图片上传: 图片上传: 第一步:在初始化ckeditor是配置filebrowserImageUploadUrl 属性,属性对应的值就是图片上传的后台连接; //初始换编辑器 var editor = CKEDITOR.replace(‘editor’, { filebrowserImageUploadUrl :“/picture/editor/upload/1”, removePlugins:‘elementspath,resize’, codeSnippet_theme: ‘zenburn’, height:‘600’ }); 第二步:配置config参数,在config.js中加入以下配置 /*将编辑器的语言设置为中文*/ config.language = 'zh-cn'; /*去掉图片预览框的文字*/ config.image_previewText = ' '; /*开启工具栏“图像”中文件上传功能,后面的url为图片上传要指向的的action或servlet*/ config.filebrowserImageUploadUrl= "/blog/uploadEditorImage"; 第三步:写后台上传图片代码: 注意:后台上传图片处理完,必须返回固定格式的json数据:

Ubuntu 18.04 LTS中cmake-gui编译opencv-3.4.16并供Qt Creator调用

一、安装opencv 1.下载opencv-3.4.16的源码并解压 2.在解压后的文件夹内新建文件夹build以及opencv_install 3.安装cmake和cmake-gui sudo apt install cmake sudo apt-get install cmake-gui 查看版本 lyc@ubuntu:~$ cmake --version cmake version 3.10.2 4.启动cmake-gui并设置 sudo cmake-gui (1)设置界面中source及build路径 (2)点击configure,选择第一个default项目,即默认本地编译器 (3)设置prefix,即安装路径 之前我在默认路径/usr/local/下已经安装交叉编译结果opencv-3.4.16-gcc-arm 这里我选择home文件夹 选择需要的库,我采用默认的。 博文(https://blog.csdn.net/zhiyuan2021/article/details/131407526)给了两个建议: 第一个建议是:在CMAKE_BUILD_TYPE 值处输入RELEASE,我查了一下,默认采用release方式编译,空着就行。 第二个建议是:在OPENCV_EXTRA_MODULES_PATH中填写opencv_contrib的路径,但我在configure时报错,好像是名称重复。等后面需要的时候,我再编译opencv_contrib吧。这次保留为空,这样configure就可以通过了。 也就是说,我没有采用这两个建议。 (4)依次点击configure, generate,之后关闭cmake-gui 4.进入opencv-3.4.16内的build文件夹,cmake-gui已经在其中生成了编译中间文件 执行: sudo make -j4 耐心等待结束!!! 执行: sudo make install 完成opencv安装。 注意:build文件夹不要删除,后期如果卸载本次安装的opencv-3.14.16,可以再次进入它并执行 sudo make uninstall 5.设置 /etc/ld.so.conf.d/opencv.conf,否则在第二部分Qt Creator编译OpenCV程序环节会出现如下错误 报错: …/lib/libopencv_core.so.3.4: cannot open shared object file: No such file or d… 原因是之前用cmake对opencv-3.4.16进行了交叉编译(详见本人博客),并设置了opencv.conf。 (如果是首次安装opencv,需要在目录/etc/ld.so.conf.d/下建立opencv.conf,命令为 touch opencv.conf )