前言
通过前四个章节,实现了一个能够嵌入多种类型数据和定制样式的二维码生成工具,其具有了生成图像、在界面中显示图像、设置图像风格、另存为图像、界面状态提示和国际化等相对完备的功能。但仍存在许多可以改进的地方,其中比较显著的问题如下:
1、多行文本的字数未作强制限制,仅通过弹窗提示上限为 200;
2、背景图模式下,输入数据实时修改二维码存在明显的卡顿问题;
3、myqr 库的数据输入不支持中文。
笔者将在这个章节,继续说明针对这三个问题的应对措施。
一、多行文本的字数限制
首先确定想要实现的效果:用户输入字数达到 200 时,弹窗提示字数限制为 200,后禁止用户输入。用户清空文本或使用退格键删除输入,使得字数小于 200 时可继续输入。
由于 QTextEdit 控件未直接提供这样的方法( QLineEdit 控件有
setMaxLength()
方法),笔者利用了修改“只读”的方式。每次输入时都会调用
show_words()
,当字数大于等于 200 时设置多行文本只读,小于 200 时解除只读。因此,只需要重写一个键盘事件,当按下退格键时解除只读,即可删除字符至 200 以下后继续修改内容。
def show_words(self): # 显示字数
nums = len(self.textEdit.toPlainText())
self.label_words_nums.setText(self.tr('Length: ')+ ' '*(3 - len(str(nums))) + f'{nums}/200')
if nums >= 200:
QMessageBox.about(self,self.tr('Remind'),self.tr('Limit words to 200 !'))
self.textEdit.setReadOnly(True)
else:
self.textEdit.setReadOnly(False)
def keyPressEvent(self, event): # 重写键盘事件
if event.key() == Qt.Key_Backspace:
self.textEdit.setReadOnly(False)
二、背景图模式下实时修改优化
前文中,为避免在多行文本的持续输入中造成频繁调用
getQR()
,是通过让用户完成输入后点击单独的按钮来解决的。如此操作降低了用户体验,且由于MyQR库的不便利性,单行文本输入也同样会存在频繁调用而造成卡顿的问题。但是,用 qrcode 库生成二维码效果就比较好,因此笔者考虑修改
QR_qrcode()
方法。
修改后的
QR_qrcode()
如下,采用的是把二维码“镂空”后叠加在背景图之上的思路,并且将生成图像保存在变量中,而不保存本地文件,避免在没有数据时仍加载了历史图像。
def QR_qrcode(data, size=5, imagepath=None, color='#000000',if_background = False, depth = 255):
try:
qr = qrcode.QRCode(
version = 4, # 精度,默认6
error_correction = qrcode.constants.ERROR_CORRECT_H,
box_size = size, # 尺寸,默认5
border = 3 )
qr.add_data(data)
qr.make(fit=True)
img = qr.make_image(fill_color = color)
img = img.convert('RGBA') # 设为彩色
if imagepath != None: # 如果打开了图片
logo = Image.open(imagepath) # 二维码中心的图片
logo = logo.convert('RGBA')
img_w, img_h = img.size # 二维码尺寸由box_size参数设定
if if_background == True: # 如果选择了背景图模式
print("背景图模式")
logo = change(logo, depth) # 将logo图作为背景图,调整背景图透明度
logo = logo.resize((img_w, img_h), Image.ANTIALIAS) # 将背景图大小缩放至和二维码图像一致
datas = img.getdata() # 获取二维码图像数据
new_data = list()
for item in datas: # 将二维码图像中白色像素点透明化
if item[0] == 255 and item[1] == 255 and item[2] == 255:
new_data.append((255, 255, 255, 0))
else:
new_data.append(item)
img.putdata(new_data) # 更新二维码图像
logo.paste(img, (0, 0), img) # 将背景图和二维码图像重叠
img = logo
elif if_background == False:
print("Logo模式")
logo_w = int(img_w / 4)
logo_h = int(img_h / 4)
logo = logo.resize((logo_w, logo_h), Image.ANTIALIAS)
w = int((img_w - logo_w) / 2) # logo在二维码中的位置
h = int((img_h - logo_h) / 2)
img.paste(logo, (w, h), logo)
# img.save('test_qr.png')
return img
except:
pass
三、背景图模式下输入中文数据
MyQR 库由于迷之原因不支持中文信息的录入,但 qrcode 库就不存在这个问题。在解决上一个问题后,这个问题自然也就解决了。来看一下新方法生成背景图的效果吧!

四、后记
到目前为止,这次做的小玩意儿还是没有迭代到让自己基本满意的程度。由于生成背景图模式的二维码的效率不高,每修改一个字符就调用生成的话,仍会出现卡顿。考虑应设计个计时器,在用户完成输入后,暂停输入一段时间后再调用,或是修改调用生成的逻辑,把背景图模式和其他区分开来。但使用自定义的镂空叠加方式生成带背景图的二维码,效果比 MyQR 库的效果还是要好一些。Emmmm,关于更多待优化的部分有机会的话会继续在本文补充的(咕咕)!然而又开始码下一个小玩意儿了(或许我只是沉迷于绘制新的打包后的程序图标),估计会把这次中的遗憾在下次解决掉吧哈哈哈。常言道,下次一定。
附件-打包后的exe:点击 度盘 提取码: ghff 。为避免卡顿影响体验,如需使用背景图,可先录入数据后再点击背景图单选按钮,修改数据需切换为logo模式,修改之后再切回背景图。
10.30.补充
通过牺牲一点点用户体验,解决实时修改数据时的卡顿问题,即不通过单行文本控件的单个字符修改的动作来调用生成,转为使用键盘快捷键 F5 来执行,可下载比较两个版本的操作区别,有可能被鲨毒软件干掉,需设置信任。附件-新版exe及源码:度盘 提取码: 2cqc