1. 背景
最近我的同学需要处理他的XRD数据,要用到diffpy.pdfgui这个软件,但他不怎么熟悉命令行操作,就找我帮他在电脑上装一下。他发给我软件的官方网站,我后面按照该软件在GitHub上的官方文档进行安装。
但是安装的过程不是很顺利,在安装和运行过程中遇到了两个问题,现在记录一下。
2. 安装过程
我使用的安装环境:
- 操作系统:Windows 11专业版25H2
2.1 第一个问题:装完Miniconda后CMD里找不到conda
在Readme文档中,它推荐的安装方案是Miniconda,之前我并没有用过这个东西。这是它的官网,直接点击Get Started就能进入下载,但会要求你邮箱登录。下载到的是一个exe安装包,直接运行,一路点下一步都没啥问题。
很吊诡的是安装之后找不到入口:不论是传统软件那种快捷方式,还是直接在CMD里敲conda,都提示找不到这个命令。但实际上它已经装在电脑上了。
原因是安装时没有将Miniconda直接加入PATH,而新版安装器本身也不推荐这么做。对于CMD,更合适的方式是通过conda init配置shell初始化,让CMD在启动时自动加载conda。
由于当前CMD还无法直接识别conda命令,因此需要先使用conda.exe的完整路径执行conda init cmd.exe。
在CMD里运行(把路径换成你自己的Miniconda安装位置,conda.exe一般位于<安装目录>\Scripts\下):
"C:\Users\<用户名>\miniconda3\Scripts\conda.exe" init cmd.execonda init cmd.exe会为当前用户的CMD配置启动钩子,使CMD启动时能够自动加载conda。配置完成后,关闭当前CMD窗口,再重新打开一个CMD。
验证一下:
conda --version如果能正常打印版本号(我这边是conda 26.1.1),就说明CMD中的conda已经配置成功,之后可以直接使用conda activate等命令。
随后按照教程的步骤安装diffpy.pdfgui即可,这里就不赘述了。
2.2 第二个问题:wxPython 4.x移除了Bitmap.SetSize,pdfgui启动即崩溃
装好diffpy.pdfgui之后,需要唤起它的GUI图形界面:
conda activate diffpy.pdfgui_env
pdfgui就会出现报错:
(diffpy.pdfgui_env) C:\Users\<用户名>\AppData\Roaming\DemeterPerl>pdfgui
Adding duplicate image handler for 'Windows bitmap file'
Adding duplicate animation handler for '1' type
Adding duplicate animation handler for '2' type
Adding duplicate animation handler for '3' type
Element wxComboBox@000001404E349040 ("comboBox", HWND=0000000000480612) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E487CB0 ("panel", HWND=00000000001705A6).
Element wxListCtrl@000001404E2E0A60 ("listCtrl", HWND=00000000003E0578) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E487CB0 ("panel", HWND=00000000001705A6).
Element wxStaticText@000001404E509940 ("Fit Summary", HWND=000000000005071E) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E4889D0 ("panel", HWND=00000000008A04CE).
Element wxStaticText@000001404E505F10 ("Phase Configuration", HWND=0000000002B0056A) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BB5F0 ("panel", HWND=0000000000050732).
Element wxGrid@000001404E74F890 ("grid", HWND=00000000000905EE) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BB5F0 ("panel", HWND=0000000000050732).
Element wxStaticText@000001404E507AA0 ("a", HWND=000000000010059A) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BB5F0 ("panel", HWND=0000000000050732).
Element wxStaticText@000001404E50E2C0 ("Scale Factor", HWND=0000000000050758) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BB5F0 ("panel", HWND=0000000000050732).
Element wxStaticText@000001404E516980 ("Phase Constraints", HWND=0000000004B305E8) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6B9BB0 ("panel", HWND=00000000004F05DA).
Element wxGrid@000001404E767020 ("grid", HWND=0000000000030960) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6B9BB0 ("panel", HWND=00000000004F05DA).
Element wxStaticText@000001404E516C90 ("a", HWND=0000000000260622) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6B9BB0 ("panel", HWND=00000000004F05DA).
Element wxStaticText@000001404E518820 ("Scale Factor", HWND=00000000000308D4) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6B9BB0 ("panel", HWND=00000000004F05DA).
Element wxStaticText@000001404E519770 ("Phase Results", HWND=0000000000030A14) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BA0F0 ("panel", HWND=0000000000030992).
Element wxGrid@000001404E750F80 ("grid", HWND=000000000004090A) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BA0F0 ("panel", HWND=0000000000030992).
Element wxStaticText@000001404E5172B0 ("a", HWND=0000000000190600) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BA0F0 ("panel", HWND=0000000000030992).
Element wxStaticText@000001404E78B0E0 ("Scale Factor", HWND=000000000024045C) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BA0F0 ("panel", HWND=0000000000030992).
Element wxStaticText@000001404E78E800 ("Data Set Configuration", HWND=000000000003083A) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BA390 ("panel", HWND=000000000003081C).
Element wxStaticText@000001404E790390 ("Data Set Constraints", HWND=00000000001305FA) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BAE10 ("panel", HWND=00000000000307F0).
Element wxStaticText@000001404E791F20 ("Data Set Results", HWND=0000000000040856) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BA8D0 ("panel", HWND=0000000000030852).
Element wxStaticText@000001404E792540 ("Calculation Configuration", HWND=0000000000030940) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E6BAB70 ("panel", HWND=0000000000040794).
Element wxStaticText@000001404E796BB0 ("Preferences", HWND=00000000000207EA) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E7745C0 ("panel", HWND=00000000000307B0).
Element wxStaticText@000001404E7974E0 ("first", HWND=0000000000020886) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxTextCtrl@000001404E7F03D0 ("text", HWND=000000000002088A) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxStaticText@000001404E79B220 ("last", HWND=000000000002088E) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxTextCtrl@000001404E7EEB90 ("text", HWND=0000000000020892) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxStaticText@000001404E79AF10 ("step", HWND=0000000000020896) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxTextCtrl@000001404E7F09E0 ("text", HWND=000000000002089A) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxStaticText@000001404E799690 ("first", HWND=000000000002089E) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxTextCtrl@000001404E7F0FF0 ("text", HWND=00000000000208A2) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxStaticText@000001404E79A2D0 ("last", HWND=00000000000208A6) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxTextCtrl@000001404E7F2830 ("text", HWND=00000000000208AA) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxStaticText@000001404E79A8F0 ("step", HWND=00000000000208AE) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Element wxTextCtrl@000001404E7F1C10 ("text", HWND=00000000000208BC) of wxStaticBoxSizer should be created as child of its wxStaticBox and not of wxPanel@000001404E773360 ("panel", HWND=000000000002087E).
Traceback (most recent call last):
File "C:\Users\<用户名>\miniconda3\envs\diffpy.pdfgui_env\Lib\site-packages\diffpy\pdfgui\gui\main.py", line 26, in OnInit
self.frame = MainFrame(None, -1, "")
~~~~~~~~~^^^^^^^^^^^^^^
File "C:\Users\<用户名>\miniconda3\envs\diffpy.pdfgui_env\Lib\site-packages\diffpy\pdfgui\gui\mainframe.py", line 193, in __init__
self.__customProperties()
~~~~~~~~~~~~~~~~~~~~~~~^^
File "C:\Users\<用户名>\miniconda3\envs\diffpy.pdfgui_env\Lib\site-packages\diffpy\pdfgui\gui\mainframe.py", line 421, in __customProperties
self.__setupToolBar() # Make the toolbar
~~~~~~~~~~~~~~~~~~~^^
File "C:\Users\<用户名>\miniconda3\envs\diffpy.pdfgui_env\Lib\site-packages\diffpy\pdfgui\gui\mainframe.py", line 683, in __setupToolBar
bitmap.SetSize(size)
^^^^^^^^^^^^^^
AttributeError: 'Bitmap' object has no attribute 'SetSize'. Did you mean: 'GetSize'?
OnInit returned false, exiting...
(diffpy.pdfgui_env) C:\Users\<用户名>\AppData\Roaming\DemeterPerl>
好在这个问题我不是第一个遇到的。去GitHub的issue里看了一下,发现了同样问题的人,他在2026年8月4日提交了这个issue #303。他的解释是:wxPython 4.x移除了Bitmap对象的SetSize方法;而4以下的旧版wxPython已经不再通过标准渠道提供,标准安装流程只会拉到wxPython 4.x,于是调用SetSize时就崩了。
2.3 第二个问题的解决办法
按照issue提交者给出的临时方案,直接找到源码里的gui/mainframe.py,把bitmap.SetSize(...)那一行注释掉。以下命令在已激活diffpy.pdfgui_env环境的CMD里运行(%CONDA_PREFIX%是conda自动设置的环境变量,指向当前环境目录)。
首先备份一下这个文件:
copy "%CONDA_PREFIX%\Lib\site-packages\diffpy\pdfgui\gui\mainframe.py" "%CONDA_PREFIX%\Lib\site-packages\diffpy\pdfgui\gui\mainframe.py.bak"随后把那一行注释掉:
powershell -Command "(Get-Content '%CONDA_PREFIX%\Lib\site-packages\diffpy\pdfgui\gui\mainframe.py') -replace '^\s*bitmap\.SetSize\(size\)\s*$', ' # bitmap.SetSize(size)' | Set-Content '%CONDA_PREFIX%\Lib\site-packages\diffpy\pdfgui\gui\mainframe.py'"重新运行:
conda activate diffpy.pdfgui_env
pdfgui主界面就能正常启动显示了。
需要说明的是:
- 这个workaround只验证了「能正常启动GUI」,我还没有实际用它做结构精修之类的功能性操作,所以不确定注释掉这一行之后,工具栏图标显示会不会有细微的样式问题(比如尺寸没对齐)。
- 提交issue的人自己也说,他对整个代码库不够熟悉,无法保证改动不会在其他地方引发新问题,仅供参考。
希望这个博文能对你带来点帮助,感谢阅读!
评论