我以前在这个网站和其他平台上读过几个主题,但是我的代码仍然不能按需要工作。我似乎无法将所有拼图拼凑在一起,需要有人来查看我的代码。在设置模块中使用python 2.7.6/PyQt4处理QVariants
我正在为程序QtiPlot编写一个插件。我使用Python 2.7.6和PyQt4。我使用QT Designer创建了插件GUI。我也是Python的新手。我使用这些“旧”资源,因为我的前任使用过它们。
我目前的任务是开发设置,即能够保存和恢复参数。 我在此网站上找到了一个用于此目的的模板:Python PyQt4 functions to save and restore UI widget values?
我想将参数保存到Ini文件中。 但是我有问题的QVariants。而不是我插入插件中的字符串,表达式“PyQt4.QtCore.QVariant对象在0x08667FB0”正在保存。我已经知道这是一个问题,因为QVariants没有被正确地转换回Python对象。因此,为了手动将QVariants转换回来,我在恢复功能中注释了QLineEdit-Objects的值赋值(注释掉的是以前的版本),我在短语“toString()”中添加了“toString()”这个词组。但是然后我的QLineEdit-Blocks插件是空的,这让我感到困惑。我在文档中读到,如果QVariant不包含预设类型之一(包括字符串),则返回空字符串。但是这种情况发生,虽然我之前输入了一个字符
这是否意味着字符串没有正确保存在第一位?否则它意味着什么,我错过了什么或者我做错了什么?
我也注意到没有值存储在Ini文件中,因此部分代码也是bug。但我不确定这是由于保存功能不起作用或因为Ini构造本身是错误的。
此外,我试图在配置文件的头部使用SIP模块来解决我的问题(它也被注释掉了,因为它到目前为止还不适用于我)。但是,尽管我把它放在代码的头部,但是我得到错误“API'QVariant'已经被设置为版本1”。我不明白为什么或从什么SIP指令被覆盖。有没有什么办法解决这一问题?
我的配置程序是这样的:
#import sip
#sip.setapi('QVariant', 2)
#sip.setapi('QString', 2)
import inspect
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
sys.path.append("C:\\Program Files (x86)\\QtiPlot\\app\\02 Python Packages")
import PyQt4_Save_Restore_UI_Widget_Values
class app_conf(QtGui.QWidget):
def __init__(self):
super(self.__class__, self).__init__()
self.version = 1.0
QtCore.QCoreApplication.setOrganizationName("Organization")
QtCore.QCoreApplication.setApplicationName("Application")
QtCore.QSettings.setPath(QSettings.IniFormat, QSettings.UserScope, "C:\\Program Files (x86)\\QtiPlot\\app\\02 Python Packages\\saved.ini")
self.settings = QtCore.QSettings("C:\\Program Files (x86)\\QtiPlot\\app\\02 Python Packages\\saved.ini", QSettings.IniFormat)
from PyQt4 import uic
self.ui = uic.loadUi(r"C:\Program Files (x86)/QtiPlot/app/03 UI Files/Config.ui")
PyQt4_Save_Restore_UI_Widget_Values.gui_restore_settings(self.ui, self.settings)
self.ui.closeEvent = self.closeEvent
self.ui.show()
def closeEvent(self, event):
PyQt4_Save_Restore_UI_Widget_Values.gui_save_settings(self.ui, self.settings)
window = app_conf()
我的设置模块(PyQt4_Save_Restore_UI_Widget_Values.py)看起来是这样的:
#===================================================================
# Module with functions to save & restore qt widget values
# Written by: Alan Lilly
# Website: http://panofish.net
#===================================================================
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import inspect
def gui_save_settings(ui, settings):
#for child in ui.children(): # works like getmembers, but because it traverses the hierarachy, you would have to call guisave recursively to traverse down the tree
for name, obj in inspect.getmembers(ui):
#if type(obj) is QComboBox: # this works similar to isinstance, but missed some field... not sure why?
if isinstance(obj, QComboBox):
name = obj.objectName() # get combobox name
index = obj.currentIndex() # get current index from combobox
text = obj.itemText(index) # get the text for current index
settings.setValue(name, text) # save combobox selection to registry
if isinstance(obj, QLineEdit):
name = obj.objectName()
value = obj.text()
settings.setValue(name, value) # save ui values, so they can be restored next time
if isinstance(obj, QCheckBox):
name = obj.objectName()
state = obj.checkState()
settings.setValue(name, state)
def gui_restore_settings(ui, settings):
for name, obj in inspect.getmembers(ui):
if isinstance(obj, QComboBox):
index = obj.currentIndex() # get current region from combobox
#text = obj.itemText(index) # get the text for new selected index
name = obj.objectName()
value = unicode(settings.value(name))
if value == "":
continue
index = obj.findText(value) # get the corresponding index for specified string in combobox
if index == -1: # add to list if not found
obj.insertItems(0,[value])
index = obj.findText(value)
obj.setCurrentIndex(index)
else:
obj.setCurrentIndex(index) # preselect a combobox value by index
if isinstance(obj, QLineEdit):
name = obj.objectName()
#value = unicode(settings.value(name)) # get stored value from registry
value = settings.value(name).toString()
obj.setText(value) # restore lineEditFile
if isinstance(obj, QCheckBox):
name = obj.objectName()
value = settings.value(name) # get stored value from registry
if value != None:
obj.setCheckState(value.toBool()) # restore checkbox
################################################################
if __name__ == "__main__":
# execute when run directly, but not when called as a module.
# therefore this section allows for testing this module!
#print "running directly, not as a module!"
sys.exit()
感谢您的回答!我看到我确实错过了一些东西。但是,当我尝试你的代码时,我得到以下错误:语法错误:语法无效,对于行:值,res = settings.value(key).toInt())#从注册表中获取存储值。为什么在这一行中分配了两个参数? – Maryn
@Maryn根据[documentation](http://pyqt.sourceforge.net/Docs/PyQt4/qvariant.html#toInt)'toInt'返回一个元组。编辑:有一个额外的括号,我修正了它。 – Frodon
再次感谢!现在我没有任何错误,但仍然没有值被保存。我使用INI文件并在那里存储了一些默认值。当我使用这个文件时,默认值被恢复。当我停止使用INI文件时,我再次只将“PyQt4.QtCore.QVariant对象存储在......”字符串中。我怀疑这可能是因为我没有正确设置我的应用程序?值可以存储到当前配置中的INI文件中吗?是否需要QtGUI.QApplication赋值(如“__main__”文件),因为我只从QtiPlot加载我的代码?还有什么可能是原因? – Maryn