This commit is contained in:
Artem30801
2019-11-25 23:19:07 +03:00
parent f58f097321
commit 3dc665bd00
7 changed files with 271 additions and 51 deletions

View File

@@ -20,6 +20,7 @@ sys.path.insert(0, parent_dir)
logger = logging.getLogger(__name__)
import messaging_lib as messaging
import config
ConfigOption = collections.namedtuple("ConfigOption", ["section", "option", "value"])

View File

@@ -0,0 +1,16 @@
[SERVER]
port = integer(default=25000)
host = ip_addr(default=192.168.1.101) #string?
buffer_size = integer(default=1024)
[BROADCAST]
use = boolean(default=True)
port = integer(default=8181)
[NTP]
use = boolean(default=False)
host = string(default=ntp1.stratum2.ru)
port = integer(default=123)
[PRIVATE]
id = string(default=/hostname, max=63)

View File

@@ -0,0 +1,19 @@
# DO NOT EDIT this file in production
# Use non-default config files for configuration purposes
[SERVER]
port = 25000
host = 192.168.1.101
buffer_size = 1024
[BROADCAST]
use = True
port = 8181
[NTP]
use = False
host = ntp1.stratum2.ru
port = 123
[PRIVATE]
id = /hostname

View File

@@ -10,25 +10,25 @@
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(268, 247)
Dialog.setModal(False)
self.gridLayout = QtWidgets.QGridLayout(Dialog)
class Ui_config_dialog(object):
def setupUi(self, config_dialog):
config_dialog.setObjectName("config_dialog")
config_dialog.resize(317, 247)
config_dialog.setModal(False)
self.gridLayout = QtWidgets.QGridLayout(config_dialog)
self.gridLayout.setObjectName("gridLayout")
self.treeView = QtWidgets.QTreeView(Dialog)
self.treeView.setObjectName("treeView")
self.gridLayout.addWidget(self.treeView, 0, 0, 1, 1)
self.config_view = QtWidgets.QTreeView(config_dialog)
self.config_view.setObjectName("config_view")
self.gridLayout.addWidget(self.config_view, 0, 0, 1, 1)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setObjectName("pushButton")
self.gridLayout_2.addWidget(self.pushButton, 0, 0, 1, 1)
self.checkBox = QtWidgets.QCheckBox(Dialog)
self.delete_button = QtWidgets.QPushButton(config_dialog)
self.delete_button.setObjectName("delete_button")
self.gridLayout_2.addWidget(self.delete_button, 0, 0, 1, 1)
self.checkBox = QtWidgets.QCheckBox(config_dialog)
self.checkBox.setObjectName("checkBox")
self.gridLayout_2.addWidget(self.checkBox, 1, 0, 1, 1)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox = QtWidgets.QDialogButtonBox(config_dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Save)
self.buttonBox.setCenterButtons(False)
@@ -36,25 +36,25 @@ class Ui_Dialog(object):
self.gridLayout_2.addWidget(self.buttonBox, 1, 1, 1, 1)
self.gridLayout.addLayout(self.gridLayout_2, 1, 0, 1, 1)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.retranslateUi(config_dialog)
self.buttonBox.accepted.connect(config_dialog.accept)
self.buttonBox.rejected.connect(config_dialog.reject)
QtCore.QMetaObject.connectSlotsByName(config_dialog)
def retranslateUi(self, Dialog):
def retranslateUi(self, config_dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Config Editor"))
self.pushButton.setText(_translate("Dialog", "Delete"))
self.pushButton.setShortcut(_translate("Dialog", "Del"))
self.checkBox.setText(_translate("Dialog", "Restart"))
self.checkBox.setShortcut(_translate("Dialog", "R"))
config_dialog.setWindowTitle(_translate("config_dialog", "Config Editor"))
self.delete_button.setText(_translate("config_dialog", "Delete"))
self.delete_button.setShortcut(_translate("config_dialog", "Del"))
self.checkBox.setText(_translate("config_dialog", "Restart"))
self.checkBox.setShortcut(_translate("config_dialog", "R"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
config_dialog = QtWidgets.QDialog()
ui = Ui_config_dialog()
ui.setupUi(config_dialog)
config_dialog.show()
sys.exit(app.exec_())

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<class>config_dialog</class>
<widget class="QDialog" name="config_dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>268</width>
<width>317</width>
<height>247</height>
</rect>
</property>
@@ -18,12 +18,12 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTreeView" name="treeView"/>
<widget class="QTreeView" name="config_view"/>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="delete_button">
<property name="text">
<string>Delete</string>
</property>
@@ -64,7 +64,7 @@
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<receiver>config_dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@@ -80,7 +80,7 @@
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<receiver>config_dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">

View File

@@ -4,13 +4,17 @@ from PyQt5.QtCore import Qt as Qt
class ConfigModelItem:
def __init__(self, data: list, parent=None):
def __init__(self, label, value="", parent=None):
self.parentItem = parent
self.itemData = data
self.itemData = [label, value]
self.childItems = []
if self.parentItem is not None:
self.parentItem.appendChild(self)
def appendChild(self, item):
self.childItems.append(item)
item.parentItem = self
def child(self, row):
return self.childItems[row]
@@ -19,7 +23,7 @@ class ConfigModelItem:
return len(self.childItems)
def columnCount(self):
return len(self.itemData)
return 2
def data(self, column):
try:
@@ -27,32 +31,51 @@ class ConfigModelItem:
except IndexError:
return None
def set_data(self, data, column):
try:
self.itemData[column] = data
except IndexError:
return False
return True
def parent(self):
return self.parentItem
def row(self):
if self.parentItem:
if self.parentItem is not None:
return self.parentItem.childItems.index(self)
return 0
def removeChild(self, position):
if position < 0 or position > len(self.childItems):
return False
child = self.childItems.pop(position)
child.parentItem = None
return True
class ConfigModel(QtCore.QAbstractItemModel):
def __init__(self, data, parent=None):
super(ConfigModel, self).__init__(parent)
self.rootItem = ConfigModelItem(("Option", "Value"))
#self.setupModelData(data.split('\n'), self.rootItem)
self.rootItem.appendChild(ConfigModelItem(("1314", "345")))
self.rootItem = ConfigModelItem("Option", "Value")
self.setup(data)
#i = ConfigModelItem("1314", "")
#self.rootItem.appendChild(i)
#i.appendChild(ConfigModelItem("36hhj", "34566"))
#i.appendChild(ConfigModelItem("36hhj", "34566"))
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
return self.rootItem.data(section)
def columnCount(self, parent):
if parent.isValid():
return parent.internalPointer().columnCount()
else:
return self.rootItem.columnCount()
return 2
def rowCount(self, parent):
if parent.column() > 0:
@@ -93,6 +116,99 @@ class ConfigModel(QtCore.QAbstractItemModel):
return self.createIndex(parentItem.row(), 0, parentItem)
def data(self, index, role):
if not index.isValid():
return None
item = index.internalPointer()
if role == Qt.DisplayRole or role == Qt.EditRole:
return item.data(index.column())
return None
@QtCore.pyqtSlot()
def setData(self, index, value, role=Qt.EditRole):
if not index.isValid():
return False
item = index.internalPointer()
if role == Qt.EditRole:
item.set_data(value, index.column())
self.dataChanged.emit(index, index, (role,))
return True
def flags(self, index):
if not index.isValid():
return Qt.NoItemFlags
childItem = index.internalPointer()
parentItem = childItem.parent()
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
if index.column() == 1 and parentItem != self.rootItem:
flags |= Qt.ItemIsEditable
return flags
@QtCore.pyqtSlot()
def removeRow(self, index):
parent = index.parent()
self.beginRemoveRows(parent, index.row(), index.row())
if not parent.isValid():
parentNode = self.rootItem
else:
parentNode = parent.internalPointer()
parentNode.removeChild(index.row())
self.endRemoveRows()
return True
def setup(self, d: dict):
for section, options in d.items():
section_item = ConfigModelItem(section, parent=self.rootItem)
for option, value in options.items():
section_item.appendChild(ConfigModelItem(option, value))
def to_dict(self):
d = {}
for section in self.rootItem.childItems:
section_d = {}
section_name, _ = section.itemData
for item in section.childItems:
option, value = item.itemData
section_d[option] = value
d[section_name] = section_d
return d
class ConfigDialog(config_editor.Ui_config_dialog):
def __init__(self, data):
super(ConfigDialog, self).__init__()
self.model = ConfigModel(data)
def setupUi(self, config_dialog):
super(ConfigDialog, self).setupUi(config_dialog)
self.config_view.setModel(self.model)
self.config_view.expandAll()
self.delete_button.pressed.connect(self.remove_selected)
def remove_selected(self):
index = self.config_view.selectedIndexes()[0]
self.model.removeRow(index)
#print(self.model.to_dict())
if __name__ == '__main__':
import sys
@@ -102,12 +218,16 @@ if __name__ == '__main__':
sys.excepthook = except_hook
m = ConfigModel([12313, 123])
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = config_editor.Ui_Dialog()
data = {"section 1": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, "...": ""},
"section 2": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, "...": ""}}
ui = ConfigDialog(data)
ui.setupUi(Dialog)
ui.treeView.setModel(m)
Dialog.show()
sys.exit(app.exec_())
print(app.exec_())
sys.exit()

64
config.py Normal file
View File

@@ -0,0 +1,64 @@
import collections
import os
from configobj import ConfigObj
from validate import Validator
ConfigOption = collections.namedtuple("ConfigOption", ["section", "option", "value"])
class ConfigManager:
def __init__(self):
self.configs = {}
@staticmethod
def _get_default_path(path):
old_path, filename = os.path.split(path)
filename = os.path.splitext(filename)[0]
newfilename = "default_{}.ini".format(filename)
print(os.path.join(old_path, newfilename))
return os.path.join(old_path, newfilename)
def load_config(self, path): # todo maybe automatic config path
vdt = Validator()
default_config = ConfigObj(
infile=self._get_default_path(path), configspec="Drone/configs/configspec_client.ini")
default_config.validate(vdt)
print(default_config)
default_config.walk(self.transform)
print(default_config.dict())
#default_config = configparser.ConfigParser(co)
#default_config.read(default_path)
def create_empty_config(self, path):
with open(path, 'w') as f:
f.write("# Write here any configurations to replace default values \n\n")
@staticmethod
def getvalue(section, key):
try:
return section.as_int(key)
except ValueError:
pass
try:
return section.as_float(key)
except ValueError:
pass
try:
return section.as_bool(key)
except ValueError:
pass
return section.get(key)
@classmethod
def transform(cls, section, key):
value = cls.getvalue(section, key)
print(value)
section[key] = value
if __name__ == '__main__':
cfg = ConfigManager()
#open('Drone/default_clinet_config.ini')
cfg.load_config('Drone/configs/clinet_config.ini')