Upload 5 files
Browse files- app.py +378 -0
- src/home.png +0 -0
- src/question_1.jpg +0 -0
- src/weixin.png +0 -0
- src/zanshang.png +0 -0
app.py
ADDED
@@ -0,0 +1,378 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import random
|
3 |
+
import time
|
4 |
+
|
5 |
+
css = '''
|
6 |
+
.show img {height: 320px}
|
7 |
+
.result img {height: 320px}
|
8 |
+
.qrcode img {height: 225px}
|
9 |
+
.btn {
|
10 |
+
justify-content: normal
|
11 |
+
}
|
12 |
+
'''
|
13 |
+
|
14 |
+
def get_new_question_and_options():
|
15 |
+
time.sleep(1.5)
|
16 |
+
number = random.randint(1,65536)
|
17 |
+
return {
|
18 |
+
"question_text": f"问题{number}是这样的。",
|
19 |
+
"option_A": f"问题{number}给出的选项A,吃饭",
|
20 |
+
"option_B": f"问题{number}给出的选项B,睡觉",
|
21 |
+
"option_C": f"问题{number}给出的选项C,打豆豆",
|
22 |
+
}
|
23 |
+
|
24 |
+
def get_option_result(question_text, option_text):
|
25 |
+
time.sleep(1.5)
|
26 |
+
numbers = [
|
27 |
+
random.randint(-10,10),
|
28 |
+
random.randint(-10,10),
|
29 |
+
random.randint(-10,10),
|
30 |
+
random.randint(-10,10)
|
31 |
+
]
|
32 |
+
|
33 |
+
return {
|
34 |
+
"result_text": f"问题“{question_text}”执行“{option_text}”选项,结果完成了",
|
35 |
+
"score_text": f"导致四个维度增减情况为 {numbers[0]} {numbers[1]} {numbers[2]} {numbers[3]}",
|
36 |
+
"deltas": numbers
|
37 |
+
}
|
38 |
+
|
39 |
+
def typePUA(a):
|
40 |
+
|
41 |
+
x = '0' if a[0] <= 50 else '1'
|
42 |
+
y = '0' if a[1] <= 50 else '1'
|
43 |
+
z = '0' if a[2] <= 50 else '1'
|
44 |
+
w = '0' if a[3] <= 50 else '1'
|
45 |
+
|
46 |
+
puatype = ''.join([x,y,z,w])
|
47 |
+
|
48 |
+
pua = {
|
49 |
+
"0000": "1 反PUA斗士",
|
50 |
+
"0001": "2",
|
51 |
+
"0010": "3",
|
52 |
+
"0011": "4",
|
53 |
+
"0100": "5",
|
54 |
+
"0101": "6",
|
55 |
+
"0110": "7",
|
56 |
+
"0111": "8",
|
57 |
+
"1000": "9",
|
58 |
+
"1001": "10",
|
59 |
+
"1010": "11",
|
60 |
+
"1011": "12",
|
61 |
+
"1100": "13",
|
62 |
+
"1101": "14",
|
63 |
+
"1110": "15",
|
64 |
+
"1111": "16 天生牛马打工人",
|
65 |
+
}
|
66 |
+
|
67 |
+
return pua[puatype]
|
68 |
+
|
69 |
+
with gr.Blocks(css=css).queue() as demo:
|
70 |
+
|
71 |
+
# 0 - 开始页面
|
72 |
+
# 1 - 测评页面
|
73 |
+
# 2 - 结果页面
|
74 |
+
page_index = gr.State(0)
|
75 |
+
|
76 |
+
# 用户信息
|
77 |
+
user_info = gr.State({
|
78 |
+
"user_name": ""
|
79 |
+
})
|
80 |
+
|
81 |
+
# 当前轮次评测问答数据
|
82 |
+
qa_data = gr.State({
|
83 |
+
"total": 3,
|
84 |
+
"progress": 1,
|
85 |
+
"question_text": "",
|
86 |
+
"result_text": "",
|
87 |
+
"score_text": "",
|
88 |
+
"options": [
|
89 |
+
"",
|
90 |
+
"",
|
91 |
+
"",
|
92 |
+
""
|
93 |
+
],
|
94 |
+
"deltas": [0,0,0,0],
|
95 |
+
"canOptionA": True,
|
96 |
+
"canOptionB": True,
|
97 |
+
"canOptionC": True,
|
98 |
+
"canOptionD": False,
|
99 |
+
"canFillD": True,
|
100 |
+
"canRestart": True,
|
101 |
+
"canRefresh": True,
|
102 |
+
"canNext": False,
|
103 |
+
"nextName": "➡️ 下一题",
|
104 |
+
})
|
105 |
+
|
106 |
+
# 评测结果数据
|
107 |
+
result_data = gr.State({
|
108 |
+
"avdice_text": "",
|
109 |
+
"score_text": "",
|
110 |
+
"score": [50,50,50,50]
|
111 |
+
})
|
112 |
+
|
113 |
+
gr.Markdown("# 😅别再PUA啦:基于多智能体的被PUA指数心理测评游戏")
|
114 |
+
gr.Markdown("### 😋机智选择,远离PUA😈")
|
115 |
+
|
116 |
+
with gr.Tab("测评"):
|
117 |
+
|
118 |
+
# 0 - 开始页面
|
119 |
+
@gr.render(inputs=[page_index, user_info, qa_data, result_data])
|
120 |
+
def show_page_by_index(index, user, qa, result):
|
121 |
+
|
122 |
+
# 未输入昵称的主页
|
123 |
+
if index == 0:
|
124 |
+
gr.Image(elem_classes="show", value="./src/home.png", label="首页图", height=400, interactive=False)
|
125 |
+
with gr.Group():
|
126 |
+
with gr.Row():
|
127 |
+
user_name = gr.Textbox(placeholder="输入您的昵称", value=user["user_name"], container=False)
|
128 |
+
start = gr.Button(value="▶️ 开始测评", variant="primary")
|
129 |
+
|
130 |
+
def onStart(user_name, user=user, index=index, qa=qa, result=result):
|
131 |
+
if not user_name.strip():
|
132 |
+
raise gr.Error("输入您的昵称后才能进行测评!", duration=3)
|
133 |
+
|
134 |
+
user["user_name"] = user_name
|
135 |
+
index = 1
|
136 |
+
qa["progress"] = 1
|
137 |
+
|
138 |
+
res = get_new_question_and_options()
|
139 |
+
qa["question_text"] = res["question_text"]
|
140 |
+
qa["options"][0] = res["option_A"]
|
141 |
+
qa["options"][1] = res["option_B"]
|
142 |
+
qa["options"][2] = res["option_C"]
|
143 |
+
|
144 |
+
qa["canOptionA"] = True
|
145 |
+
qa["canOptionB"] = True
|
146 |
+
qa["canOptionC"] = True
|
147 |
+
qa["canOptionD"] = False
|
148 |
+
qa["canFillD"] = True
|
149 |
+
qa["canRestart"] = True
|
150 |
+
qa["canRefresh"] = True
|
151 |
+
qa["canNext"] = False
|
152 |
+
|
153 |
+
result["score"] = [50,50,50,50]
|
154 |
+
|
155 |
+
print(qa, result)
|
156 |
+
return index, user, qa, result
|
157 |
+
|
158 |
+
start.click(onStart, [user_name], [page_index, user_info, qa_data, result_data])
|
159 |
+
|
160 |
+
# 1 - 测评页面
|
161 |
+
elif index == 1:
|
162 |
+
gr.Markdown(f"您好,{user['user_name']}。请根据如下提示完成测评流程!小心不要被 PUA 到啦 ~")
|
163 |
+
with gr.Row():
|
164 |
+
with gr.Column():
|
165 |
+
gr.Image(elem_classes="show", value=f"./src/question_{qa['progress']}.jpg", label="事件图示", height=400, interactive=False)
|
166 |
+
gr.Slider(label=f"测评进度(共{qa['total']}题)", value=qa['progress'], minimum=0, maximum=qa["total"], step=1, interactive=False)
|
167 |
+
gr.Markdown("当前分数")
|
168 |
+
with gr.Group():
|
169 |
+
gr.Slider(label="维度1", value=result["score"][0], minimum=0, maximum=100, step=1, interactive=False)
|
170 |
+
gr.Slider(label="维度2", value=result["score"][1], minimum=0, maximum=100, step=1, interactive=False)
|
171 |
+
gr.Slider(label="维度3", value=result["score"][2], minimum=0, maximum=100, step=1, interactive=False)
|
172 |
+
gr.Slider(label="维度4", value=result["score"][3], minimum=0, maximum=100, step=1, interactive=False)
|
173 |
+
with gr.Column():
|
174 |
+
question_text = gr.TextArea(label="事件背景", value=qa["question_text"], placeholder="请等待生成", interactive=False, lines=4)
|
175 |
+
result_text = gr.TextArea(label="事件结果", value=qa["result_text"], placeholder="请根据事件背景,结合个人实际情况做出选择。注意,选择之间并无对错之分。", interactive=False, lines=4)
|
176 |
+
score_text = gr.TextArea(label="分数变更", value=qa["score_text"], placeholder="请根据事件背景,结合个人实际情况做出选择。注意,选择之间并无对错之分。", interactive=False, lines=4)
|
177 |
+
option_A_button = gr.Button(value=f"A: {qa['options'][0]}", interactive=qa["canOptionA"], elem_classes="btn")
|
178 |
+
option_B_button = gr.Button(value=f"B: {qa['options'][1]}", interactive=qa["canOptionB"], elem_classes="btn")
|
179 |
+
option_C_button = gr.Button(value=f"C: {qa['options'][2]}", interactive=qa["canOptionC"], elem_classes="btn")
|
180 |
+
with gr.Group():
|
181 |
+
option_D_button = gr.Button(value="D: 我选这个", interactive=qa["canOptionD"], elem_classes="btn")
|
182 |
+
option_D_text = gr.Textbox(show_label=False, value=qa['options'][3], placeholder="我有独特的主见", interactive=qa["canFillD"], container=False)
|
183 |
+
|
184 |
+
def onClickABC(question_text, btn, qa=qa, result=result):
|
185 |
+
option_text = btn[2:]
|
186 |
+
res = get_option_result(question_text, option_text)
|
187 |
+
|
188 |
+
qa["result_text"] = res["result_text"]
|
189 |
+
qa["score_text"] = res["score_text"]
|
190 |
+
qa["deltas"] = res["deltas"]
|
191 |
+
qa["canOptionA"] = False
|
192 |
+
qa["canOptionB"] = False
|
193 |
+
qa["canOptionC"] = False
|
194 |
+
qa["canOptionD"] = False
|
195 |
+
qa["canFillD"] = False
|
196 |
+
qa["canRefresh"] = False
|
197 |
+
qa["canNext"] = True
|
198 |
+
|
199 |
+
for i in range(len(result["score"])):
|
200 |
+
result["score"][i] = max(min(result["score"][i] + res["deltas"][i], 100), -100)
|
201 |
+
if qa["progress"] == qa["total"]:
|
202 |
+
qa["nextName"] = "✨查看结果"
|
203 |
+
|
204 |
+
print(qa["progress"],qa["total"])
|
205 |
+
return qa["result_text"], qa["score_text"], qa, result
|
206 |
+
|
207 |
+
def onClickD(question_text, option_D_text, qa=qa, result=result):
|
208 |
+
res = get_option_result(question_text, option_D_text)
|
209 |
+
|
210 |
+
qa["result_text"] = res["result_text"]
|
211 |
+
qa["score_text"] = res["score_text"]
|
212 |
+
qa["deltas"] = res["deltas"]
|
213 |
+
qa["canOptionA"] = False
|
214 |
+
qa["canOptionB"] = False
|
215 |
+
qa["canOptionC"] = False
|
216 |
+
qa["canOptionD"] = False
|
217 |
+
qa["canFillD"] = False
|
218 |
+
qa["canRefresh"] = False
|
219 |
+
qa["canNext"] = True
|
220 |
+
|
221 |
+
for i in range(len(result["score"])):
|
222 |
+
result["score"][i] = max(min(result["score"][i] + res["deltas"][i], 100), -100)
|
223 |
+
|
224 |
+
if qa["progress"] == qa["total"]:
|
225 |
+
qa["nextName"] = "✨查看结果"
|
226 |
+
|
227 |
+
print(qa, result)
|
228 |
+
return qa["result_text"], qa["score_text"], qa, result
|
229 |
+
|
230 |
+
def onChangeD(option_D_text, qa=qa):
|
231 |
+
qa["options"][3] = option_D_text
|
232 |
+
if option_D_text.strip():
|
233 |
+
qa["canOptionD"] = True
|
234 |
+
else:
|
235 |
+
qa["canOptionD"] = False
|
236 |
+
|
237 |
+
print(qa, result)
|
238 |
+
return qa
|
239 |
+
|
240 |
+
option_A_button.click(onClickABC, [question_text, option_A_button], [result_text, score_text, qa_data, result_data])
|
241 |
+
option_B_button.click(onClickABC, [question_text, option_B_button], [result_text, score_text, qa_data, result_data])
|
242 |
+
option_C_button.click(onClickABC, [question_text, option_C_button], [result_text, score_text, qa_data, result_data])
|
243 |
+
option_D_button.click(onClickD, [question_text, option_D_text], [result_text, score_text, qa_data, result_data])
|
244 |
+
option_D_text.blur(onChangeD, option_D_text, qa_data)
|
245 |
+
|
246 |
+
with gr.Row():
|
247 |
+
restart = gr.Button(value="↩️ 重新开始", interactive=qa["canRestart"])
|
248 |
+
refresh = gr.Button(value="🔄️ 刷新", interactive=qa["canRefresh"])
|
249 |
+
next = gr.Button(value=qa["nextName"], interactive=qa["canNext"])
|
250 |
+
|
251 |
+
def onRestart(index=index):
|
252 |
+
index = 0
|
253 |
+
return index
|
254 |
+
|
255 |
+
def onRefresh(qa=qa, result=result):
|
256 |
+
res = get_new_question_and_options()
|
257 |
+
qa["question_text"] = res["question_text"]
|
258 |
+
qa["result_text"] = ""
|
259 |
+
qa["score_text"] = ""
|
260 |
+
qa["options"][0] = res["option_A"]
|
261 |
+
qa["options"][1] = res["option_B"]
|
262 |
+
qa["options"][2] = res["option_C"]
|
263 |
+
qa["options"][3] = ""
|
264 |
+
qa["canOptionA"] = True
|
265 |
+
qa["canOptionB"] = True
|
266 |
+
qa["canOptionC"] = True
|
267 |
+
qa["canOptionD"] = False
|
268 |
+
qa["canFillD"] = True
|
269 |
+
qa["canRestart"] = True
|
270 |
+
qa["canRefresh"] = True
|
271 |
+
qa["canNext"] = False
|
272 |
+
|
273 |
+
print(qa, result)
|
274 |
+
return qa["question_text"] , qa["result_text"], qa["score_text"], qa["options"][3], qa, result
|
275 |
+
|
276 |
+
def onNext(index=index, qa=qa, result=result):
|
277 |
+
if qa["nextName"] == "➡️ 下一题":
|
278 |
+
qa["progress"] += 1
|
279 |
+
|
280 |
+
res = get_new_question_and_options()
|
281 |
+
qa["question_text"] = res["question_text"]
|
282 |
+
qa["result_text"] = ""
|
283 |
+
qa["score_text"] = ""
|
284 |
+
qa["options"][0] = res["option_A"]
|
285 |
+
qa["options"][1] = res["option_B"]
|
286 |
+
qa["options"][2] = res["option_C"]
|
287 |
+
qa["options"][3] = ""
|
288 |
+
qa["canOptionA"] = True
|
289 |
+
qa["canOptionB"] = True
|
290 |
+
qa["canOptionC"] = True
|
291 |
+
qa["canOptionD"] = False
|
292 |
+
qa["canFillD"] = True
|
293 |
+
qa["canRestart"] = True
|
294 |
+
qa["canRefresh"] = True
|
295 |
+
qa["canNext"] = False
|
296 |
+
|
297 |
+
print(qa, result)
|
298 |
+
return qa["question_text"] , qa["result_text"], qa["score_text"], qa["options"][3], index, qa, result
|
299 |
+
else:
|
300 |
+
qa["question_text"] = ""
|
301 |
+
qa["result_text"] = ""
|
302 |
+
qa["score_text"] = ""
|
303 |
+
qa["options"][0] = ""
|
304 |
+
qa["options"][1] = ""
|
305 |
+
qa["options"][2] = ""
|
306 |
+
qa["options"][3] = ""
|
307 |
+
qa["canOptionA"] = True
|
308 |
+
qa["canOptionB"] = True
|
309 |
+
qa["canOptionC"] = True
|
310 |
+
qa["canOptionD"] = False
|
311 |
+
qa["canFillD"] = True
|
312 |
+
qa["canRestart"] = True
|
313 |
+
qa["canRefresh"] = True
|
314 |
+
qa["canNext"] = False
|
315 |
+
index = 2
|
316 |
+
return "", "", "", "", index, qa, result
|
317 |
+
|
318 |
+
restart.click(onRestart, None, page_index)
|
319 |
+
refresh.click(onRefresh, None, [question_text, result_text, score_text, option_D_text, qa_data, result_data])
|
320 |
+
next.click(onNext, None, [question_text, result_text, score_text, option_D_text, page_index, qa_data, result_data])
|
321 |
+
|
322 |
+
# 2 - 结果页面
|
323 |
+
else:
|
324 |
+
gr.Markdown("### 测评结果")
|
325 |
+
with gr.Row():
|
326 |
+
with gr.Column():
|
327 |
+
gr.Image(elem_classes="result", value="./src/home.png", label="测评结果图示", height=400, interactive=False)
|
328 |
+
gr.Markdown("最终分数")
|
329 |
+
with gr.Group():
|
330 |
+
gr.Slider(label="维度1", value=result["score"][0], minimum=0, maximum=100, step=1, interactive=False)
|
331 |
+
gr.Slider(label="维度2", value=result["score"][1], minimum=0, maximum=100, step=1, interactive=False)
|
332 |
+
gr.Slider(label="维度3", value=result["score"][2], minimum=0, maximum=100, step=1, interactive=False)
|
333 |
+
gr.Slider(label="维度4", value=result["score"][3], minimum=0, maximum=100, step=1, interactive=False)
|
334 |
+
with gr.Column():
|
335 |
+
with gr.Row():
|
336 |
+
gr.Number(label="您的被PUA指数", value=sum(result["score"])/4, interactive=False)
|
337 |
+
gr.Textbox(label="您的被PUA类型", value=typePUA(result["score"]), interactive=False, placeholder="测评结束后生成")
|
338 |
+
gr.TextArea(label="您的测评结果解释", placeholder="测评结束后生成", interactive=False, lines=6)
|
339 |
+
gr.TextArea(label="可能的解决方案", placeholder="测评结束后生成", interactive=False, lines=14)
|
340 |
+
restart = gr.Button(value="↩️ 重新开始", interactive=qa["canRestart"])
|
341 |
+
|
342 |
+
def onRestart(index=index):
|
343 |
+
index = 0
|
344 |
+
return index
|
345 |
+
|
346 |
+
restart.click(onRestart, None, page_index)
|
347 |
+
|
348 |
+
gr.Button(value="如果对您有用,欢迎分享网站与测评结果 🥰", variant="primary")
|
349 |
+
|
350 |
+
# # 历史测评结果
|
351 |
+
# with gr.Tab("历史"):
|
352 |
+
# pass
|
353 |
+
|
354 |
+
# # 测评原理解释
|
355 |
+
# with gr.Tab("说明"):
|
356 |
+
# pass
|
357 |
+
|
358 |
+
# 作者声明
|
359 |
+
with gr.Tab("关于"):
|
360 |
+
gr.Markdown("")
|
361 |
+
gr.Markdown("**Datawhale AI夏令营(第四期)x 浪潮信息 “源”大模型应用开发活动**")
|
362 |
+
gr.Markdown("---")
|
363 |
+
gr.Markdown("**项目名称**:别再PUA啦:基于多智能体的被PUA指数心理测评游戏")
|
364 |
+
gr.Markdown("**项目Slogan**:机智选择,远离PUA")
|
365 |
+
gr.Markdown("**项目简介**:“别再PUA啦”是一款创新的心理测评游戏,它基于多智能体技术,旨在通过互动游戏的形式,测量个体对PUA策略的抵抗力和识别能力,从而帮助用户提高自我保护意识和社交技巧。")
|
366 |
+
gr.Markdown("**项目技术栈**:Yuan 2.0,RAG,Langchain,Muiti-Agent, Gradio")
|
367 |
+
gr.Markdown("**项目演示视频**:【TODO】")
|
368 |
+
gr.Markdown("**项目构建分析与复盘博客**:【TODO】")
|
369 |
+
gr.Markdown("---")
|
370 |
+
gr.Markdown("**作者**:胡钧耀(南开大学计算机视觉在读一年级直博生,个人研究兴趣方向为视觉AIGC)")
|
371 |
+
gr.Markdown("**联系方式**:微信(LittleDream_hjy),[Bilibili](https://space.bilibili.com/2042113),[GitHub](https://github.com/JunyaoHu),[个人主页](https://junyaohu.github.io)")
|
372 |
+
with gr.Row():
|
373 |
+
gr.Image(elem_classes="qrcode", value="./src/weixin.png", label="微信", height=250)
|
374 |
+
gr.Image(elem_classes="qrcode", value="./src/zanshang.png", label="感谢支持", height=250)
|
375 |
+
|
376 |
+
if __name__ == "__main__":
|
377 |
+
# demo.launch()
|
378 |
+
demo.launch(share=True)
|
src/home.png
ADDED
![]() |
src/question_1.jpg
ADDED
![]() |
src/weixin.png
ADDED
![]() |
src/zanshang.png
ADDED
![]() |