【Python】解决“Tk_GetPixmap: Error from CreateDIBSection”闪退问题

解决Python使用Tkinter的Notebook切换标签时出现的"Tk_GetPixmap: Error from CreateDIBSection 操作成功完成"闪退问题

零、问题描述

在使用Tkinter的Notebook控件时,对其标签进行切换,发现切换不了,一切换就报如下图错误:

第一个页面正常显示,后面的就都不行了,都是报这个错误。第一个页面里面是一些标签(label)、多选框(Checkbutton)、下拉框(Combobox)和按钮(Button),用的都是TTK的库,代码如下:

py 复制代码
self.label_in_way = ttk.Label(self.tab_in_setting)
self.label_in_way.place(relx=0.015, rely=0.018, height=21, width=52)
self.label_in_way.configure(text='''输入方式''')

self.cb_in_picture = ttk.Checkbutton(self.tab_in_setting)
self.cb_in_picture.place(relx=0.015, rely=0.073, relwidth=0.071, relheight=0.0, height=23)
self.cb_in_picture.configure(variable=self.cb_in_picture_var)
self.cb_in_picture.configure(text='''图片''')

self.cb_in_video = ttk.Checkbutton(self.tab_in_setting)
self.cb_in_video.place(relx=0.106, rely=0.073, relwidth=0.071, relheight=0.0, height=23)
self.cb_in_video.configure(variable=self.cb_in_video_var)
self.cb_in_video.configure(text='''视频''')

self.cb_in_net = ttk.Checkbutton(self.tab_in_setting)
self.cb_in_net.place(relx=0.197, rely=0.073, relwidth=0.071, relheight=0.0, height=23)
self.cb_in_net.configure(variable=self.cb_in_net_var)
self.cb_in_net.configure(text='''网络''')

self.cb_in_camera = ttk.Checkbutton(self.tab_in_setting)
self.cb_in_camera.place(relx=0.288, rely=0.073, relwidth=0.089, relheight=0.0, height=23)
self.cb_in_camera.configure(variable=self.cb_in_camera_var)
self.cb_in_camera.configure(text='''摄像头''')

self.cb_in_custom = ttk.Checkbutton(self.tab_in_setting)
self.cb_in_custom.place(relx=0.394, rely=0.073, relwidth=0.089, relheight=0.0, height=23)
self.cb_in_custom.configure(variable=self.cb_in_custom_var)
self.cb_in_custom.configure(text='''自定义''')

self.label_in_source = ttk.Label(self.tab_in_setting)
self.label_in_source.place(relx=0.015, rely=0.145, height=21, width=52)
self.label_in_source.configure(text='''输入来源''')

self.cb_in_source = ttk.Combobox(self.tab_in_setting)
self.cb_in_source.place(relx=0.015, rely=0.2, relheight=0.042, relwidth=0.964)
self.cb_in_source.configure(textvariable=self.cb_in_source_var)

self.btn_in_source_choose = ttk.Button(self.tab_in_setting)
self.btn_in_source_choose.place(relx=0.848, rely=0.255, height=27, width=87)
self.btn_in_source_choose.configure(text='''选择''')

第二个页面页差不多是这些东西,多选框换成了输入框(Entry)而已,代码如下:

py 复制代码
self.label_save_type = ttk.Label(self.tab_out_setting)
self.label_save_type.place(relx=10.0, rely=10.0, height=21, width=52)
self.label_save_type.configure(text='''保存类型''')

self.cb_prediction_info = ttk.Checkbutton(self.tab_out_setting)
self.cb_prediction_info.place(relx=10.0, rely=40.0, relwidth=71.0, relheight=0.0, height=23)
self.cb_prediction_info.configure(variable=self.cb_prediction_info_var)
self.cb_prediction_info.configure(text='''预测信息''')

self.cb_prediction_video = ttk.Checkbutton(self.tab_out_setting)
self.cb_prediction_video.place(relx=100.0, rely=40.0, relwidth=71.0, relheight=0.0, height=23)
self.cb_prediction_video.configure(variable=self.cb_prediction_video_var)
self.cb_prediction_video.configure(text='''预测视频''')

self.cb_raw_video = ttk.Checkbutton(self.tab_out_setting)
self.cb_raw_video.place(relx=200.0, rely=40.0, relwidth=71.0, relheight=0.0, height=23)
self.cb_raw_video.configure(variable=self.cb_raw_video_var)
self.cb_raw_video.configure(text='''原始视频''')

self.label_save_path = ttk.Label(self.tab_out_setting)
self.label_save_path.place(relx=10.0, rely=80.0, height=21, width=52)
self.label_save_path.configure(text='''保存位置''')

self.entry_path = ttk.Entry(self.tab_out_setting)
self.entry_path.place(relx=10.0, rely=110.0, relheight=23.0, relwidth=636.0)

self.btn_choose_save_path = ttk.Button(self.tab_out_setting)
self.btn_choose_save_path.place(relx=560.0, rely=140.0, height=27, width=87)
self.btn_choose_save_path.configure(text='''选择''')

到某度上查不到啥资料,只能自己解决,折腾了半天,碰巧发现了解决方案。

壹、解决问题

我做了如下尝试:

  1. 把页面二的所有控件清空,切换到页面二,不报错
  2. 页面二只留下标签(Label),不报错,也不显示
  3. 页面二只留下多选框(Checkbutton),也不报错,不显示
  4. 页面二只留下输入框(Entry),报错
  5. 页面二只留下按钮(Button),不报错,也不显示
  6. 页面二只删除输入框(Entry),不报错,也不显示

得出是输入框造成报错的结论,但是不显示是怎么回事呢?不知道

第一次尝试

简单分析页面一和页面二的情况,其他控件都一样,就输入框(Entry)和下拉框(Combobox)不一样,其中,下拉框设置了textvariable属性,输入框则没有,而下拉框是可以正常使用的,所以怀疑是textvariable属性的问题。

给输入框加上textvariable属性:

py 复制代码
self.entry_path_var = tk.StringVar()  # 创建值
self.entry_path = ttk.Entry(self.tab_out_setting)
self.entry_path.place(relx=10.0, rely=110.0, relheight=23.0, relwidth=636.0)
self.entry_path.configure(textvariable=self.entry_path_var)  # 设置值

还是报错。

第二次尝试

在刚刚的尝试中有一个现象,不报错也不显示,有没有一种可能,它不是不显示,只是显示到屏幕外边去了?

这边给它设置位置的就是place函数了,简单查了下它的用法,其中比较重要的:

relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge)

relx的作用是指定相对坐标,relx的取值为0~1的小数。如果relx=0,表示子控件的x方向的起始位置在父控件的最左边;如果rely=1,表示子控件的y方向的起始位置在父控件的最右边。

然后看了下我的代码,relx、rely、relheight和relwidth全都大于1了,可能是这个的问题。

重新改代码如下(尝试了一个控件,通过了,然后把一页的改了):

py 复制代码
self.label_save_type = ttk.Label(self.tab_out_setting)
self.label_save_type.place(relx=0.015, rely=0.018, height=21, width=52)
self.label_save_type.configure(text='''保存类型''')

self.cb_prediction_info = ttk.Checkbutton(self.tab_out_setting)
self.cb_prediction_info.place(relx=0.015, rely=0.073, relwidth=0.108, relheight=0.0, height=23)
self.cb_prediction_info.configure(variable=self.cb_prediction_info_var)
self.cb_prediction_info.configure(text='''预测信息''')

self.cb_prediction_video = ttk.Checkbutton(self.tab_out_setting)
self.cb_prediction_video.place(relx=0.152, rely=0.073, relwidth=0.108, relheight=0.0, height=23)
self.cb_prediction_video.configure(variable=self.cb_prediction_video_var)
self.cb_prediction_video.configure(text='''预测视频''')

self.cb_raw_video = ttk.Checkbutton(self.tab_out_setting)
self.cb_raw_video.place(relx=0.303, rely=0.073, relwidth=0.108, relheight=0.0, height=23)
self.cb_raw_video.configure(variable=self.cb_raw_video_var)
self.cb_raw_video.configure(text='''原始视频''')

self.label_save_path = ttk.Label(self.tab_out_setting)
self.label_save_path.place(relx=0.015, rely=0.145, height=21, width=52)
self.label_save_path.configure(text='''保存位置''')

self.entry_path = ttk.Entry(self.tab_out_setting)
self.entry_path.place(relx=0.015, rely=0.2, relheight=0.042, relwidth=0.964)

self.btn_choose_save_path = ttk.Button(self.tab_out_setting)
self.btn_choose_save_path.place(relx=0.848, rely=0.255, height=27, width=87)
self.btn_choose_save_path.configure(text='''选择''')

一切正常!

贰、总结

至此,问题解决,是调用place函数时传入的参数不正确造成的,rel(relative)开头的参数一般传入值的区间应该是0,1,改过就好了。我的代码是使用Page 7.6生成的,故没有多管它调用每个函数的细节。本次错误应该算是page 7.6的一个Bug。

叁、参考文献

  1. 记录一个没解决的createDIBSection失败的bug
  2. CreateDIBSection函数详解
  3. tkinter-place布局详解
  4. Python之tkinter 多选项卡 Notebook
相关推荐
砚底藏山河1 小时前
python量化入门:多周期数据对齐统一时间轴
java·数据库·python·金融·maven
毕业设计7032 小时前
(免费领源码)django空气净化器销售系统09218- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
python·scrapy·mysql·pycharm·django·flask·pandas
小小张说故事2 小时前
Python 闭包到底捕获了啥?一个计数器例子讲透,别再背定义了
python
深蓝AI2 小时前
AI Agent 点了发布却超时:一条回执丢失,为什么能造成两篇文章?
人工智能·python
怪奇云呼军2 小时前
教育试听预约后没到课,闪电智能 Voice Agent 如何做分层回访?
人工智能·python·算法·云计算·音视频
weixin199701080163 小时前
《淘宝TOP API:落地方案、接口边界与业务踩坑 —— 聚石塔内外价差 10 倍的真相》(附 Python 源码)
开发语言·python
梦想的颜色3 小时前
【编程实战】AI 时代 APP 开发全栈硬核指南:技术选型 + AI 架构 + 模型落地全维度决策
python·flutter·react native·react.js·ai·桌面应用·milvus
Madison-No73 小时前
多语言聊天大模型--测试报告
linux·git·python·selenium·jmeter·自动化·postman
鲲鹏ai3 小时前
盈启鲲鹏数字人招商政策
大数据·人工智能·python
荣码3 小时前
从0到1搭一个生产级RAG系统:串联前面21篇所有知识
java·python