Compare commits
	
		
			10 Commits
		
	
	
		
			59b55c1e0f
			...
			3937be3cb5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3937be3cb5 | ||
|   | 77da13fbaa | ||
|   | 8ca81184a9 | ||
|   | 7bcca92697 | ||
|   | 1e0950083e | ||
|   | 4efc72e071 | ||
|   | 9904d5b4e9 | ||
|   | 9cc5c6cd57 | ||
|   | c6a63b972e | ||
|   | b2de966586 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | .idea/ | ||||||
|  | __pycache__/ | ||||||
							
								
								
									
										42
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								README.md
									
									
									
									
									
								
							| @@ -1 +1,41 @@ | |||||||
| Это зачаток программы управления данными на основе описания структуры в json формате. | # Это зачаток программы управления данными на основе описания структуры в json формате. | ||||||
|  | Пишется на python3 в качестве графической библиотеки Qt5. | ||||||
|  |  | ||||||
|  | # Использование | ||||||
|  |  | ||||||
|  | По умолчанию используется шаблон и БД 'dm'. Для того чтобы изменить БД, создаем JSON шаблон согласно описания (см. примеры в db_template). | ||||||
|  |  | ||||||
|  | Затем данный файл нужно скопировать в '~/.dm/db_template/', следущим шагом меняем в конфиге 'dm.cfg' имя БД на имя вашего шаблона без расширения json, т.е. к примеру для работы с книжным каталогом (файл db_template/library.json) файл настроек будет выглядеть следующим оюбразом:  | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | [DataBase] | ||||||
|  | db_type = sqlite | ||||||
|  | db_hostname = localhost | ||||||
|  | db_name = library | ||||||
|  | db_user = dm | ||||||
|  | db_password = password | ||||||
|  |  | ||||||
|  | [Directory] | ||||||
|  | work_dir = /home/svkalinin/.dm | ||||||
|  | template_dir = /home/svkalinin/.dm/db_template | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | После этого можно запустить программу, при первом запуске будет создана БД согласно шаблона: | ||||||
|  |      | ||||||
|  | ``` | ||||||
|  | python3 gui.py | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | # СУБД | ||||||
|  |  | ||||||
|  | Пока реализована работа с Mysql (или Mariadb) и sqlite (по умолчанию). Для из менения типа БД в конфиге меняем 'dbtype': | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | dbtype = sqlite | ||||||
|  |  | ||||||
|  | или | ||||||
|  |  | ||||||
|  | dbtype = mysql | ||||||
|  | ``` | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								__pycache__/dm.cpython-36.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								__pycache__/dm.cpython-36.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -6,8 +6,8 @@ | |||||||
|       "fieldList": [ |       "fieldList": [ | ||||||
|         { |         { | ||||||
|           "fName": "id", |           "fName": "id", | ||||||
|           "fDescription": "Номер п.п.", |           "fDescription": "UID", | ||||||
|           "fType": "int(6)", |           "fType": "INTEGER", | ||||||
|           "index": "PRIMARY KEY", |           "index": "PRIMARY KEY", | ||||||
|           "autoIncrement": "yes", |           "autoIncrement": "yes", | ||||||
|           "relation": [] |           "relation": [] | ||||||
| @@ -60,8 +60,8 @@ | |||||||
|       "fieldList": [ |       "fieldList": [ | ||||||
|         { |         { | ||||||
|           "fName": "id", |           "fName": "id", | ||||||
|           "fDescription": "Номер п.п.", |           "fDescription": "UID", | ||||||
|           "fType": "int(6)", |           "fType": "INTEGER", | ||||||
|           "index": "PRIMARY KEY", |           "index": "PRIMARY KEY", | ||||||
|           "autoIncrement": "yes", |           "autoIncrement": "yes", | ||||||
|           "relation": [] |           "relation": [] | ||||||
| @@ -85,7 +85,7 @@ | |||||||
|         { |         { | ||||||
|           "fName": "users_id", |           "fName": "users_id", | ||||||
|           "fDescription": "Владелец", |           "fDescription": "Владелец", | ||||||
|           "fType": "int(6)", |           "fType": "INTEGER", | ||||||
|           "index": "no", |           "index": "no", | ||||||
|           "autoIncrement": "no", |           "autoIncrement": "no", | ||||||
|           "relation": ["users.id", "last_name, name, middle_name"] |           "relation": ["users.id", "last_name, name, middle_name"] | ||||||
| @@ -93,7 +93,7 @@ | |||||||
|         { |         { | ||||||
|           "fName": "parent_id", |           "fName": "parent_id", | ||||||
|           "fDescription": "Родительский документ", |           "fDescription": "Родительский документ", | ||||||
|           "fType": "int(6)", |           "fType": "INTEGER", | ||||||
|           "index": "no", |           "index": "no", | ||||||
|           "autoIncrement": "no", |           "autoIncrement": "no", | ||||||
|           "relation": ["docs.id", "doc_name"] |           "relation": ["docs.id", "doc_name"] | ||||||
| @@ -106,8 +106,8 @@ | |||||||
|       "fieldList": [ |       "fieldList": [ | ||||||
|         { |         { | ||||||
|           "fName": "id", |           "fName": "id", | ||||||
|           "fDescription": "Номер п.п.", |           "fDescription": "UID", | ||||||
|           "fType": "int(6)", |           "fType": "INTEGER", | ||||||
|           "index": "PRIMARY KEY", |           "index": "PRIMARY KEY", | ||||||
|           "autoIncrement": "yes", |           "autoIncrement": "yes", | ||||||
|           "relation": [] |           "relation": [] | ||||||
| @@ -122,7 +122,7 @@ | |||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "fName": "city", |           "fName": "city", | ||||||
|           "fDescription": "Населеннй пункт", |           "fDescription": "Населенный пункт", | ||||||
|           "fType": "varchar(200)", |           "fType": "varchar(200)", | ||||||
|           "index": "no", |           "index": "no", | ||||||
|           "autoIncrement": "no", |           "autoIncrement": "no", | ||||||
| @@ -147,54 +147,116 @@ | |||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "tableName": "test", |       "tableName": "items", | ||||||
|       "tableDescription": "Шляпа", |       "tableDescription": "Оборудование", | ||||||
|       "fieldList": [ |       "fieldList": [ | ||||||
|         { |         { | ||||||
|           "fName": "id", |           "fName": "id", | ||||||
|           "fDescription": "Номер п.п.", |           "fDescription": "UID", | ||||||
|           "fType": "int(11)", |           "fType": "INTEGER", | ||||||
|           "index": "PRIMARY KEY", |           "index": "PRIMARY KEY", | ||||||
|           "autoIncrement": "yes", |           "autoIncrement": "yes", | ||||||
|           "relation": [] |           "relation": [] | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "fName": "user", |           "fName": "item_name", | ||||||
|           "fDescription": "Юзер шляпы", |           "fDescription": "Наименование", | ||||||
|           "fType": "int(11)", |           "fType": "VARCHAR(100)", | ||||||
|           "index": "no", |           "index": "no", | ||||||
|           "autoIncrement": "no", |           "autoIncrement": "no", | ||||||
|           "relation": ["users.id", "last_name, name, middle_name"] |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "item_address", | ||||||
|  |           "fDescription": "Место расположения", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["address.id", "city, street, house"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "item_type", | ||||||
|  |           "fDescription": "Тип", | ||||||
|  |           "fType": "CHAR(20)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["itemtype.id", "type_name"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "inventory_number", | ||||||
|  |           "fDescription": "Инвентарный номер", | ||||||
|  |           "fType": "CHAR(10)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|         } |         } | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "tableName": "test2", |       "tableName": "itemtype", | ||||||
|       "tableDescription": "Шляпа2", |       "tableDescription": "Тип оборудования", | ||||||
|       "fieldList": [ |       "fieldList": [ | ||||||
|         { |         { | ||||||
|           "fName": "id", |           "fName": "id", | ||||||
|           "fDescription": "Номер п.п.", |           "fDescription": "UID", | ||||||
|           "fType": "int(11)", |           "fType": "INTEGER", | ||||||
|           "index": "PRIMARY KEY", |           "index": "PRIMARY KEY", | ||||||
|           "autoIncrement": "yes", |           "autoIncrement": "yes", | ||||||
|           "relation": [] |           "relation": [] | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "fName": "ins_date", |           "fName": "type_name", | ||||||
|           "fDescription": "Дата добавления", |           "fDescription": "Тип", | ||||||
|  |           "fType": "VARCHAR(100)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "tableName": "itemrelocation", | ||||||
|  |       "tableDescription": "Перемещения", | ||||||
|  |       "fieldList": [ | ||||||
|  |         { | ||||||
|  |           "fName": "id", | ||||||
|  |           "fDescription": "UID", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "PRIMARY KEY", | ||||||
|  |           "autoIncrement": "yes", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "item_id", | ||||||
|  |           "fDescription": "Оборудование", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["items.id", "item_name, inventory_number"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "source_place", | ||||||
|  |           "fDescription": "Откуда", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["address.id", "city, street, house"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "destination_place", | ||||||
|  |           "fDescription": "Куда", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["address.id", "city, street, house"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "create_datetime", | ||||||
|  |           "fDescription": "Дата перемещения", | ||||||
|           "fType": "DATETIME", |           "fType": "DATETIME", | ||||||
|           "index": "no", |           "index": "no", | ||||||
|           "autoIncrement": "no", |           "autoIncrement": "no", | ||||||
|           "relation": [] |           "relation": [] | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "fName": "user", |  | ||||||
|           "fDescription": "Юзер шляпы", |  | ||||||
|           "fType": "int(11)", |  | ||||||
|           "index": "no", |  | ||||||
|           "autoIncrement": "no", |  | ||||||
|           "relation": ["users.id", "last_name, name, middle_name"] |  | ||||||
|         } |         } | ||||||
|       ] |       ] | ||||||
|     } |     } | ||||||
							
								
								
									
										141
									
								
								db_template/library.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								db_template/library.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | |||||||
|  | { | ||||||
|  |   "tables": [ | ||||||
|  |     { | ||||||
|  |       "tableName": "publisher", | ||||||
|  |       "tableDescription": "Издательство", | ||||||
|  |       "fieldList": [ | ||||||
|  |         { | ||||||
|  |           "fName": "id", | ||||||
|  |           "fDescription": "Номер п.п.", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "PRIMARY KEY", | ||||||
|  |           "autoIncrement": "yes", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "publisher_name", | ||||||
|  |           "fDescription": "Наименование", | ||||||
|  |           "fType": "char(20)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "tableName": "authors", | ||||||
|  |       "tableDescription": "Авторы", | ||||||
|  |       "fieldList": [ | ||||||
|  |         { | ||||||
|  |           "fName": "id", | ||||||
|  |           "fDescription": "Номер п.п.", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "PRIMARY KEY", | ||||||
|  |           "autoIncrement": "yes", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "last_name", | ||||||
|  |           "fDescription": "Фамилия", | ||||||
|  |           "fType": "char(20)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "name", | ||||||
|  |           "fDescription": "Имя", | ||||||
|  |           "fType": "char(20)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "middle_name", | ||||||
|  |           "fDescription": "Отчество", | ||||||
|  |           "fType": "char(20)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "tableName": "books", | ||||||
|  |       "tableDescription": "Книги", | ||||||
|  |       "fieldList": [ | ||||||
|  |         { | ||||||
|  |           "fName": "id", | ||||||
|  |           "fDescription": "Номер п.п.", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "PRIMARY KEY", | ||||||
|  |           "autoIncrement": "yes", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "book_name", | ||||||
|  |           "fDescription": "Название", | ||||||
|  |           "fType": "varchar(100)", | ||||||
|  |           "index": "yes", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "description", | ||||||
|  |           "fDescription": "Описание", | ||||||
|  |           "fType": "varchar(200)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "authors_id", | ||||||
|  |           "fDescription": "Автор", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["authors.id", "last_name, name, middle_name"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "publisher_id", | ||||||
|  |           "fDescription": "Издательство", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["publisher.id", "publisher_name"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "category_id", | ||||||
|  |           "fDescription": "Жанр", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["category.id", "category_name"] | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "tableName": "category", | ||||||
|  |       "tableDescription": "Жанр", | ||||||
|  |       "fieldList": [ | ||||||
|  |         { | ||||||
|  |           "fName": "id", | ||||||
|  |           "fDescription": "Номер п.п.", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "PRIMARY KEY", | ||||||
|  |           "autoIncrement": "yes", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "category_name", | ||||||
|  |           "fDescription": "Название жанра", | ||||||
|  |           "fType": "varchar(100)", | ||||||
|  |           "index": "yes", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										72
									
								
								db_template/radio-catalog.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								db_template/radio-catalog.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | { | ||||||
|  |   "tables": [ | ||||||
|  |     { | ||||||
|  |       "tableName": "type", | ||||||
|  |       "tableDescription": "Тип элемента", | ||||||
|  |       "fieldList": [ | ||||||
|  |         { | ||||||
|  |           "fName": "id", | ||||||
|  |           "fDescription": "Номер п.п.", | ||||||
|  |           "fType": "INT(6)", | ||||||
|  |           "index": "PRIMARY KEY", | ||||||
|  |           "autoIncrement": "yes", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "name", | ||||||
|  |           "fDescription": "Тип элемента", | ||||||
|  |           "fType": "char(20)", | ||||||
|  |           "index": "yes", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |      }, | ||||||
|  |      { | ||||||
|  |       "tableName": "items", | ||||||
|  |       "tableDescription": "Элементы", | ||||||
|  |       "fieldList": [ | ||||||
|  |         { | ||||||
|  |           "fName": "id", | ||||||
|  |           "fDescription": "Номер п.п.", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "PRIMARY KEY", | ||||||
|  |           "autoIncrement": "yes", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "item_name", | ||||||
|  |           "fDescription": "Наименование", | ||||||
|  |           "fType": "varchar(100)", | ||||||
|  |           "index": "yes", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "description", | ||||||
|  |           "fDescription": "Описание", | ||||||
|  |           "fType": "varchar(200)", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "type_id", | ||||||
|  |           "fDescription": "Тип", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": ["type.id", "name"] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fName": "count", | ||||||
|  |           "fDescription": "Количество", | ||||||
|  |           "fType": "INTEGER", | ||||||
|  |           "index": "no", | ||||||
|  |           "autoIncrement": "no", | ||||||
|  |           "relation": [] | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										129
									
								
								dm.py
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								dm.py
									
									
									
									
									
								
							| @@ -3,8 +3,8 @@ import json, os, configparser, shutil, re | |||||||
| from datetime import datetime, date, time | from datetime import datetime, date, time | ||||||
|  |  | ||||||
| def firstInit(): | def firstInit(): | ||||||
|     # Инициализация переменныхб создание конфигруационного файла, копирование шаблонов |     # Инициализация переменных создание конфигруационного файла, копирование шаблонов | ||||||
|     global db_type, db_hostname, db_user, db_password, db_name, template_file, db_type |     global db_type, db_hostname, db_user, db_password, db_name, template_file, db_type, template_dir | ||||||
|     config = configparser.RawConfigParser() |     config = configparser.RawConfigParser() | ||||||
|     # проверяем тип ОС |     # проверяем тип ОС | ||||||
|     if os.name == "nt": |     if os.name == "nt": | ||||||
| @@ -19,7 +19,7 @@ def firstInit(): | |||||||
|     cfg_file = os.path.join(cfg_dir, 'dm.cfg') |     cfg_file = os.path.join(cfg_dir, 'dm.cfg') | ||||||
|     # создадим файл конфигурации |     # создадим файл конфигурации | ||||||
|     config.add_section('DataBase') |     config.add_section('DataBase') | ||||||
|     config.set('DataBase', 'db_type', 'mysql') |     config.set('DataBase', 'db_type', 'sqlite') | ||||||
|     config.set('DataBase', 'db_hostname', 'localhost') |     config.set('DataBase', 'db_hostname', 'localhost') | ||||||
|     config.set('DataBase', 'db_name', 'dm') |     config.set('DataBase', 'db_name', 'dm') | ||||||
|     config.set('DataBase', 'db_user', 'dm') |     config.set('DataBase', 'db_user', 'dm') | ||||||
| @@ -39,6 +39,7 @@ def firstInit(): | |||||||
|         config.read(cfg_file) |         config.read(cfg_file) | ||||||
|  |  | ||||||
|     work_dir = config.get('Directory', 'work_dir') |     work_dir = config.get('Directory', 'work_dir') | ||||||
|  |     global template_dir | ||||||
|     template_dir = config.get('Directory', 'template_dir') |     template_dir = config.get('Directory', 'template_dir') | ||||||
|     db_type = config.get('DataBase', 'db_type') |     db_type = config.get('DataBase', 'db_type') | ||||||
|     db_hostname =  config.get('DataBase', 'db_hostname') |     db_hostname =  config.get('DataBase', 'db_hostname') | ||||||
| @@ -59,11 +60,13 @@ def firstInit(): | |||||||
|     else: |     else: | ||||||
|         os.mkdir(template_dir) |         os.mkdir(template_dir) | ||||||
|     # копируем и читаем файл шаблон БД |     # копируем и читаем файл шаблон БД | ||||||
|     template_file = os.path.join(template_dir, 'tables.json') |     template = config.get('DataBase', 'db_name') + '.json' | ||||||
|  |  | ||||||
|  |     template_file = os.path.join(template_dir, template) | ||||||
|     if os.path.isfile(template_file): |     if os.path.isfile(template_file): | ||||||
|         print("Template file already exists") |         print("Template file already exists " + template_file) | ||||||
|     else: |     else: | ||||||
|         shutil.copy('tables.json', template_file) |         shutil.copy('db_template/dm.json', template_file) | ||||||
|  |  | ||||||
|  |  | ||||||
| def dbConnect(): | def dbConnect(): | ||||||
| @@ -167,17 +170,18 @@ def createTables(tbl_list): | |||||||
|         i = i + 1 |         i = i + 1 | ||||||
|         dbTablesDescriptionList.append(one_Table_descr) |         dbTablesDescriptionList.append(one_Table_descr) | ||||||
|         dbTablesStructList.append(one_Table_struct) |         dbTablesStructList.append(one_Table_struct) | ||||||
|         #print(qwery_create) |         print(qwery_create) | ||||||
|         c.execute(qwery_create) |         c.execute(qwery_create) | ||||||
|     return dbTablesNamesList |     return dbTablesNamesList | ||||||
|  |  | ||||||
| def initDBstructure(): | def initDBstructure(): | ||||||
|     global dbTablesDescriptionList, template_file, tblNamesList |     global dbTablesDescriptionList, template_file, tblNamesList | ||||||
|     table_list = open(template_file, "r", encoding="utf-8") |     table_list = open(template_file, "r", encoding="utf-8") | ||||||
|     data = json.load(table_list, encoding="utf-8") |     # data = json.load(table_list, encoding="utf-8") | ||||||
|     tbl_list = data["tables"] |     data = json.load(table_list) | ||||||
|     tblNamesList = createTables(tbl_list) |     #tbl_list = data["tables"] | ||||||
|  |     #tblNamesList = createTables(tbl_list) | ||||||
|  |     tblNamesList = createTables(data["tables"]) | ||||||
|     return tblNamesList |     return tblNamesList | ||||||
|  |  | ||||||
| # выборка данных из заданной таблицы | # выборка данных из заданной таблицы | ||||||
| @@ -186,6 +190,7 @@ def selectData(tbl): | |||||||
|     # если юольше 1 поля добавить CONCAT |     # если юольше 1 поля добавить CONCAT | ||||||
|     qwery = "SELECT " |     qwery = "SELECT " | ||||||
|     subqwery = "" |     subqwery = "" | ||||||
|  |     #print(dbTablesStructList) | ||||||
|     for item in dbTablesStructList: |     for item in dbTablesStructList: | ||||||
|         if item[0] == tbl: |         if item[0] == tbl: | ||||||
|             for field in item[1]: |             for field in item[1]: | ||||||
| @@ -204,20 +209,17 @@ def selectData(tbl): | |||||||
|                 else: |                 else: | ||||||
|                     subqwery = table1 |                     subqwery = table1 | ||||||
|                 # составляем подзапрос и подменяем им поле в запросе |                 # составляем подзапрос и подменяем им поле в запросе | ||||||
|  |                 print(subqwery) | ||||||
|  |  | ||||||
|                 if db_type == "mysql": |                 if db_type == "mysql": | ||||||
|                     field_replace = field_replace.replace(",", ",' ',") |                     field_replace = field_replace.replace(",", ",' ',") | ||||||
|                     #subqwery = "(SELECT CONCAT(" + field_replace + ") FROM " + subqwery + " WHERE " + table1 + "." + field1 + "=" + tbl + "." + field + ") AS " + field |                     subqwery = "(SELECT CONCAT('>', {}.{}, '<', {}) FROM {} WHERE  {}.{}={}.{}) AS {}"\ | ||||||
|                     # subqwery = "(SELECT CONCAT({}) FROM {} WHERE  {}.{}={}.{}) AS {}"\ |                         .format(tbl,field,field_replace,subqwery,table1,field1,tbl,field,field) | ||||||
|                     #     .format(field_replace,subqwery,table1,field1,tbl,field,field) |  | ||||||
|                     subqwery = "(SELECT CONCAT('>', {}, '<', {}) FROM {} WHERE  {}.{}={}.{}) AS {}"\ |  | ||||||
|                         .format(field,field_replace,subqwery,table1,field1,tbl,field,field) |  | ||||||
|                 elif db_type == "sqlite": |                 elif db_type == "sqlite": | ||||||
|                     field_replace = field_replace.replace(",", " || ' ' ||") |                     field_replace = field_replace.replace(",", " || ' ' ||") | ||||||
|                     #subqwery = "(SELECT (" + field_replace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tbl +"."+ field +") AS " + field |  | ||||||
|                     subqwery = "(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}" \ |                     subqwery = "(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}" \ | ||||||
|                         .format(field_replace, subqwery, table1, field1, tbl, field, field) |                         .format(field_replace, subqwery, table1, field1, tbl, field, field) | ||||||
|                 qwery = qwery.replace(field, subqwery) |                 qwery = qwery.replace(field, subqwery) | ||||||
|     #qwery = qwery.rstrip(',') + " FROM " + tbl + " LIMIT 10000" |  | ||||||
|     qwery = '{} FROM {} LIMIT 10000'.format(qwery.rstrip(','), tbl) |     qwery = '{} FROM {} LIMIT 10000'.format(qwery.rstrip(','), tbl) | ||||||
|     print(qwery) |     print(qwery) | ||||||
|     c.execute(qwery) |     c.execute(qwery) | ||||||
| @@ -226,8 +228,6 @@ def selectData(tbl): | |||||||
| # получаем на вход имя таблицы и возвращаем список заголовков полей | # получаем на вход имя таблицы и возвращаем список заголовков полей | ||||||
| def getTableStructure(tbl): | def getTableStructure(tbl): | ||||||
|     global dbTablesDescriptionList, dbTablesStructList |     global dbTablesDescriptionList, dbTablesStructList | ||||||
|     #print(dbTablesDescriptionList) |  | ||||||
|     #print(dbTablesStructList) |  | ||||||
|     for item in dbTablesDescriptionList: |     for item in dbTablesDescriptionList: | ||||||
|         if item[0] == tbl: |         if item[0] == tbl: | ||||||
|             return item[1] |             return item[1] | ||||||
| @@ -235,8 +235,6 @@ def getTableStructure(tbl): | |||||||
| # Получаем список названий полей и типов для заданной таблицы | # Получаем список названий полей и типов для заданной таблицы | ||||||
| def getFields(tbl): | def getFields(tbl): | ||||||
|     global dbTablesDescriptionList, dbTablesStructList |     global dbTablesDescriptionList, dbTablesStructList | ||||||
|     #print(dbTablesDescriptionList) |  | ||||||
|     #print(dbTablesStructList) |  | ||||||
|     for item in dbTablesStructList: |     for item in dbTablesStructList: | ||||||
|         if item[0] == tbl: |         if item[0] == tbl: | ||||||
|             #print(item[1]) |             #print(item[1]) | ||||||
| @@ -256,7 +254,7 @@ def fieldTypeConvert(ftype): | |||||||
|     # разбираем строку на тип и длину |     # разбираем строку на тип и длину | ||||||
|     ftype = str.lower(ftype) |     ftype = str.lower(ftype) | ||||||
|     line = re.search("(.+?)\(([0-9]+)\)", ftype) |     line = re.search("(.+?)\(([0-9]+)\)", ftype) | ||||||
|     if  line: |     if line: | ||||||
|         fType = line.groups()[0] |         fType = line.groups()[0] | ||||||
|         fLength = line.groups()[1] |         fLength = line.groups()[1] | ||||||
|         if fType == 'int' or fType == 'integer': |         if fType == 'int' or fType == 'integer': | ||||||
| @@ -265,26 +263,20 @@ def fieldTypeConvert(ftype): | |||||||
|             fType = 'character' |             fType = 'character' | ||||||
|     else: |     else: | ||||||
|         fType = ftype |         fType = ftype | ||||||
|  |     #print(fType) | ||||||
|     return fType |     return fType | ||||||
|  |  | ||||||
| def getFieldType(tbl, field): | def getFieldType(tbl, field): | ||||||
|     global dbTablesDescriptionList, dbTablesStructList |     global dbTablesDescriptionList, dbTablesStructList | ||||||
|     #print(dbTablesDescriptionList) |  | ||||||
|     #print(dbTablesStructList) |  | ||||||
|     for item in dbTablesStructList: |     for item in dbTablesStructList: | ||||||
|         if item[0] == tbl: |         if item[0] == tbl: | ||||||
|             for i in item[1]: |             for i in item[1]: | ||||||
|                 if i[0] == field: |                 if i[0] == field: | ||||||
|                     fType = i[1] |                     fType = i[1] | ||||||
|                     return fType |                     return fType | ||||||
|             #print(item[1]) |  | ||||||
|             #return item[1] |  | ||||||
|  |  | ||||||
| def getRelationsForField(tblSearch, fieldName): | def getRelationsForField(tblSearch, fieldName): | ||||||
|     global dbTablesStructList, c, db_type |     global dbTablesStructList, c, db_type | ||||||
|     #print("Ищем связи для:" +tblSearch +','+ fieldName) |  | ||||||
|     #print(dbTablesStructList) |  | ||||||
|     #searchField = tblSearch + '.' + fieldName |  | ||||||
|     dataList = [] |     dataList = [] | ||||||
|     for item in dbTablesStructList: |     for item in dbTablesStructList: | ||||||
|         #print(item) |         #print(item) | ||||||
| @@ -295,16 +287,10 @@ def getRelationsForField(tblSearch, fieldName): | |||||||
|             if tblName == tblSearch: |             if tblName == tblSearch: | ||||||
|                 # выдергиваем из списка название и поле нужной нам таблицы |                 # выдергиваем из списка название и поле нужной нам таблицы | ||||||
|                 if rel[0] == fieldName: |                 if rel[0] == fieldName: | ||||||
|                     #print('table -  ' + tblName) |  | ||||||
|                     ##print('field - ' + fieldName) |  | ||||||
|                     #print('relation - ' + str(rel)) |  | ||||||
|                     l = rel[1][0].split('.') |                     l = rel[1][0].split('.') | ||||||
|                     relTable = l[0] |                     relTable = l[0] | ||||||
|                     relField = l[1] |                     relField = l[1] | ||||||
|                     replaceFields = rel[1][1] |                     replaceFields = rel[1][1] | ||||||
|                    # print('reltable -  ' + relTable) |  | ||||||
|                     #print('relfield - ' + relField) |  | ||||||
|                     #print('relrelation - ' + replaceFields) |  | ||||||
|                     return [relTable, relField, replaceFields] |                     return [relTable, relField, replaceFields] | ||||||
|     return "q" |     return "q" | ||||||
|  |  | ||||||
| @@ -314,10 +300,6 @@ def insertDataIntoBD(dataList): | |||||||
|     global c, conn |     global c, conn | ||||||
|     dbConnect() |     dbConnect() | ||||||
|     tableName = dataList[0] |     tableName = dataList[0] | ||||||
|     #print(dataList) |  | ||||||
|     #datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") |  | ||||||
|  |  | ||||||
|     #qwery = 'INSERT INTO ' + tableName + ' (' |  | ||||||
|     qwery = 'INSERT INTO {} ('.format(tableName) |     qwery = 'INSERT INTO {} ('.format(tableName) | ||||||
|     qweryData = '' |     qweryData = '' | ||||||
|     qweryField = '' |     qweryField = '' | ||||||
| @@ -326,30 +308,23 @@ def insertDataIntoBD(dataList): | |||||||
|         #print(fType) |         #print(fType) | ||||||
|         # проверяем если значение поля пустое то в запрос оно не включается |         # проверяем если значение поля пустое то в запрос оно не включается | ||||||
|         if item[1] != '': |         if item[1] != '': | ||||||
|             #qweryField = qweryField + item[0] + ',' |  | ||||||
|             qweryField = '{}{},'.format(qweryField,item[0]) |             qweryField = '{}{},'.format(qweryField,item[0]) | ||||||
|             if fType == 'integer': |             if fType == 'integer': | ||||||
|                 #qweryData = qweryData + '' + item[1] + ',' |  | ||||||
|                 qweryData = '{}{},'.format(qweryData,item[1]) |                 qweryData = '{}{},'.format(qweryData,item[1]) | ||||||
|             elif fType == 'datetime': |             elif fType == 'datetime': | ||||||
|                 # преобразуем дату всяко разно |                 # преобразуем дату всяко разно | ||||||
|                 dt = datetime.strptime(item[1], "%d.%m.%y %H:%M") |                 dt = datetime.strptime(item[1], "%d.%m.%y %H:%M") | ||||||
|                 item[1] = str(dt) |                 item[1] = str(dt) | ||||||
|                 #qweryData = qweryData + '\'' + item[1] + '\',' |  | ||||||
|                 qweryData = "{}'{}',".format(qweryData,item[1]) |                 qweryData = "{}'{}',".format(qweryData,item[1]) | ||||||
|             elif fType == 'date': |             elif fType == 'date': | ||||||
|                 d = item[1].split('.') |                 d = item[1].split('.') | ||||||
|                 #myDate = d[2] + '-' + d[1] + '-' + d[1] |  | ||||||
|                 myDate = '{}-{}-{}'.format(d[2], d[1], d[1]) |                 myDate = '{}-{}-{}'.format(d[2], d[1], d[1]) | ||||||
|                 item[1] = str(myDate) |                 item[1] = str(myDate) | ||||||
|                 #qweryData = qweryData + '\'' + item[1] + '\',' |  | ||||||
|                 qweryData = "{}'{}',".format(qweryData, item[1]) |                 qweryData = "{}'{}',".format(qweryData, item[1]) | ||||||
|             else: |             else: | ||||||
|                 #qweryData = qweryData + '\'' + item[1] + '\',' |  | ||||||
|                 qweryData = "{}'{}',".format(qweryData, item[1]) |                 qweryData = "{}'{}',".format(qweryData, item[1]) | ||||||
|  |  | ||||||
|  |  | ||||||
|     #qwery = qwery + qweryField.rstrip(',') + ')' + ' VALUES (' + qweryData.rstrip(',') + ');' |  | ||||||
|     qwery = '{}{}) VALUES ({});'.format(qwery, qweryField.rstrip(','), qweryData.rstrip(',')) |     qwery = '{}{}) VALUES ({});'.format(qwery, qweryField.rstrip(','), qweryData.rstrip(',')) | ||||||
|  |  | ||||||
|     print(qwery) |     print(qwery) | ||||||
| @@ -385,20 +360,16 @@ def selectDataFromDB(tblName, fieldName, fieldValue): | |||||||
|                 # составляем подзапрос и подменяем им поле в запросе |                 # составляем подзапрос и подменяем им поле в запросе | ||||||
|                 if db_type == "mysql": |                 if db_type == "mysql": | ||||||
|                     fieldReplace = fieldReplace.replace(",", ",' ',") |                     fieldReplace = fieldReplace.replace(",", ",' ',") | ||||||
|                     #subqwery = "(SELECT CONCAT(" + fieldReplace + ") FROM " + subqwery + " WHERE " + table1 + "." + field1 + "=" + tblName + "." + field + ") AS " + field |  | ||||||
|                     subqwery = '(SELECT CONCAT({}) FROM {} WHERE {}.{}={}.{}) AS {}'\ |                     subqwery = '(SELECT CONCAT({}) FROM {} WHERE {}.{}={}.{}) AS {}'\ | ||||||
|                         .format(fieldReplace, subqwery, table1, field1, tblName, field, field) |                         .format(fieldReplace, subqwery, table1, field1, tblName, field, field) | ||||||
|                 elif db_type == "sqlite": |                 elif db_type == "sqlite": | ||||||
|                     fieldReplace = fieldReplace.replace(",", " || ' ' ||") |                     fieldReplace = fieldReplace.replace(",", " || ' ' ||") | ||||||
|                     #subqwery = "(SELECT (" + fieldReplace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tblName +"."+ field +") AS " + field |  | ||||||
|                     subqwery = '(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}'\ |                     subqwery = '(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}'\ | ||||||
|                         .format(fieldReplace, subqwery, table1, field1, tblName, field, field) |                         .format(fieldReplace, subqwery, table1, field1, tblName, field, field) | ||||||
|                 #print("---" + subqwery) |  | ||||||
|                 qwery = qwery.replace(field, subqwery) |                 qwery = qwery.replace(field, subqwery) | ||||||
|     #qwery = qwery.rstrip(',') + " FROM " + tblName + " LIMIT 10000" |  | ||||||
|     #qwery = qwery.rstrip(',') + " FROM " + tblName + " WHERE " + fieldName + '=' + fieldValue |  | ||||||
|     qwery = '{} FROM {} WHERE {}={}'.format(qwery.rstrip(','), tblName, fieldName, fieldValue) |     qwery = '{} FROM {} WHERE {}={}'.format(qwery.rstrip(','), tblName, fieldName, fieldValue) | ||||||
|  |  | ||||||
|  |  | ||||||
|     print(qwery) |     print(qwery) | ||||||
|     c.execute(qwery) |     c.execute(qwery) | ||||||
|     return c.fetchall() |     return c.fetchall() | ||||||
| @@ -435,11 +406,11 @@ def getTablesDescriptionOfName(tblName): | |||||||
| def deleteRecordsFromDB(tableName, valueList): | def deleteRecordsFromDB(tableName, valueList): | ||||||
|     global c, db_type, conn |     global c, db_type, conn | ||||||
|     qwery = 'DELETE FROM {} WHERE '.format(tableName) |     qwery = 'DELETE FROM {} WHERE '.format(tableName) | ||||||
|     #print(qwery) |     #print(valueList) | ||||||
|     subQwery='' |     subQwery='' | ||||||
|     i = 0 |     i = 0 | ||||||
|     for item in getFields(tableName): |     for item in getFields(tableName): | ||||||
|         print(item[0], item[1]) |         #print(item[0], item[1]) | ||||||
|         if item[1] == 'integer': |         if item[1] == 'integer': | ||||||
|             #subQwery = subQwery + item[0] + '=' + valueList[i] + ' AND ' |             #subQwery = subQwery + item[0] + '=' + valueList[i] + ' AND ' | ||||||
|             subQwery = '{}{}={} AND '.format(subQwery, item[0], valueList[i]) |             subQwery = '{}{}={} AND '.format(subQwery, item[0], valueList[i]) | ||||||
| @@ -449,11 +420,61 @@ def deleteRecordsFromDB(tableName, valueList): | |||||||
|         i += 1 |         i += 1 | ||||||
|     qwery += subQwery |     qwery += subQwery | ||||||
|     qwery = qwery.rstrip('AND ').replace("='None'", " IS NULL") |     qwery = qwery.rstrip('AND ').replace("='None'", " IS NULL") | ||||||
|  |     qwery = qwery.rstrip('AND ').replace("=None", " IS NULL") | ||||||
|  |     qwery = qwery.rstrip('AND ').replace("=NULL", " IS NULL") | ||||||
|     print(qwery) |     print(qwery) | ||||||
|     c.execute(qwery) |     c.execute(qwery) | ||||||
|     conn.commit() |     conn.commit() | ||||||
|     return |     return | ||||||
|  |  | ||||||
|  | # Редактирование записи в БД | ||||||
|  | def editDataIntoBD(dataList): | ||||||
|  |     global c, conn | ||||||
|  |     dbConnect() | ||||||
|  |     tableName = dataList[0] | ||||||
|  |     qwery = 'UPDATE {} SET '.format(tableName) | ||||||
|  |     #qweryData = '' | ||||||
|  |     qweryField = '' | ||||||
|  |     qweryWhere = '' | ||||||
|  |     for item in dataList[1]: | ||||||
|  |         fType = getFieldType(tableName, item[0]) | ||||||
|  |         # проверяем если значение поля пустое то в запрос оно не включается | ||||||
|  |         if item[1] != '': | ||||||
|  |             qweryField = '{}{}='.format(qweryField,item[0]) | ||||||
|  |  | ||||||
|  |             if fType == 'integer': | ||||||
|  |                 qweryField = '{}{},'.format(qweryField,item[1]) | ||||||
|  |             elif fType == 'datetime': | ||||||
|  |                 # преобразуем дату всяко разно | ||||||
|  |                 dt = datetime.strptime(item[1], "%d.%m.%y %H:%M") | ||||||
|  |                 item[1] = str(dt) | ||||||
|  |                 qweryField = "{}'{}',".format(qweryField,item[1]) | ||||||
|  |             elif fType == 'date': | ||||||
|  |                 d = item[1].split('.') | ||||||
|  |                 myDate = '{}-{}-{}'.format(d[2], d[1], d[1]) | ||||||
|  |                 item[1] = str(myDate) | ||||||
|  |                 qweryField = "{}'{}',".format(qweryField, item[1]) | ||||||
|  |             else: | ||||||
|  |                 qweryField = "{}'{}',".format(qweryField, item[1]) | ||||||
|  |     qwery = '{}{} WHERE {};'.format(qwery, qweryField.rstrip(','), qweryWhere) | ||||||
|  |  | ||||||
|  |     print(qwery) | ||||||
|  |     #c.execute(qwery) | ||||||
|  |     #conn.commit() | ||||||
|  |     #c.close() | ||||||
|  |     return | ||||||
|  | # Вывод структуры таблицы из базы данных | ||||||
|  | def getTableStructureFromDB(tableName): | ||||||
|  |     global c, db_type, conn | ||||||
|  |  | ||||||
|  |     if db_type == 'sqlite': | ||||||
|  |         qwery = 'PRAGMA table_info({})'.format(tableName) | ||||||
|  |         fieldsList = c.execute(qwery).fetchall() | ||||||
|  |         #for row in fieldsList: | ||||||
|  |         #    print(row) | ||||||
|  |     return(fieldsList) | ||||||
|  |  | ||||||
|  |  | ||||||
| #initDBstructure() | #initDBstructure() | ||||||
| firstInit() | firstInit() | ||||||
| dbConnect() | dbConnect() | ||||||
|   | |||||||
							
								
								
									
										154
									
								
								gui.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										154
									
								
								gui.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -5,6 +5,8 @@ import sys | |||||||
| from PyQt5.QtCore import * | from PyQt5.QtCore import * | ||||||
| from PyQt5.QtGui import * | from PyQt5.QtGui import * | ||||||
| from PyQt5.QtWidgets import * | from PyQt5.QtWidgets import * | ||||||
|  | #from PyQt5.QtWidgets import (QMainWindow, QTextEdit, QAction, QFileDialog, QApplication) | ||||||
|  | #from PyQt5.QtGui import QIcon | ||||||
|  |  | ||||||
| #import pymysql | #import pymysql | ||||||
| import dm | import dm | ||||||
| @@ -33,6 +35,7 @@ class MyTable(QTableWidget): | |||||||
|     def contextMenuEvent(self, event): |     def contextMenuEvent(self, event): | ||||||
|         Rmenu = QMenu(self) |         Rmenu = QMenu(self) | ||||||
|         addRecord = Rmenu.addAction("Добавить запись") |         addRecord = Rmenu.addAction("Добавить запись") | ||||||
|  |         editRecord = Rmenu.addAction("Редактировать запись") | ||||||
|         delRecord = Rmenu.addAction("Удалить запись") |         delRecord = Rmenu.addAction("Удалить запись") | ||||||
|         showRelations = Rmenu.addAction("Показать связанные документы") |         showRelations = Rmenu.addAction("Показать связанные документы") | ||||||
|         action = Rmenu.exec_(self.mapToGlobal(event.pos())) |         action = Rmenu.exec_(self.mapToGlobal(event.pos())) | ||||||
| @@ -46,6 +49,13 @@ class MyTable(QTableWidget): | |||||||
|         elif action == addRecord: |         elif action == addRecord: | ||||||
|             print("Добавить запись  ") |             print("Добавить запись  ") | ||||||
|             addNewRecord() |             addNewRecord() | ||||||
|  |         elif action == editRecord: | ||||||
|  |             row = self.rowAt(event.pos().y()) | ||||||
|  |             col = self.columnAt(event.pos().x()) | ||||||
|  |             #print("Удаляем row:%d, col:%d" % (row, col)) | ||||||
|  |             item = self.item(self.currentIndex().row(), self.currentIndex().column()) | ||||||
|  |             print("Редактировать запись  ") | ||||||
|  |             self.editCurrentRecord(row) | ||||||
|         elif action == showRelations: |         elif action == showRelations: | ||||||
|             item = self.item(self.currentIndex().row(), self.currentIndex().column()) |             item = self.item(self.currentIndex().row(), self.currentIndex().column()) | ||||||
|             showRelationsRecords(self.currentIndex().column(), item.text()) |             showRelationsRecords(self.currentIndex().column(), item.text()) | ||||||
| @@ -69,6 +79,24 @@ class MyTable(QTableWidget): | |||||||
|             #print(self.item(row, i).text()) |             #print(self.item(row, i).text()) | ||||||
|             i += 1 |             i += 1 | ||||||
|         deleteRecord(self, row, self.dbTableName, valueList) |         deleteRecord(self, row, self.dbTableName, valueList) | ||||||
|  |     # редактирование записи | ||||||
|  |     def editCurrentRecord(self, row): | ||||||
|  |         valueList = [] | ||||||
|  |         #print(self.dbTableName, row, self.statusTip()) | ||||||
|  |         i = 0 | ||||||
|  |         #print(self.columnCount()) | ||||||
|  |         #print(self.verticalHeaderItem(row).text(), '---') | ||||||
|  |         while i < self.columnCount(): | ||||||
|  |             if self.item(row, i): | ||||||
|  |                 val = self.item(row, i).text() | ||||||
|  |                 print(val) | ||||||
|  |                 valueList.append(str(val)) | ||||||
|  |             else: | ||||||
|  |                 valueList.append('') | ||||||
|  |  | ||||||
|  |             i += 1 | ||||||
|  |         print(valueList) | ||||||
|  |         editRecord(self, row, self.dbTableName, valueList) | ||||||
|  |  | ||||||
| # Диалог выбора связанных данных | # Диалог выбора связанных данных | ||||||
| class RelationDataView(QMainWindow): | class RelationDataView(QMainWindow): | ||||||
| @@ -170,10 +198,14 @@ class EditForm(QMainWindow): | |||||||
|     lblList = [] |     lblList = [] | ||||||
|     editList = [] |     editList = [] | ||||||
|  |  | ||||||
|     def __init__(self, tblName, tblDescr): |     def __init__(self, tblName, tblDescr, action): | ||||||
|         super().__init__() |         super().__init__() | ||||||
|         self.tblName = tblName |         self.tblName = tblName | ||||||
|         self.setWindowTitle("Добавление записи") |         self.action = action | ||||||
|  |         if action == 'edit': | ||||||
|  |             self.setWindowTitle("Редактирование записи") | ||||||
|  |         elif action == 'add': | ||||||
|  |             self.setWindowTitle("Добавление записи") | ||||||
|         #self.setGeometry(300, 300, 400, 400) |         #self.setGeometry(300, 300, 400, 400) | ||||||
|         scroll_widget = QWidget() |         scroll_widget = QWidget() | ||||||
|         self.general_layout = QVBoxLayout() |         self.general_layout = QVBoxLayout() | ||||||
| @@ -240,6 +272,7 @@ class EditForm(QMainWindow): | |||||||
|                 edit.setValidator(integerValidator) |                 edit.setValidator(integerValidator) | ||||||
|             else: |             else: | ||||||
|                 edit = QLineEdit() |                 edit = QLineEdit() | ||||||
|  |  | ||||||
|             # создаём список полей и соответсвующих им QEdit |             # создаём список полей и соответсвующих им QEdit | ||||||
|             self.widgetsList.append([fName, edit]) |             self.widgetsList.append([fName, edit]) | ||||||
|  |  | ||||||
| @@ -247,15 +280,15 @@ class EditForm(QMainWindow): | |||||||
|             hboxEdit.addWidget(lbl2) |             hboxEdit.addWidget(lbl2) | ||||||
|             hboxEdit.addWidget(edit) |             hboxEdit.addWidget(edit) | ||||||
|             # добавляем к полю кнопку для вызова связанных |             # добавляем к полю кнопку для вызова связанных | ||||||
|             print(fName) |             #print(fName) | ||||||
|             listRelationTableAndField = dm.getRelationsForField(tblName, fName) |             listRelationTableAndField = dm.getRelationsForField(tblName, fName) | ||||||
|  |  | ||||||
|             print(listRelationTableAndField) |             #print(listRelationTableAndField) | ||||||
|             if listRelationTableAndField != 'q': |             if listRelationTableAndField != 'q': | ||||||
|                 tableRelation = listRelationTableAndField[0] |                 tableRelation = listRelationTableAndField[0] | ||||||
|                 fieldRelation = listRelationTableAndField[1] |                 fieldRelation = listRelationTableAndField[1] | ||||||
|                 replaceField = listRelationTableAndField[2] |                 replaceField = listRelationTableAndField[2] | ||||||
|                 print(tableRelation + '-' + fieldRelation +'-'+replaceField) |                 #print(tableRelation + '-' + fieldRelation +'-'+replaceField) | ||||||
|                 btnRelations = QPushButton('...') |                 btnRelations = QPushButton('...') | ||||||
|                 btnRelations.setFixedWidth(30) |                 btnRelations.setFixedWidth(30) | ||||||
|                 # добавляем название виджета в список соответсвия кнопок и таблиц БД |                 # добавляем название виджета в список соответсвия кнопок и таблиц БД | ||||||
| @@ -284,7 +317,10 @@ class EditForm(QMainWindow): | |||||||
|                 listFieldData.append([item[0], item[1].text()]) |                 listFieldData.append([item[0], item[1].text()]) | ||||||
|         listData.append(listFieldData) |         listData.append(listFieldData) | ||||||
|         #print(listData) |         #print(listData) | ||||||
|         dm.insertDataIntoBD(listData) |         if self.action == 'add': | ||||||
|  |             dm.insertDataIntoBD(listData) | ||||||
|  |         elif self.action == 'edit': | ||||||
|  |             dm.editDataIntoBD(listData) | ||||||
|         self.close() |         self.close() | ||||||
|     # выбираем данные для связанной таблицы |     # выбираем данные для связанной таблицы | ||||||
|     def openRelationTable(self): |     def openRelationTable(self): | ||||||
| @@ -356,29 +392,38 @@ def addDataIntoTable(dbTableName, tblDataWidget, data='NULL'): | |||||||
|     dbFieldRelationValueList = [] |     dbFieldRelationValueList = [] | ||||||
|     for key in data: |     for key in data: | ||||||
|         n = 0 |         n = 0 | ||||||
|         #print(fieldNames, '\n', key) |         print(key) | ||||||
|         for item in key: |         for item in key: | ||||||
|             #print(m, n, item) |  | ||||||
|             listRelationTableAndField = dm.getRelationsForField(dbTableName, fieldNames[n][0]) |             listRelationTableAndField = dm.getRelationsForField(dbTableName, fieldNames[n][0]) | ||||||
|             #print('--->', fieldNames[n][1]) |  | ||||||
|             if listRelationTableAndField != 'q': |             if listRelationTableAndField != 'q': | ||||||
|                 #print('yahooooo', fieldNames[n][0]) |                 # кривой алгоритм, надо придумывать что-то другое | ||||||
|                 itemString = dm.re.search('>([0-9])+<(.+)', str(item)) |                 itemString = dm.re.search('>([0-9]+)<(.+)', str(item)) | ||||||
|                 if itemString: |                 if itemString: | ||||||
|                     #print('--->',itemString.groups()) |  | ||||||
|                     newitem = QTableWidgetItem(itemString.groups()[1]) |                     newitem = QTableWidgetItem(itemString.groups()[1]) | ||||||
|                     dbFieldRelationValueList.append([newitem, m, n, itemString.groups()[0], itemString.groups()[1]]) |                     dbFieldRelationValueList.append([newitem, m, n, itemString.groups()[0], itemString.groups()[1]]) | ||||||
|  |                 else: | ||||||
|  |                     newitem = QTableWidgetItem(str(item)) | ||||||
|  |                     dbFieldRelationValueList.append([newitem, m, n, 'None', 'None']) | ||||||
|             else: |             else: | ||||||
|  |                 # преобразуем все типы в строку | ||||||
|                 newitem = QTableWidgetItem(str(item)) |                 newitem = QTableWidgetItem(str(item)) | ||||||
|  |             #print(fieldNames[n][0]) | ||||||
|             # преобразуем все типы в строку |             #print(str(item)) | ||||||
|  |             # проверяем название поля и если это id то данные вносим в заголовок строки | ||||||
|  |             # таким образом внесем уникальный ID в чётко определенное поле | ||||||
|  |             #if fieldNames[n][0] == "id": | ||||||
|  |             #   tblDataWidget.setVerticalHeaderItem(m, QTableWidgetItem(str(item))) | ||||||
|             tblDataWidget.setItem(m, n, newitem) |             tblDataWidget.setItem(m, n, newitem) | ||||||
|             n += 1 |             n += 1 | ||||||
|         m += 1 |         m += 1 | ||||||
|     #print(dbFieldRelationValueList) |  | ||||||
| # Показ менб и панели инструментов | # Показ меню и панели инструментов | ||||||
| def showMenuToolbar(window): | def showMenuToolbar(window): | ||||||
|  |     openFileAction = QAction(QIcon('img/open.gif'), 'Открыть', window) | ||||||
|  |     openFileAction.setShortcut('Ctrl+O') | ||||||
|  |     openFileAction.setStatusTip('Открыть') | ||||||
|  |     openFileAction.triggered.connect(openTemplate) | ||||||
|  |  | ||||||
|     newAction = QAction(QIcon('img/new.gif'), 'Добавить', window) |     newAction = QAction(QIcon('img/new.gif'), 'Добавить', window) | ||||||
|     newAction.setShortcut('Ins') |     newAction.setShortcut('Ins') | ||||||
|     newAction.setStatusTip('Добавить') |     newAction.setStatusTip('Добавить') | ||||||
| @@ -387,45 +432,46 @@ def showMenuToolbar(window): | |||||||
|     deleteAction = QAction(QIcon('img/delete.gif'), 'Удалить', window) |     deleteAction = QAction(QIcon('img/delete.gif'), 'Удалить', window) | ||||||
|     deleteAction.setShortcut('Del') |     deleteAction.setShortcut('Del') | ||||||
|     deleteAction.setStatusTip('Удалить') |     deleteAction.setStatusTip('Удалить') | ||||||
|     # deleteAction.triggered.connect(window.qqqq) |  | ||||||
|  |  | ||||||
|     exitAction = QAction(QIcon('img/exit.gif'), 'Выход', window) |     exitAction = QAction(QIcon('img/exit.gif'), 'Выход', window) | ||||||
|     exitAction.setShortcut('Ctrl+Q') |     exitAction.setShortcut('Ctrl+Q') | ||||||
|     exitAction.setStatusTip('Выход') |     exitAction.setStatusTip('Выйти') | ||||||
|     exitAction.triggered.connect(window.close) |     exitAction.triggered.connect(exit) | ||||||
|  |  | ||||||
|  |     structureAction = QAction(QIcon('img/table.gif'), 'Показать структуру', window) | ||||||
|  |     #structureAction.setShortcut('Ctrl+Q') | ||||||
|  |     structureAction.setStatusTip('Показать структуру') | ||||||
|  |     structureAction.triggered.connect(showStructure) | ||||||
|  |  | ||||||
|     cutAction = QAction(QIcon('img/cut.gif'), 'Вырезать', window) |     cutAction = QAction(QIcon('img/cut.gif'), 'Вырезать', window) | ||||||
|     cutAction.setShortcut('Ctrl+X') |     cutAction.setShortcut('Ctrl+X') | ||||||
|     cutAction.setStatusTip('Вырезать') |     cutAction.setStatusTip('Вырезать') | ||||||
|     # cutAction.triggered.connect(window.close) |  | ||||||
|  |  | ||||||
|     copyAction = QAction(QIcon('img/copy.gif'), 'Копировать', window) |     copyAction = QAction(QIcon('img/copy.gif'), 'Копировать', window) | ||||||
|     copyAction.setShortcut('Ctrl+С') |     copyAction.setShortcut('Ctrl+С') | ||||||
|     copyAction.setStatusTip('Копировать') |     copyAction.setStatusTip('Копировать') | ||||||
|     # copyAction.triggered.connect(window.close) |  | ||||||
|  |  | ||||||
|     pasteAction = QAction(QIcon('img/paste.gif'), 'Вставить', window) |     pasteAction = QAction(QIcon('img/paste.gif'), 'Вставить', window) | ||||||
|     pasteAction.setShortcut('Ctrl+V') |     pasteAction.setShortcut('Ctrl+V') | ||||||
|     pasteAction.setStatusTip('Вставить') |     pasteAction.setStatusTip('Вставить') | ||||||
|     # pasteAction.triggered.connect(window.close) |  | ||||||
|  |  | ||||||
|     findAction = QAction(QIcon('img/find.gif'), 'Копировать', window) |     findAction = QAction(QIcon('img/find.gif'), 'Поиск', window) | ||||||
|     findAction.setShortcut('Ctrl+F') |     findAction.setShortcut('Ctrl+F') | ||||||
|     findAction.setStatusTip('Искать') |     findAction.setStatusTip('Искать') | ||||||
|     # findAction.triggered.connect(window.close) |  | ||||||
|  |  | ||||||
|     printAction = QAction(QIcon('img/print.gif'), 'Печатать', window) |     printAction = QAction(QIcon('img/print.gif'), 'Печатать', window) | ||||||
|     printAction.setShortcut('Ctrl+P') |     printAction.setShortcut('Ctrl+P') | ||||||
|     printAction.setStatusTip('Печатать') |     printAction.setStatusTip('Печатать') | ||||||
|     # printAction.triggered.connect(window.close) |  | ||||||
|  |  | ||||||
|     window.statusBar() |     window.statusBar() | ||||||
|  |  | ||||||
|     menubar = window.menuBar() |     menubar = window.menuBar() | ||||||
|     fileMenu = menubar.addMenu('&Файл') |     fileMenu = menubar.addMenu('&Файл') | ||||||
|  |     fileMenu.addAction(openFileAction) | ||||||
|     fileMenu.addAction(newAction) |     fileMenu.addAction(newAction) | ||||||
|     fileMenu.addAction(deleteAction) |     fileMenu.addAction(deleteAction) | ||||||
|     fileMenu.addAction(printAction) |     fileMenu.addAction(printAction) | ||||||
|  |     fileMenu.addAction(structureAction) | ||||||
|     fileMenu.addAction(exitAction) |     fileMenu.addAction(exitAction) | ||||||
|  |  | ||||||
|     editMenu = menubar.addMenu('&Редактирование') |     editMenu = menubar.addMenu('&Редактирование') | ||||||
| @@ -439,6 +485,7 @@ def showMenuToolbar(window): | |||||||
|     # toolbar = window.addToolBar('Редактирование') |     # toolbar = window.addToolBar('Редактирование') | ||||||
|  |  | ||||||
|     toolbar = window.addToolBar('Панель инструментов') |     toolbar = window.addToolBar('Панель инструментов') | ||||||
|  |     #toolbar.addAction(openFileAction) | ||||||
|     toolbar.addAction(newAction) |     toolbar.addAction(newAction) | ||||||
|     toolbar.addAction(deleteAction) |     toolbar.addAction(deleteAction) | ||||||
|     toolbar.addAction(copyAction) |     toolbar.addAction(copyAction) | ||||||
| @@ -457,7 +504,7 @@ def addNewRecord(): | |||||||
|             tblName = i[0] |             tblName = i[0] | ||||||
|  |  | ||||||
|     #print(tblName) |     #print(tblName) | ||||||
|     editForm = EditForm(tblName, tblDescr) |     editForm = EditForm(tblName, tblDescr, 'add') | ||||||
|     editForm.show() |     editForm.show() | ||||||
|     #editForm.setParent(listDBTables) |     #editForm.setParent(listDBTables) | ||||||
|     #editForm.show() |     #editForm.show() | ||||||
| @@ -497,27 +544,58 @@ def showRelationsRecords(fieldIndex, fieldValue): | |||||||
|             addDataIntoTable(tbl, tblRelationsData, qweryResult) |             addDataIntoTable(tbl, tblRelationsData, qweryResult) | ||||||
|             # пишем название активной таблицы БД в строку статуса |             # пишем название активной таблицы БД в строку статуса | ||||||
|             tblRelationsData.setStatusTip(tbl) |             tblRelationsData.setStatusTip(tbl) | ||||||
|  | # Удаление записи | ||||||
| def deleteRecord(tableWidget, row, dbTableName, valueList): | def deleteRecord(tableWidget, row, dbTableName, valueList): | ||||||
|     global dbFieldRelationValueList |     global dbFieldRelationValueList | ||||||
|     #print(tableWidget, row, dbTableName, valueList) |  | ||||||
|     #print(self.columnCount()) |  | ||||||
|     i = 0 |     i = 0 | ||||||
|     #print(valueList) |  | ||||||
|     for val in valueList: |     for val in valueList: | ||||||
|         #print(tableWidget.item(row, i)) |  | ||||||
|         #print('Значение из таблицы-->',valueList[i]) |  | ||||||
|         for item in dbFieldRelationValueList: |         for item in dbFieldRelationValueList: | ||||||
|             if item[0] == tableWidget.item(row, i): |             if item[0] == tableWidget.item(row, i): | ||||||
|                 #print(item[0]) |  | ||||||
|                 #print('еще значение',tableWidget.item(row, i).text(), item[0]) |  | ||||||
|                 value = item[3] |                 value = item[3] | ||||||
|                 valueList.pop(i) |                 valueList.pop(i) | ||||||
|                 valueList.insert(i, item[3]) |                 valueList.insert(i, item[3]) | ||||||
|  |  | ||||||
|         i += 1 |         i += 1 | ||||||
|     #print(valueList) |  | ||||||
|     dm.deleteRecordsFromDB(dbTableName, valueList) |     dm.deleteRecordsFromDB(dbTableName, valueList) | ||||||
|  | # Редактирование записи | ||||||
|  | def editRecord(tableWidget, row, dbTableName, valueList): | ||||||
|  |     global dbFieldRelationValueList | ||||||
|  |     editForm = EditForm(dbTableName, dm.getTablesDescriptionOfName(dbTableName), 'edit') | ||||||
|  |     editForm.show() | ||||||
|  |     i = 0 | ||||||
|  |     for val in valueList: | ||||||
|  |         for item in dbFieldRelationValueList: | ||||||
|  |             if item[0] == tableWidget.item(row, i): | ||||||
|  |                 value = item[3] | ||||||
|  |                 valueList.pop(i) | ||||||
|  |                 valueList.insert(i, item[3]) | ||||||
|  |                 val = item[3] | ||||||
|  |                 #print(val) | ||||||
|  |         editForm.widgetsList[i][1].setText(val) | ||||||
|  |         i += 1 | ||||||
|  |     #print(valueList) | ||||||
|  |  | ||||||
|  |     #print(editForm.widgetsList) | ||||||
|  |     #dm.deleteRecordsFromDB(dbTableName, valueList) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def showStructure(): | ||||||
|  |     global tabRelationsData, listDBTables | ||||||
|  |     tblDescr = listDBTables.model().data(listDBTables.currentIndex()) | ||||||
|  |     i = 0 | ||||||
|  |     for i in dbTablesList: | ||||||
|  |         if i[1] == tblDescr: | ||||||
|  |             tblName = i[0] | ||||||
|  |     print(tblName) | ||||||
|  |     #print(dm.getTableStructure(tblName)) | ||||||
|  |     print(dm.getFields(tblName)) | ||||||
|  |     print(dm.getTableStructureFromDB(tblName)) | ||||||
|  |  | ||||||
|  | def openTemplate(): | ||||||
|  |     global template_file, template_dir | ||||||
|  |     template_file = QFileDialog.getOpenFileName(None, 'Open file', template_dir)[0] | ||||||
|  |     dm.initDBstructure(template_file) | ||||||
|  |  | ||||||
|  |  | ||||||
| def main(): | def main(): | ||||||
|     global dbTablesList, listDBTables, tabRelationsData, dbFieldRelationValueList |     global dbTablesList, listDBTables, tabRelationsData, dbFieldRelationValueList | ||||||
| @@ -555,12 +633,12 @@ def main(): | |||||||
|     print(dm.getTablesNameOfDescription(listDBTables.model().data(listDBTables.currentIndex()))) |     print(dm.getTablesNameOfDescription(listDBTables.model().data(listDBTables.currentIndex()))) | ||||||
|  |  | ||||||
|  |  | ||||||
|     mainWin.setGeometry(300, 300, 800, 600) |     mainWin.setGeometry(300, 300, 1024, 800) | ||||||
|     mainWin.setWindowTitle('Data manipulator') |     mainWin.setWindowTitle('Data manipulator') | ||||||
|     mainWin.show() |     mainWin.show() | ||||||
|  |  | ||||||
|     return app.exec_() |     return app.exec_() | ||||||
|  |  | ||||||
|  |  | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|     main() |     main() | ||||||
|  |     print(template_dir) | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | pymysql==1.0.2 | ||||||
|  | PyQt5==5.15.7 | ||||||
							
								
								
									
										93
									
								
								test.py
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								test.py
									
									
									
									
									
								
							| @@ -1,93 +0,0 @@ | |||||||
| #!/usr/bin/env python |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ############################################################################# |  | ||||||
| ## |  | ||||||
| ## Copyright (C) 2013 Riverbank Computing Limited. |  | ||||||
| ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |  | ||||||
| ## All rights reserved. |  | ||||||
| ## |  | ||||||
| ## This file is part of the examples of PyQt. |  | ||||||
| ## |  | ||||||
| ## $QT_BEGIN_LICENSE:BSD$ |  | ||||||
| ## You may use this file under the terms of the BSD license as follows: |  | ||||||
| ## |  | ||||||
| ## "Redistribution and use in source and binary forms, with or without |  | ||||||
| ## modification, are permitted provided that the following conditions are |  | ||||||
| ## met: |  | ||||||
| ##   * Redistributions of source code must retain the above copyright |  | ||||||
| ##     notice, this list of conditions and the following disclaimer. |  | ||||||
| ##   * Redistributions in binary form must reproduce the above copyright |  | ||||||
| ##     notice, this list of conditions and the following disclaimer in |  | ||||||
| ##     the documentation and/or other materials provided with the |  | ||||||
| ##     distribution. |  | ||||||
| ##   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor |  | ||||||
| ##     the names of its contributors may be used to endorse or promote |  | ||||||
| ##     products derived from this software without specific prior written |  | ||||||
| ##     permission. |  | ||||||
| ## |  | ||||||
| ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  | ||||||
| ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  | ||||||
| ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  | ||||||
| ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  | ||||||
| ## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  | ||||||
| ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  | ||||||
| ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  | ||||||
| ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  | ||||||
| ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  | ||||||
| ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  | ||||||
| ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |  | ||||||
| ## $QT_END_LICENSE$ |  | ||||||
| ## |  | ||||||
| ############################################################################# |  | ||||||
|  |  | ||||||
|  |  | ||||||
| from PyQt5.QtCore import QModelIndex, Qt |  | ||||||
| from PyQt5.QtGui import QStandardItemModel |  | ||||||
| from PyQt5.QtWidgets import QApplication, QItemDelegate, QSpinBox, QTableView |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SpinBoxDelegate(QItemDelegate): |  | ||||||
|     def createEditor(self, parent, option, index): |  | ||||||
|         editor = QSpinBox(parent) |  | ||||||
|         editor.setMinimum(0) |  | ||||||
|         editor.setMaximum(100) |  | ||||||
|  |  | ||||||
|         return editor |  | ||||||
|  |  | ||||||
|     def setEditorData(self, spinBox, index): |  | ||||||
|         value = index.model().data(index, Qt.EditRole) |  | ||||||
|  |  | ||||||
|         spinBox.setValue(value) |  | ||||||
|  |  | ||||||
|     def setModelData(self, spinBox, model, index): |  | ||||||
|         spinBox.interpretText() |  | ||||||
|         value = spinBox.value() |  | ||||||
|  |  | ||||||
|         model.setData(index, value, Qt.EditRole) |  | ||||||
|  |  | ||||||
|     def updateEditorGeometry(self, editor, option, index): |  | ||||||
|         editor.setGeometry(option.rect) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| if __name__ == '__main__': |  | ||||||
|  |  | ||||||
|     import sys |  | ||||||
|  |  | ||||||
|     app = QApplication(sys.argv) |  | ||||||
|  |  | ||||||
|     model = QStandardItemModel(4, 4) |  | ||||||
|     tableView = QTableView() |  | ||||||
|     tableView.setModel(model) |  | ||||||
|  |  | ||||||
|     delegate = SpinBoxDelegate() |  | ||||||
|     tableView.setItemDelegate(delegate) |  | ||||||
|  |  | ||||||
|     for row in range(4): |  | ||||||
|         for column in range(4): |  | ||||||
|             index = model.index(row, column, QModelIndex()) |  | ||||||
|             model.setData(index, (row + 1) * (column + 1)) |  | ||||||
|  |  | ||||||
|     tableView.setWindowTitle("Spin Box Delegate") |  | ||||||
|     tableView.show() |  | ||||||
|     sys.exit(app.exec_()) |  | ||||||
		Reference in New Issue
	
	Block a user