Skip to content

Commit 095e74f

Browse files
committed
docs(python-core): add convert-bytes-to-any-ctypes
1 parent a5bc568 commit 095e74f

File tree

4 files changed

+415
-311
lines changed

4 files changed

+415
-311
lines changed

docs/pypi-package/pyside6/chapter04/index.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,57 @@ description: 第 4 章:PySide6 控件
66
# 4. PySide6 控件
77

88
[[TOC]]
9+
10+
## QButtonGroup
11+
12+
在 Qt Designer 中,选择多个 `RadioButton` 对象右键,选择分配给按钮组,新建按钮组即可创建一个 `QButtonGroup`
13+
14+
## 使用 InputMask 设置字符掩码
15+
16+
`QLineEdit` 有一个属性是 `InputMask`,可以使用 `setInputMask` 进行设置,目的是设置字符掩码,限制用户输入的内容必须符合掩码。[^1]
17+
18+
[^1]: QLineEdit,Qt6,<https://doc.qt.io/qt-6/qlineedit.html#inputMask-prop>
19+
20+
下面是 Qt6 规范:
21+
22+
| 掩码字符 | 含义 |
23+
| :------: | :---------------------------------- |
24+
| `A` | 只能是字母且必须,取值为 `[a-zA-Z]` |
25+
| `a` | 同上但不是必须的 |
26+
| `N` | 字母或数字 `[0-9a-zA-Z]` |
27+
| `n` | 同上但不是必须的 |
28+
| `X` | 任何字符 |
29+
| `x` | 同上但不是必须的 |
30+
| `9` | 数字 `[0-9]` |
31+
| `0` | 同上但不是必须的 |
32+
| `D` | 数字 `[1-9]` |
33+
| `d` | 同上但不是必须的 |
34+
| `#` | 数字或加减号 `[0-9+-]`,不是必须的 |
35+
| `H` | 十六进制字符 `[0-9a-fA-F]` |
36+
| `h` | 同上但不是必须的 |
37+
| `B` | 二进制字符 `[01]` |
38+
| `b` | 同上但不是必须的 |
39+
40+
还可以使用元字符用于增强规则:
41+
42+
| 元字符 | 含义 |
43+
| :-------: | :--------------------------------- |
44+
| `>` | 所有字符都被转换为大写 |
45+
| `<` | 所有字符都被转换为小写 |
46+
| `!` | 关闭大小写转换 |
47+
| `;c` | 终止掩码规则并将空字符设置为 *`c`* |
48+
| `[ ] { }` | 保留内容 |
49+
| `\` | 转义上述掩码字符或元字符 |
50+
51+
总结:
52+
- 掩码字符中,大写为必须输入,小写为可选
53+
- 元字符可以混合使用以便控制输入方式
54+
55+
| 实例 | 含义 |
56+
| ---------------------------------- | ---------------------------- |
57+
| `000.000.000.000;_` | IP 地址,`_` 表示空白 |
58+
| `HH:HH:HH:HH:HH:HH;_` | MAC 地址 |
59+
| `0000-00-00` | ISO 日期,空白为空格 `' '` |
60+
| `>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#` | 许可证号码,大写,空白为 `#` |
61+
62+
如果我需要设计一个输入 4 字节十六进制数字的输入框,可以使用 `>HH-HH-HH-HH;_` 来表示。
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: 将 bytes 转换为任意 C 类型
3+
description: 将 bytes 转换为任意 C 类型
4+
---
5+
6+
# 将 bytes 转换为任意 C 类型
7+
8+
下面的方法实现了 `bytes` 转换到任意 C 类型。
9+
10+
```python
11+
from ctypes import POINTER, c_char_p, c_double, cast, sizeof
12+
from typing import TypeVar
13+
14+
_T = TypeVar('_T')
15+
16+
def cast_bytes(data_bytes: bytes, ctype: type[_T]) -> _T:
17+
"""Cast bytes to a ctype"""
18+
assert len(data_bytes) >= sizeof(ctype)
19+
return cast(
20+
c_char_p(data_bytes),
21+
POINTER(ctype)
22+
).contents
23+
24+
v = cast_bytes(b'\x7f' * 8, c_double)
25+
print(v.value)
26+
```
27+
28+
这样我们就获得了一个 `c_double` 类型的 `v` 变量,使用 `v.value` 很容易获得其值。
29+
30+
以上的代码相当于下面的 C++ 代码:
31+
32+
```cpp
33+
#include <iostream>
34+
using namespace std;
35+
36+
int main() {
37+
char a[] = "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f";
38+
double value = *(double*)a;
39+
cout << value << endl;
40+
return 0;
41+
}
42+
```
43+
44+
如果需要使用 Python 将 C 类型转换为二进制表示,使用 `memoryview` 即可。

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
"author": "Alex",
2121
"license": "ISC",
2222
"devDependencies": {
23-
"@vuepress/client": "2.0.0-beta.60",
23+
"@vuepress/client": "2.0.0-beta.61",
2424
"vue": "^3.2.47",
25-
"vuepress": "2.0.0-beta.60",
26-
"vuepress-plugin-auto-catalog": "2.0.0-beta.181",
27-
"vuepress-plugin-copy-code2": "2.0.0-beta.181",
28-
"vuepress-plugin-md-enhance": "2.0.0-beta.181",
29-
"vuepress-plugin-search-pro": "2.0.0-beta.181"
25+
"vuepress": "2.0.0-beta.61",
26+
"vuepress-plugin-auto-catalog": "2.0.0-beta.185",
27+
"vuepress-plugin-copy-code2": "2.0.0-beta.185",
28+
"vuepress-plugin-md-enhance": "2.0.0-beta.185",
29+
"vuepress-plugin-search-pro": "2.0.0-beta.185"
3030
}
3131
}

0 commit comments

Comments
 (0)