我以前在這個網站和其他平臺上讀過幾個主題,但是我的代碼仍然不能按需要工作。我似乎無法將所有拼圖拼湊在一起,需要有人來查看我的代碼。在設置模塊中使用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