程序设计背景
老师上课点名考虑公平性,要求实现随机点名
实现功能
- 随机点名
- 程序每次运行每个·名字只出现一次
- 简单混淆加密,防止同学篡改数据
界面预览
-
默认
-
点名
-
结束
基本思路
qml
实现程序界面random
实现随机点名base64
实现名单混淆
具体实现
辅助程序:对名单进行 base64
混淆
from pathlib import Path
import yaml
import base64
inputPath = Path(__file__).parent.parent / "data" / "yaml"
outputPath = Path(__file__).parent.parent / "data" / "base64"
for file in inputPath.iterdir():
yml: list = yaml.load(file.read_text(encoding="utf-8"), Loader=yaml.FullLoader)
code = base64.encodebytes(str(yml).encode("utf-8"))
output = outputPath / file.name.replace(".yml", "")
output.write_text(code.decode("utf-8"), encoding="utf-8")
- 通过
pathlib
确定输入输出路径 - 把从名单(YAML)中读取的数据混淆后保存
主程序
读取名单
names: list[str] = eval(
base64.decodebytes(
(DATA / "names").read_text(encoding="utf-8").encode("utf-8")
).decode("utf-8")
)
将数据目录下的 names
文件进行读取,解码
运行过程中的处理
class UI(QObject):
def __init__(self):
super().__init__()
@Slot(result=str)
def run(self):
name = random.choice(names) if names else "没有名字了,重启程序以继续"
try:
names.remove(name)
except:
...
return name
在ui调用 run()
方法时返回随机姓名,并将其从名单中删除
启动程序
if __name__ == "__main__":
app = QGuiApplication([])
app.setWindowIcon(QIcon(str(ROOT / "icon.png")))
qmlRegisterType(UI, "Py", 1, 0, "Py")
engine = QQmlApplicationEngine()
engine.addImportPath(QML)
engine.addImportPath(QML / "imports")
engine.load(QML / "main.qml")
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
- 设置图标
- 设置qml工程文件夹、
imports
文件夹为导入路径,避免qml加载失败 - 运行
UI实现
Qt Design Studio 使用
安装 Qt Design Studio
,用其创建工程(前人之述备矣,本文不再赘述,具体情况参考下面两位大佬的文章)
qml核心代码详解
import QtQuick 6.5
import QtQuick.Controls 6.5
import Ui
import QtQuick.Layouts
import Py
Rectangle {
id: page
width: Constants.width
height: Constants.height
anchors.fill: parent
color: Constants.backgroundColor
Py {
id: py
}
ColumnLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.rightMargin: 10
anchors.leftMargin: 10
anchors.bottomMargin: 10
anchors.topMargin: 10
Text {
id: name
text: qsTr("此处将显示名字")
font.pixelSize: 30
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
Layout.preferredWidth: 216
Layout.preferredHeight: 39
}
Button {
id: run
text: qsTr("获取随机姓名")
Layout.leftMargin: 0
Layout.fillWidth: true
Connections {
target: run
onClicked: name.text = py.run()
}
}
}
}
- 导入
- QtQuick组件
- 工程组件(Ui,有工程名称决定)
- python交互
- 在本文中为
Py.Py
- 由代码
qmlRegisterType(UI, "Py", 1, 0, "Py")
定义UI
为python中的类名- 两个
"Py" 分别为qml中的包名和模块名
- 数字为其版本号
- 在本文中为
- 连接python
- 将对象
id
设为py - 在后续程序中直接调用python函数
- 将对象
- 文本框
- 按钮
- 在点击时调用
name.text = py.run()
更新文本框 - 填充窗口的宽
- 在点击时调用
特别说明
本程序已开源:Gitee
2. 在后续程序中直接调用python函数
3. 文本框
4. 按钮
- 在点击时调用
name.text = py.run()
更新文本框 - 填充窗口的宽
特别说明
本程序已开源:Gitee