Мне нужна поддержка моего небольшого программного обеспечения с Qwidget и QTreeWidgets. см. рисунок ниже.
Вот так выглядит мой Qwidget. Я хочу восстановить элементы Qtreewidget и виджет при закрытии окна и восстановить его с предыдущим выбором. как отмечено на рисунке ниже. Как вы видите в моих сценариях ниже, я использовал Qsettings, я пытался исправить это с помощью pickle, но он не работает.
Любое улучшение в кодировании приветствуется.
from PyQt5 import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import*
from PyQt5.QtGui import *
import sys
import pickle
iconroot = QFileInfo(__file__).absolutePath()
ORGANIZATION_NAME = 'Circularcolumn App'
ORGANIZATION_DOMAIN = 'Circular shape'
APPLICATION_NAME = 'QSettings program'
SETTINGS_TRAY = 'settings/tray'
class usedcircularshape(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Frequently used shape")
self.setWindowIcon(QIcon(iconroot+"/images/circularcolumnnorebar.png"))
#self.setStyleSheet("background-color:#f2f2f2")
self.addbutton = QPushButton("Add")
self.addbutton.clicked.connect(self.add)
self.deletebutton = QPushButton("Delete")
self.deletebutton.clicked.connect(self.delete)
self.okbutton = QPushButton("Ok")
self.okbutton.setCursor(Qt.PointingHandCursor)
#self.okbutton.clicked.connect(self.hidethiswindow)
self.okbutton.clicked.connect(self.savesetting)
self.cancelbutton = QPushButton("Cancel")
self.cancelbutton.setCursor(Qt.PointingHandCursor)
self.cancelbutton.clicked.connect(self.loadsetting)
#self.cancelbutton.clicked.connect(self.close)
self.addimage()
self.qlabeltodefinesection()
self.treewidget()
self.sectionnamecircular = QLabel('Section name: ')
self.sectionnamecircularindata = QLineEdit('Define en name to section')
self.sectionnamecircularindata.setObjectName("sectionnamecircularindata")
self.sectionnamecircular.setBuddy(self.sectionnamecircularindata)
self.sectionnamecircular.setFocus()
self.grid_sectionname = QHBoxLayout()
self.grid_sectionname.addWidget(self.sectionnamecircular)
self.grid_sectionname.addWidget(self.sectionnamecircularindata)
self.boxlayout = QGridLayout()
self.boxlayout.addLayout(self.grid_sectionname,0,0,1,2)
self.boxlayout.addWidget(self.treewidget,1,0,5,2)
self.boxlayout.addWidget(self.addbutton,2,2)
self.boxlayout.addWidget(self.deletebutton,3,2)
self.boxlayout.addWidget(self.imagelabel,6,0)
self.boxlayout.addLayout(self.qlabelhboxgrid ,6,1)
self.boxlayout.addWidget(self.okbutton,8,1)
self.boxlayout.addWidget(self.cancelbutton,8,2)
self.setLayout(self.boxlayout)
try:
self.loadsetting()
except ( ValueError, TypeError):
pass
def treewidget(self):
self.treewidget = QTreeWidget(self)
self.treewidget.setColumnCount(1)
self.treewidget.setColumnWidth(1,20)
self.treewidget.setHeaderItem(QTreeWidgetItem(['Standard Section Library']))
#self.treewidget.addTopLevelItem(QTreeWidgetItem(['Standard Sectiontype']))
self.treewidget.setRootIsDecorated(True)
self.firstparentitem = QTreeWidgetItem(self.treewidget)
self.firstparentitem.setText(0,'Circular shapes')
self.firstparentitem.setIcon(0,QIcon(iconroot+"/images/circularcolumnnorebar.png"))
standardsectionlist = ["D100","D150","D200","D250","D300","D350","D400","D450","D500","D550","D600","D650"
,"D700","D750","D800","D850","D900","D950","D1000"]
for i in standardsectionlist:
self.firstparentitem.addChild(QTreeWidgetItem(["%s"%i]))
self.secondparentitem = QTreeWidgetItem(self.treewidget)
self.secondparentitem.setText(0,'Customized')
self.secondparentitem.setIcon(0,QIcon(iconroot+"/images/circularcolumnnorebar.png"))
self.secondchilditem = QTreeWidgetItem(["D235"])
self.secondparentitem.insertChild(0,self.secondchilditem)
self.secondchilditem.setChildIndicatorPolicy(QTreeWidgetItem.DontShowIndicator)
self.treewidget.move(15,15)
self.treewidget.setGeometry(15,15,200,600)
self.treewidget.setAlternatingRowColors(True)
self.treewidget.expandItem ( self.firstparentitem )
self.show()
print(self.treewidget.headerItem().text(0))
print(self.treewidget.columnCount())
print(self.treewidget.currentColumn())
print(self.treewidget.indexFromItem(self.firstparentitem).row())
print(self.firstparentitem.childCount())
print(self.firstparentitem.child(1).text(0))
print(self.firstparentitem.text(0))
print(self.treewidget.headerItem().text(0))
print(self.treewidget.topLevelItem(0).text(0))
print(self.firstparentitem.isSelected())
print(self.treewidget.selectedItems())
print(self.secondchilditem.text(1))
branchstyle = '''QTreeWidget {border:none;}
QTreeView::branch:has-siblings:!adjoins-item {
border-image: url(images/vline.png) 0;}
QTreeView::branch:has-siblings:adjoins-item {
border-image: url(images/branch-more.png) 0;}
QTreeView::branch:!has-children:!has-siblings:adjoins-item {
border-image: url(images/branch-end.png) 0;}
QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
border-image: none;
image: url(images/branch-closed.png);}
QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
border-image: none;
image: url(images/branch-open.png);}'''
self.treewidget.setStyleSheet(branchstyle)
self.treewidget.itemClicked.connect(self.currentitem)
self.treewidget.currentItemChanged.connect(self.current_item_changed)
#@QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem, QtWidgets.QTreeWidgetItem)
def current_item_changed(self, current, previous):
#print('\ncurrent: {}, \nprevious: {}'.format(current, previous))
print(current.text(0),previous)
def add(self):
text, ok = QInputDialog.getText(self, "Add custom section", "Enter section geometry f.ex as D325 or just 325 in mm: ")
if ok:
self.secondchilditem = QTreeWidgetItem(["%s"% text])
self.secondparentitem.insertChild(0,self.secondchilditem)
self.treewidget.expandItem ( self.secondparentitem )
self.gettext = text
print(self.secondparentitem.child(0), self.gettext)
def delete(self):
self.secondparentitem.takeChild(0)
def currentitem(self):
print(self.treewidget.currentItem().text(0),self.treewidget.selectedItems())
self.itemtext = self.treewidget.currentItem().text(0)
if self.itemtext == self.firstparentitem.text(0) or self.itemtext == self.secondparentitem.text(0):
return None
elif self.itemtext == self.treewidget.topLevelItem(0).text(0):
return None
elif self.itemtext == None:
return None
else:
self.select_circular_section = int(self.itemtext.translate({ord('D'):None}))
print(self.itemtext, self.treewidget.selectedItems, self.select_circular_section)
area = str(format(3.1416/4*(self.select_circular_section)**2,'0.2E'))
inerti = str(format(3.1416/64*pow(self.select_circular_section,4),'0.2E'))
self.qlabelcirculardiameterselected = QLabel('')
qlabelcircularareaselected = QLabel('')
qlabelcircularinertimomentselected = QLabel("")
emptylabel1 = QLabel(' ')
self.qlabelcirculardiameterselected.setText('%s mm '% self.select_circular_section)
qlabelcircularareaselected.setText('{} mm2 ' .format(area))
qlabelcircularinertimomentselected.setText("%s mm4 " %(inerti))
qlabelhboxgridselected = QGridLayout()
qlabelhboxgridselected.addWidget(emptylabel1,0,0)
qlabelhboxgridselected.addWidget(self.qlabelcirculardiameterselected,1,0)
qlabelhboxgridselected.addWidget(qlabelcircularareaselected,2,0)
qlabelhboxgridselected.addWidget(qlabelcircularinertimomentselected,3,0)
qlabelhboxgridselected.addWidget(emptylabel1,4,0,5,0)
return print(self.itemtext, self.treewidget.selectedItems, self.select_circular_section), self.boxlayout.addLayout(qlabelhboxgridselected ,6,2),self.qlabelcirculardiameterselected
def addimage(self):
self.imagelabel = QLabel()
self.circularimage = QPixmap(iconroot+"/images/circularcolumnnorebard.png").scaled(230,230,Qt.KeepAspectRatio)
self.imagelabel.setPixmap(self.circularimage)
self.imagelabel.setGeometry(15,15,15,15)
def hidethiswindow(self):
if self.itemtext == self.firstparentitem.text(0) or self.itemtext == self.secondparentitem.text(0):
QMessageBox.about(self,'Error selection','Please, select a section not a text')
elif self.itemtext == self.treewidget.topLevelItem(0).text(0):
QMessageBox.about(self,'Error selection','Please, select a section not a text')
elif self.itemtext == None:
QMessageBox.about(self,'Error selection','Please, select a section not a text')
else:
self.savesetting()
self.hide()
def qlabeltodefinesection(self):
self.qlabelcirculardiameter = QLabel(' D = ')
self.qlabelcirculararea = QLabel(' A = ')
self.qlabelcircularinertimoment = QLabel(" I = ")
self.emptylabel = QLabel(' ')
self.qlabelhboxgrid = QGridLayout()
self.qlabelhboxgrid.addWidget(self.emptylabel,0,0)
self.qlabelhboxgrid.addWidget(self.qlabelcirculardiameter,1,0)
self.qlabelhboxgrid.addWidget(self.qlabelcirculararea,2,0)
self.qlabelhboxgrid.addWidget(self.qlabelcircularinertimoment,3,0)
self.qlabelhboxgrid.addWidget(self.emptylabel,4,0,5,0)
def savesetting(self):
settings = QSettings(ORGANIZATION_NAME,APPLICATION_NAME)
#settings = QSettings('config.ini',QSettings.IniFormat)
settings.beginGroup('D')
settings.setValue(SETTINGS_TRAY,self.geometry())
settings.setValue("LineEdit",self.sectionnamecircularindata.text())
settings.setValue("Selectitem",self.treewidget.currentItem())
settings.setValue("Label",self.qlabelcirculardiameterselected)
settings.endGroup()
print('Saved', )
#self.hide()
def loadsetting(self):
settings = QSettings(ORGANIZATION_NAME,APPLICATION_NAME)
#settings = QSettings('config.ini',QSettings.IniFormat)
settings.beginGroup('D')
myrect = settings.value(SETTINGS_TRAY)
restorelineEdit = settings.value("LineEdit",'')
restoreselectsection = settings.value("Selectitem",)
restoreqlabel = settings.value("Label",'')
self.setGeometry(myrect)
self.sectionnamecircularindata.setText(restorelineEdit)
self.treewidget.setCurrentItem(restoreselectsection)
settings.endGroup()
if __name__ == "__main__":
QCoreApplication.setApplicationName(ORGANIZATION_NAME)
QCoreApplication.setOrganizationDomain(ORGANIZATION_DOMAIN)
QCoreApplication.setApplicationName(APPLICATION_NAME)
app = QApplication(sys.argv)
subwindow=usedcircularshape()
subwindow.show()
app.exec()
Что делает код?
Это программное обеспечение для конкретных колонок, идея в том, что пользователь должен иметь возможность выбрать стандартный раздел, например D350, D означает диаметр, а 350 - диаметр круглой бетонной колонны в мм.
Пользователь имеет возможность добавлять собственные формы круглых столбцов. И когда пользователь щелкает и выбирает в Qtreewidget раздел, этот раздел должен оставаться глобальным и доступным для дальнейшего расчета, который ей не показан. Это виджет для определения геометрии в большом конкретном программном обеспечении.
Я бы ниже пояснил код.
Сначала я создаю Qdialog и создаю Qtreewidget, изображение для уточнения и Qlabel на основе выбора элемента.
В Qtreewidget я сначала создаю родительский элемент и называю его «Круглые формы»
self.firstparentitem = QTreeWidgetItem(self.treewidget)
self.firstparentitem.setText(0,'Circular shapes')
Затем у родительского элемента есть дочерние элементы, для их определения и добавления сначала создается список со стандартными разделами
standardsectionlist = ["D100","D150","D200","D250","D300","D350","D400","D450","D500","D550","D600","D650"
,"D700","D750","D800","D850","D900","D950","D1000"]
И выполнить условие для добавления детей в родительский элемент.
for i in standardsectionlist:
self.firstparentitem.addChild(QTreeWidgetItem(["%s"%i]))
позже я определяю второй родительский элемент, даю имя «Customized» и определяю список, затем добавляю элемент списка как дочерний элемент ко второму родительскому элементу.
Чтобы пользователь мог добавить и удалить дочерний элемент из второго родительского элемента, я создаю 2 кнопки
self.addbutton = QPushButton("Add")
self.deletebutton = QPushButton("Delete")
В Addbutton есть функция для добавления дочернего элемента во второй родительский элемент.
Кнопка Delete имеет функцию для удаления первого дочернего элемента из второго родительского элемента.
def currentitem(self):
функция currentitem имеет функцию, когда пользователь щелкает и выбирает элемент в Qtreewidget, он берет текст currentitem и удаляет из него букву D и преобразует его в int, затем отображает его как D = Diameter,
A = Площадь ЭСТ…
def hidethiswindow(self)
Функция скрытия этого окна позволяет пользователю выбрать элемент или отменить виджет. В случае, если пользователь по ошибке выбрал элемент header, появится сообщение об ошибке и будет сказано выбрать дочерний элемент. Это не мощно!
Остальной код должен отображать и Qsettings. Надеюсь, что это объясняет код.