Zephyr255 发布的文章

出于一些原因我搞到了一台 Ender-3 V2 打印机,拧好了螺丝调好了平之后开机发现它读不出自带的 TF 卡里的文件。于是从树莓派里掏张卡出来,装几个 gcode 文件进去,重启打印机⸺然后发现卡在启动界面了。查打印机的说明书才发现它在开机时会自动读取 TF 卡里 .bin 文件。原来用在树莓派上的卡里肯定有不少 .bin 文件,猜测是打印机把其中的一个当打印机固件读取并刷写了,导致不开机。那怎么修复呢?你想看普通的修复教程?不不,那样就和随处可见(存疑)的论坛帖子没有区别了,这是为了博客特制的,明白吗?请阅读下文以感受我修复之路的痛楚⋯⋯尝试“正常”的修复方法去 创想三维的固件发布页 找到了原版固件,阅读说明得知只要把新固件放进 TF 卡里装进机器就可以自动更新固件。听起来非常的简单是不是,我们动手做一下吧。先把树莓派卡格式化成 FAT32,装上固件⸺等一下,这么多固件我选哪个,怎么也没有说明?从主板盖板下面的缝里打光能看到主板版本是 V4.2.2,就选个比较新而且不花里胡哨的 Ender-3 V2_HW_V4.2.2_SW_V1.0.7 吧。装上 TF 卡,重启打印机,然而并没有解决问题,还是卡在启动画面。换了原装 TF 卡装固件,还是没有作用。上网查一下呢?在 一篇红迪帖子 里找到了修复方法:用一张格式化为 FAT32,簇大小 4096B,容量不超过 32GB 的 TF 卡装上固件插进打印机里。按照指示重新格式化了卡然后装上固件,但依旧没有解决问题。打开主板盖板,拔掉常开风扇、挤出头加热棒、挤出头热敏电阻的线。还是没用。拆开挤出头,松一松固定热敏电阻的螺丝。什么也没有发生。那接下来怎么办?开始发癫抱着试一试的想法插了根线到打印机的 USB 口,然后 lsusb 一下,发现了经典 CH340 串口芯片。用串口终端打开一看,还真收到了打印机发送的信息:Update failed, No SD/TF-Card or error。但我明明装了卡啊,而且一开始不就是因为从这卡上错误地读了二进制文件才导致了问题的吗?猜测是误刷的固件把整块主控都搞得乱糟糟的了(实际上这个猜测错得离谱)。在主板上一通搜索,发现了熟悉的 SWDIO 和 SWCLK SWD 接口。连上 DAPLink 调试器,pyOCD 启动!警告:不要贸然尝试以下的任何代码!SWD 刷写很容易就可以把你的主控送上天!初步尝试 SWD观察主板得知主控芯片是 GD32F303RET6,那就先下载对应的目标文件:pyocd pack install GD32F303RE,成功建立与主控的通信。以防万一先读取备份一下主控的固件:pyocd cmd --target gd32f303re -c reset halt -c savemem 0 0x400000 e3v2_gd32f303_dump.bin(事后发现这个操作救了我)现在我们可以大胆去做了。先 pyocd erase -t gd32f303re -c 清空存储器,然后 pyocd flash --target gd32f303re -v ./GD-Ender-3\ V2Marlin2.0.6.1V1.0.5HW4.2.2 试着刷写原厂固件。然后不出所料地没用。插上 USB 线发现糟了,串口都没输出了。再次上网查资料:神秘的 RepRap 论坛 网友提到 V4.2.2 版本主板的固件应该存在 0x08007000 位置之后,而 0x0800000-0x08006FF 的这一段地址是分配给 bootloader 的。继续查阅 GD32F303 的技术手册,发现 0x00000000-0x002fffff 的这一段地址是映射到位于 0x08000000 - 0x082fffff 的主 FLASH 存储器的,而默认状况下这颗芯片上电后从 0x00000000 开始执行。看来通过 SWD 直写固件不工作的原因是固件需要依赖 bootloader 的存在才能工作,或者是链接时写死的内存位置因为我从 0x0000000 开始直接写入固件也混乱了。那么,原本的 bootloader 似乎不起作用,厂商提供的固件又依赖 bootloader 才能工作,我该怎么办呢?似乎自己编译固件才是唯一的方法了,毕竟这只是个普通的微控制器,也有开源的固件,想整一些非常规的花活应该也不困难。编译固件还好 Ender-3 V2 原装的固件就是基于 Marlin 的,对它的社区支持也相当完善,按照 Marlin 官方指引 很快就改好了一个配置文件。这里要注意创想三维在不改变主板版本号的情况下居然推出了使用两种(甚至更多)主控芯片的主板:有的是 STM32F1 系列,有的是 STM32F3 系列,还有的是 GD32F3 系列,而且(显然的)它们的固件并不通用,这也是为什么在原厂固件下载页面会有带 GD- 前缀和不带的固件版本。真不愧是三轮厂,我无语了。因为我的主板使用 GD32F303,所以要注意在 Configuration.h 里设置 #define MOTHERBOARD BOARD_CREALITY_V422_GD32_MFL。改配置文件本身倒没什么难的,直接复制官方给的配置例子都没什么问题。只是注意如果使用非 CrealityUI 的话,对屏幕的版本也有要求(对,创想三维还搞出了不同屏幕的花活)。然后在 ini/gd32.ini 里修改board_build.offset = 0x7000 board_upload.offset_address = 0x08007000为board_build.offset = 0x0 board_upload.offset_address = 0x08000000然后重新编译固件。现在通过 SWD 直写到 0x0 总能运行了吧?⋯⋯并不能。到底哪出错了?可能是固件的代码并不完全依赖这两个值计算地址,或许在什么地方有控制链接器行为的代码,但要调整那些的话难度也会陡然上升,再折腾下去时间成本就太高了,不如买块新主板了事。从头再来睡了一觉,倔劲又上来了,决定从头再来:看看一开始读取出来的固件,验证一下我之前的猜想。xxd e3v2_gd32f303_dump.bin | less 发现在 0x7000 之前的内容看起来确是 bootloader,且没有用完这段空间,在 0x6100 之后就全都是 0xFF 了,这样就和之前发现的地址布局相符。搜索一下,甚至能在 bootloader 的二进制文件里找到之前的 "Update failed, No SD/TF-Card or error" 字符串。继续往后看,0x7000 之后的空间里居然出现了和树莓派相关的字符串,证明打印机是错误读取了树莓派卡里的二进制文件才导致问题的猜测也是正确的。先刷回原来的 bootloader 试试。如果用 SWD 刷回的 bootloader 能产生串口输出,那我至少没把主控搞坏。用 dd if=ender3fwbk.bin of=extracted_bootloader.bin bs=1 count=$((0x7000)) 提取出二进制固件的前 0x7000 字节即为 bootloader。pyocd erase -t gd32f303re -c 把主控清除。接着 pyocd flash --target gd32f303re -v -a 0x08000000 extracted_bootloader.bin 把提取出的 bootloader 写入到 0x08000000。开机发现串口重新有输出了!继续试验:用回原来的 *.offset 值编译固件,然后 pyocd flash --target gd32f303re -v -a 0x08007000 刷写到 bootloader 之后的预定位置。开机,居然成功解决了问题?难道原来的 bootloader 没有损坏,之后的固件依然能读取?本来想在 0x08007000 之后刷回原厂固件测试一下的,但发现不知为何 SWD 已经连接不上主控了(可能是固件重设了 SWD 的映射引脚),但反正现在的固件也能用,遂作罢。总结清空树莓派 TF 卡,装上几个 GCode 文件插进打印机,发现不识别了。这时候想起来之前查资料的时候看到过 TF 卡的格式要求除了 FAT32 文件系统,4096B 簇大小以外还要求 MBR 分区表,大小不超过 8GB。按照这个要求重新格式化 TF 卡并装上 Gcode 文件,居然能读出来了。现在回想起来,我一开始假设 bootloader 被写坏或许就是错的。bootloader 并没有坏,是我的卡没有按要求格式化,导致装上原厂固件后插进机器不识别,才有了后面兜的大圈子。归根结底是创想三维不明确写明对 TF 卡的格式要求才导致了这一问题的发生,而且受害者远远不止我一个。珍爱生命,远离三轮厂⋯⋯附录:bootloader 文件如果有倒霉蛋不幸搞丢了自己的 bootloader,在此提供一份我提取的:extracted_firmware.bin附录:如何在 GNU/Linux 上按要求格式化 TF 卡插上新的装有 Gcode 的 TF 卡发现还是读不出来,只好重新格式化一下:lsblk 找到卡的块设备名。按照 SIZE 应该很好认出来。比如我的卡就显示为:sdb 8:16 1 29G 0 disk └─sdb1 8:17 1 5.6G 0 part在下文我会以此为例给出命令,请根据自己的系统调整。请再三确认你输对了目标,不然接下来的操作就要让你宝贵的数据进火葬场了。sudo wipefs -a /dev/sdb 清空卡上的所有文件系统。sudo parted /dev/sdb --script mklabel msdos 创建一个 DOS (MBR) 分区表,然后 sudo parted /dev/sdb --script mkpart primary fat32 1MiB 100% 创建一个使用整张卡容量的 FAT32 分区。有人提到过打印机不认大于 8G 的卡,我倒是没有遇到,但你或许可以试试调小分区以防患于未然。sudo mkfs.vfat -F 32 0s 8 -S 512 -n SDCARD /dev/sdb1 把新创建的分区设置到 512B 每扇区 × 8 扇区 = 4096B 簇大小。(题外话:“簇”是什么垃圾翻译?计算机领域的名词怎么都翻译得这么懒?诸位读者以后请务必用心翻译专业名词谢谢喵)你说你用的是 Windows?那不关我的事喵。

化学第四小考,极不称意;平生考试,此为最下。打牌。⸺胡适全集 第 27 卷量子力学学到现在深感无力,直呼不可理解,遂记此笔记以期整理思绪。基础狄拉克记号 (bra-ket notation)维基百科已经解释得很好了,在此直接引用:狄拉克符号或狄拉克标记 (Dirac notation) 是量子力学中广泛应用于描述量子态的一套标准符号系统。在这套系统中,每一个量子态都被描述为希尔伯特空间中的态矢量,定义为右矢 (ket):$| \psi \rangle$;每一个右矢的共轭转置定义为其左矢 (bra): $\langle \psi |$;换一种说法,右矢的厄米共轭(即取转置运算加上共轭复数运算),就可以得到左矢。简单地解释一下定义中的专业名词:量子态 (quantum state) 指量子系统的状态。态矢量 (state vector) 可以用于抽象地表示一个量子系统的状态。态矢量是希尔伯特空间中的一个矢量。希尔伯特空间即为完备的内积空间,其维数由其描述的物理系统定义。两个态矢量 $|\pm \psi \rangle$ 在二维的 1/2 自旋系统中构成一组基,其满足三条基本属性:$|+\rangle \cdot |+\rangle = 1$$|+\rangle \cdot |-\rangle = 0$$|\psi\rangle = a|+\rangle +b|-\rangle$通过厄米转置 (Hermitian conjugate,亦称埃尔米特转置) 可将右矢变换为左矢:若 $|\psi\rangle = a|+\rangle + b|+\rangle$,则 $\langle\psi| = a^\ast\langle+| + b^\ast\langle-|$量子力学中的内积之定义为左矢与右矢之积 $\langle\psi|\psi\rangle$符号之外,量子力学还有一套重要的基本公设:一个量子力学系统之状态(包括了其所有的可知性质)可在数学上使用归一化过的右矢 $|\psi\rangle$ 表示。一个物理可观测量由可作用于右矢上的算符 $A$ 表示。对某个可观测量的测量结果只可能是与其相对应的算符 $A$ 的一个特征值 $a_n$在对处于量子态 $|\psi\rangle$ 的系统的可观测量 $A$ 作测量时,得到结果 $a_n$ 的可能性是 $P_{a_n} = |\langle a_n|\psi\rangle|^2$,其中 $|a_n\rangle$ 为 $a_n$ 对应的归一化处理后的特征向量。测量 $A$ 得到结果 $a_n$ 后,该系统的量子态变为原系统之右矢在测量结果对应的右矢上的归一化投影:$$|\psi\rangle = \frac{P_n|\psi\rangle}{\sqrt{\langle \psi|P_n|\psi\rangle}}$$量子力学系统的时间演化可以由将其汉密顿量(或总能量)算子带入薛定谔方程得出:$$i\hbar\frac{d}{dt}|\psi\rangle=H(t)|\psi(t)\rangle$$不要恐慌!看不懂其中的专有名词是正常的,在接下来的章节中我们会慢慢解释它们的意义。矩阵表述使用上述的内容,我们唯一的描述矢的方法,便是使用其与其它矢的内积:$|\psi\rangle = \langle +|\psi\rangle|+\rangle+\langle-|\psi\rangle|-\rangle$于是 $|+\rangle_x$ 可以描述为 $|+\rangle_x=\langle + |+\rangle_x|+\rangle +\langle-|+\rangle_x|-\rangle = {1\over\sqrt{2}}|+\rangle+{1\over\sqrt{2}}|-\rangle$也就是说,只要选定一对基(即上述例子中的 $|+\rangle$ 和 $|-\rangle$,我们便可以用一对系数来描述一个量子态,例如上述的 $|+\rangle_x$ 可以写作 ${1\over\sqrt{2}}\begin{pmatrix}1\\1\end{pmatrix}$,而任意量子态 $|\psi\rangle$ 则可用 $\begin{pmatrix}\langle+|\psi\rangle\\ \langle-|\psi\rangle\end{pmatrix}$ 写成矩阵形式。为了符合矩阵运算法则,左矢可以写成右矢的共轭转置,即右矢 $|\psi\rangle=\begin{pmatrix}a\\b\end{pmatrix}$ 对应的左矢为 $\langle\psi|=\begin{pmatrix}a^*&b^*\end{pmatrix}$。任意量子系统注意到我们目前讨论的都是 1/2 自旋系统,因此一对基由两个正交的矢组成,测量结果也仅有 $+{1\over2}\hbar$ 和 $-{1\over 2}\hbar$ 两种。这显然不足以描述许多量子力学系统,因此我们将其扩展:对应测量结果 $a_n$ 的量子态为 $|a_n\rangle$,而这些量子态都满足狄拉克记号章节中所述的全部量子力学基本公设,即正交性与完全性,具体数学表述为下:正交性:$\langle a_i|a_j\rangle = \delta_{ij}$,其中 $\delta_{ij}$ 为克罗内克δ函数,满足 $\delta_{ij} = \left\{\begin{matrix}1 & (i=j)\\0 &(i\ne j)\end{matrix}\right.$完备性:$\forall|\psi\rangle:|\psi\rangle=\sum_i\langle a_i|\psi\rangle|a_i\rangle$算符与测量在基本公设 (2) 中,我们提到了代表可观测量的算符。算符可以作用于右矢上,并产生一个新的右矢,即 $A|\psi\rangle = |\phi\rangle$。若右矢 $|\psi\rangle$ 和值 $a$ 满足 $A|\psi\rangle=a|\psi\rangle$,我们便称 $|\psi\rangle$ 为算符 $A$ 的本征态 (eigenstate),$a$ 为算符 $A$ 的特征值 (eigenvalue)。这引出了基本公设 (3),即对某个可观测量的测量结果只可能是与其算符 $A$ 的一个特征值 $a_n$。在 1/2 自旋系统中,对Z方向自旋的测量对应自旋算符 $S_z$,对此可以写出特征值等式$$S_z|+\rangle=+{\hbar\over 2}|+\rangle$$ $$S_z|-\rangle=-{\hbar\over 2}|-\rangle.$$由 $A=\begin{pmatrix}\langle+|A|+\rangle & \langle+|A|-\rangle\\ \langle-|A|+\rangle & \langle-|A|-\rangle\end{pmatrix}$ 可得 $S_z = {\hbar\over2}\begin{pmatrix}1&0\\0&-1\end{pmatrix}$。注意到 $S_z$ 为对角矩阵,且其对角项为为算符的特征值。这是因为该矩阵表示使用的基正是 $S_z$ 的特征向量。易证:使用其特征向量作为基表示的算符矩阵永远为对焦矩阵;在该表示下,特征向量即为单位向量。在已知其特征值等式的情况下,我们现在可以用矩阵表示某个算符。这一过程的逆向,即在已知算符之矩阵表示的情况下,预测测量其对应可观测量的可能结果,其实就是给定矩阵,求其特征值的问题,想必有线性代数知识的人都知道该怎么做:设 $\mathrm{det}|A-\lambda I|=0$,求解得到的 $\lambda$ 就是 $A$ 的特征值。厄米算符在使用矩阵表示的情况下,$A|\psi\rangle=|\phi\rangle$ 非常合理:矩阵乘矢量等于矢量。但对于左矢,算符必须处在左矢的右边才能产生有定义的结果;同时,注意到 $\langle\psi|A\ne\langle\phi|$。我们需要对算符也进行操作才能使这个等式相等。为此,引入厄米伴随算符 $A^\dagger$,满足 $\langle\psi|A^\dagger=\langle\phi|$。若算符 $A$ 与其自身的厄米伴随算符相等,我们则称之为厄米(埃尔米特)或自伴。自伴算符有两个重要性质:自伴算符必有实特征值;自伴算符的特征向量构成一套完备的基。投影算符$|\psi\rangle=(\langle+|\psi\rangle)|+\rangle+(\langle-|\psi\rangle)|-\rangle$ 中的 $(\langle+|\psi\rangle)|+\rangle$ 可以重写为:$$(\langle+|\psi\rangle)|+\rangle=|+\rangle(\langle+|\psi\rangle)=(|+\rangle\langle+|)|\psi\rangle$$注意到括号中的部分 $|+\rangle\langle+|$ 作用于 $|\psi\rangle$ 上并产生了一个新的右矢。显然,这是一个算符,我们称之为外积。外积具有完备性:$|+\rangle\langle+|+|-\rangle\langle-|=\Bbb{1}$ 当外积的左矢可由右矢进行厄米转置得到,它便是一个投影算符。对应某个本征态的投影算符作用于右矢 $|\psi\rangle$ 上会产生一个新右矢,其方向与该本征态相同,大小等于 $|\psi\rangle$ 处于该本征态的幅度(含相位)。测量我们已经在基本公设中提到过如何计算量子系统处于某一状态中的概率,但仅仅知道概率显然是不够的,为此我们将介绍均值和标准差的计算方法。量子系统的均值是其所有可能性的平均值,其数学描述为:$$\langle A\rangle=\langle\psi|A|\psi\rangle=\sum_n a_n \mathcal{P}_{a_n}$$其中 $a_n$ 为算符 $A$ 的特征值。量子系统的标准差则由对其均值的离差做平方再开二次方根得到,数学描述为:$$\Delta A=\sqrt{\langle(A-\langle A\rangle)^2\rangle}=\sqrt{\langle A^2\rangle-\langle A\rangle^2}$$对易算符量子力学中,有时两个变量可以同时精确测量(例如氢原子的汉密顿量和角动量),有时不行(例如粒子的位置和动量)。决定这一关系的便是对易算符 (commutator),亦称交换子。对于可观测量 $A,B$,其数学定义为 $[A,B]=AB-BA$。若该式等于零,则我们称 $A,B$ 是对易的。这意味着它们有相同的本征态,且我们可以同时知道它们的精确值。反之,如若两个正交方向的自旋算符 $S_x,S_y$ 的对易算符 $[S_x, S_y]=i\hbar S_y$ 不等于零,则我们无法同时知道它们的精确值;换句话说,我们无法在不改变对 $S_y$ 测量结果的情况下测量 $S_x$。不确定性原理在上一节中我们引入了对易算符,并介绍了它与测量的关系。在这一节中我们给出对易算符与可观测量的标准差之间的关系:$$\Delta A\Delta B\ge{1\over2}|\langle A, B\rangle|$$这就是量子力学不确定性原理,其最著名的例子便是粒子的动量和位置无法同时得知:$[x,p]\ge i\hbar$。

本博客现通过 $\KaTeX$ 支持 $\LaTeX$测试一下:薛定谔方程:$$ i\hbar\frac{d}{dt}|\Psi\rangle = \hat{H}|\Psi\rangle $$积分形式微分形式$$\text{积分形式: }\oint_A\vec{E}\cdot d\vec{a}=\frac{Q_{enc}}{\epsilon_0}$$$$\text{微分形式: }\nabla \cdot\vec{E}=\frac{\rho}{\epsilon_0}$$

注意:本指南为8.2.11版QQ写成。当在Play版QQ中打开黑夜和/或简洁模式时,总会提示设置失败。这是因为激活这些模式需要从腾讯的服务器下载额外的CSS资源,而此版本使用的资源地址已经不再受支持。要解决这个问题,就需要在QQ发送资源请求后,将其重定向到正确的地址。我们可以使用LightProxy或任何类似的应用来完成这一操作。在此以LightProxy为例,提供一个解决方法。从上述链接中下载LightProxy并安装在LightProxy的规则中加入:http://showv6.gtimg.cn https://showv6.gtimg.cn http://iv6.gtimg.cn https://iv6.gtimg.cn http://gxh.material.qq.com https://gxh.material.qq.com http://qzonestyle.gtimg.cn https://qzonestyle.gtimg.cnCTRL+S保存规则,在右边栏中点击手机代理确保手机和运行LightProxy的主机处在同一网络下,按LightProxy的提示设置手机的代理;此处以类原生安卓系统为例:互联网 → <当前连接的Wifi> → 右上角'编辑'图标 → 高级选项 → 代理(手动)注:通常情况下可以不安装提供的证书打开QQ并重试打开黑夜/简洁模式,成功后可以将代理设回无并关闭LightProxy如果仍然失败,则在主机上的浏览器中打开LightProxy提供的地址,并在LightProxy中打开日志并寻找Username及Password字样使用日志中找到的凭证登录管理页面,并在其中找到以192.168开头的地址,依此再次设置手机代理重试打开黑夜/简洁模式,成功后可以将代理设回无并关闭LightProxy

我在使用Krita的时候,发现系统内所有KDE应用(包括Krita, Konsole, Dolphin等)的菜单栏(如下图)都消失了。经过一番搜索之后发现这是一个从2018年就开始出现的bug特性。解决方法也并不难:打开终端,输入cd /home/%USERNAME%/.config,回车 (请把%USERNAME%替换成您的用户名)输入find ./ -type f -exec sed -i 's/MenuBar=Disabled/MenuBar=Enabled/g' {} \;,回车;打开系统设置,进入应用程序样式 > 窗口装饰 > 标题栏按钮, 移除"应用程序菜单";回到系统设置的第一级,进入开机与关机 > 后台服务 > 应用程序菜单守护程序,将其关闭;重启打开的KDE应用,现在菜单栏应该会出现了。没错,我又水了一篇文章 (ゝ∀・)

事情的起因要从我试图把Vim的默认字体设成Firacode说起。这套字体支持所谓"Ligatures",简单来讲就是可以把"->""!="等两个符号组成的常用操作符连成单个符号。然而我的Vim似乎并不支持这种魔法,研究一下之后发现是我的Vim版本过旧所致。然而Debian的祖宗之法使得bullseye版本的官方.deb包最高只到8.2.2434,并不支持这套字体;Vim官方提供的Appimage也没法正常运行,那就只好自行编译了。经过了一番折腾之后,总结出来的步骤如下:sudo apt-get install libncurses libgtk2.0-dev libatk1.0-dev libcairo2-dev libx11-dev libxpm-dev libxt-devsudo apt-get build-dep vim-gtk vim-x11 #安装依赖git clone https://github.com/vim/vim.git #从Github获取编译所需的源代码cd vim/src #移动到vim/src/路径下sudo apt-get install ruby-dev #(可选)安装ruby支持./configure --with-features=huge --enable-gui=gtk3 --with-x #设置编译参数,确保编译后的结果带有GVimmake #编译sudo make install #安装,完成安装完成之后,Vim依然不支持Ligatures,需要手动启用这一功能::set guiligatures=!\"#$%&()*+-./:<=>?@[]^_{\|~ #这一串字符为允许Ligatures起作用的字符教程结束!

如果你使用过一些开源软件(例如Krita, QGIS和FreeCAD),你会发现它们都是基于Qt框架的。尽管它们中的一部分允许你在偏好设置里直接更改应用的字体,但另一部分则由于一些原因而没有加入这种功能。很不幸的是,这些应用在中文Windows系统下的默认字体都是臭名昭著的SimSun,即仿宋体(如下)。不过,由于这些软件使用的都是Qt框架,修改它们的默认字体相当容易。首先,你需要找到这些软件的Qt Stylesheet文件。以FreeCAD为例,你可以在<应用安装目录>\data\Gui\Stylesheets下找到这些.qss后缀的文件。如果这个目录下有多个.qss文件,则说明你的应用程序支持切换颜色主题。你只需要随便选一个,之后再在应用内切换成这个主题文件即可。注意: 你最好在开始下一步前备份一下现在的.qss文件,以免你不小心搞砸了什么东西...接下来,打开这个文件。在它的开头,你可以找到这样的一段代码:* { padding: 0px; margin: 0px; border: 0px; border-style: none; border-image: none; outline: 0; color: #f5f5f5; /* Default color for labels and different text elements that usually use dark colors */ }这段代码规定了该主题下软件的默认样式,而要修改默认字体,你只需要再在color: #f5f5f5;后面添加一行font-family: "Source Sans Pro";。如果你的电脑上有这一字体的话,这行代码会将程序的默认字体设为思源黑体。当然,你也可以将它改成其它的字体,或是根据这个参考页面更改其它的默认参数。完成修改后,保存这个.qss文件。在软件内切换到你修改过的主题或是重启一下软件后,你的设置应该就会生效了。这是将FreeCAD默认字体改成思源黑体后的样子:至此,教程结束。

1. 什么是XMPP?XMPP,全称Extensible Messaging and Presence Protocol (可扩展消息与状态协议), 是一种以XML为基础的开放式即时通信协议。XMPP项目自1998年开始开发,于2000年5月正式发布。虽然你很可能从未听说过它,但实际上你大概率已经多次使用过它了: 许多游戏的内置聊天系统都是基于XMPP的, 天国的Google Talk也使用了这个通信协议。接下来,我将向你介绍XMPP的优势,以及如何使用它。2. XMPP的优势在哪?为什么要使用它?I. 可扩展正如我们之前所提到的一样,XMPP基于XML,也就是eXtensible Markup Language (可扩展标记语言)。这一特性使得XMPP的可扩展性非常强大, 可以支持大量的插件和附加功能。举个例子: 我希望每条消息不仅可以包含原本的文本内容,还可以包含一条发送者所在国家的信息。那么,我们就只需要给客户端加入一个插件,使它可以在发送时添加这条信息并在读取时解读它。比如说,Adam想发送一条内容为"Hello"的信息到Betty的账户上,那么:原来的客户端的信息:<message from="adam@example.com"/> <message to="betty@example.com"> <body>Hello</body> </message>解读的结果就是Adam发送了一条内容为"Hello"的信息给Betty。加入了插件之后,信息变成:<message from="adam@example.com"/> <message to="betty@example.com"> <body>Hello</body> </message> <location type="available" > <country>CA</country> </location> 解读的结果是Adam发送了一条内容为"Hello"的信息给Betty; 同时Adam的客户端支持这个插件,他的所在国家是加拿大。由此可以看出,XMPP可以很简单地进行扩展。这也意味着,这个协议拥有大量的扩展: 在线状态,已读反馈... 这些插件让这个简单的协议变得非常强大。II. 分布式XMPP通信网络的结构和电子邮箱很像: 不同的邮箱域名之间可以互相通信,比如说Gmail和Outlook邮箱之间可以互发消息; XMPP也是这样, 比如这里(sedirk.cn)上的XMPP账号也可以与xabber.org上的另一个账号互发消息。因为这种分布式结构的缘故,即使这个网络里的某一个服务器故障了,其它服务器之间的通信也不受影响, 而不会像那些有中央服务器的通信工具(比如QQ, LINE)一样, 整个网络都陷入瘫痪; 同时, 因为每一台服务器都能连接上这个网络, 用户也有大量的XMPP服务提供商可以选择,而不必被限制只能使用一个提供商的服务。这个特点也使得XMPP的另一个重要特性成为现实,那就是它的自由性。III. 自由与安全我们之前提到用户可以自由选择XMPP服务提供商, 这意味着只要用户对服务提供商的使用协议不满意,可以随时改用另一家提供商的服务; 不仅如此, 用户还可以自行搭建自己的服务器,从而完全将自己的权利掌握在手中。在商业软件(比如QQ, 微信, LINE)中, 用户则根本没有这种选择的权利: 服务提供商可以随时无理由关停或锁死用户的账号, 或是强行要求用户同意它们的使用条款; 而在XMPP中,则不会有这种情况出现,用户也就可以享有最大程度的自由。除此之外,XMPP的核心协议和几乎全部的插件都是开放源代码的。这意味着XMPP通讯协议是完全开放透明的, 用户可以自由开发自己的客户端和服务器端程序,而不必被现有的程序所限制。这一特点在各大XMPP客户端应用上都有着体现: 因为有一整个开发者社区进行优化,它们的体积都非常小,通常小于100MB, 在运行过程中也只会占用极少量的内存空间; 相比之下, QQ等专有软件则有着动辄500MB的体积, 运行时也会占用大量的内存空间。此外,在数据隐私方面,XMPP还拥有OpenPGP, OMEMO等端对端加密程序,因此用户也无须担心自己的聊天内容被服务提供商或第三方获得。3. 那么,我该怎么使用XMPP聊天呢?I. 注册账户首先,你需要一个XMPP账户。在之前的介绍中我也提到,你有许多XMPP服务提供商可以选择。不过, 既然你是在这个提供XMPP服务的网站上看到了这篇文章,为什么不直接在这里注册呢? 当然, 其它服务提供商的注册方式也都与这里十分相似, 你大可以放心去使用它们提供的服务。下图为本网站上的XMPP注册页面:注册步骤:在"Username"中填写你想设置的用户名。"Name"作为你的昵称使用,可以不填。在"Email"中填写你的邮箱地址。这个邮箱将作为你找回密码的渠道使用。可以不填,但如果忘记了密码只能找管理员重置。在"Password"中填写你想设置的密码。在"Confirm Password"中再次填写你想设置的密码,防止填错。点击"Create Account"即可完成创建XMPP账户。现在你就可以开始使用XMPP服务了!II. 客户端现在,你应该已经拥有了自己的XMPP账号。下一步,你需要选择一个客户端。在xmpp.org上有大量针对不同平台的客户端推荐, 你大可以自己选择你喜欢的那一个。我个人推荐在Windows, MacOS或GNU/Linux系统里使用Gajim, 在安卓系统里使用Conversations, 在ios中使用Siskin IM或Monal。在接下来的教程中,我也将以这两个客户端为例。当然,这个网站也提供一个网页版的客户端,登录方式也很简单,在此不做赘述了。

对于我这种折腾佬来说,索尼的无反既便宜性能也不错,是一个作后背的极佳选择。然而,那些便宜大碗的机型的控制都非常糟心。例如NEX-5,只有一个拨轮,拿来作为项目的核心实在是不太够用。好在索尼为这些相机都做了一个PC控制软件,可以从电脑上控制参数,从而让我能享受较好的控制。为了给之后的项目铺路,今天我就来试着解析一下这个控制协议。首先先用软件监控接着相机的USB口的流量,这里我用了HHD的USB Analyzer。接上相机,控制其它参数不变,调整一个参数,捕捉流量信息。从B门开始逐渐调高速度直到1/4000s。然后关闭监控,回放记录:人肉解析数据流其实非常简单可以看见每个分包的数据都基本相同,只有一个数字不同,那这就是控制快门速度的参数了:25表示B门,26表示30s,27表示25s,以此类推可以找到所有快门速度对应的控制数值。对于ISO和光圈等参数同理,也可以分析出来。第一步解析到此结束,对于协议一开始相机和电脑握手的步骤就在下一篇文章再继续研究吧( ゚∀゚)

我自从买了a6300和斯坦尼康之后就一直在一个循环中挣扎:拍视频->上斯坦尼康->把肩带拆下来拍照片->手持怕摔->把肩带再装回去每天重复至少三次...这也是没有办法的事情嘛,谁叫我买了这台机器同时做摄影和摄像用途呢...然后我发现了这样一个好东西:Peak Design的肩带快扣!这玩意是这样子的:看起来超棒的一个设计...只可惜对我来说太贵了,148RMB一对虽说这样子的东西也有天朝仿制品,但是看评价似乎质量堪忧的样子然后我在翻着购物网站的时候它给我推了一个用登山扣的电脑包肩带想了一下之后...我明白了!这两个东西不是一样子的嘛...遂去附近的百货市场买了一对登山扣,装上去拆下来试试...拆装都超快的,甚至比PD店里面演示的还快而且这玩意还是全金属的!虽然是超薄的一层铝最重要的是这玩意的价格仅仅是Peak Design那玩意的0.054倍(^^所以说PD的快扣为什么那么受欢迎呢...大概就是因为它优雅一点罢看来我得更仔细地想一想怎么把我自己整的设计也弄优雅点了