2017-03-13 15:18:52 +03:00
|
|
|
|
#!/usr/bin/python3
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
import sys
|
2017-03-21 16:47:18 +03:00
|
|
|
|
from PyQt5.QtCore import *
|
|
|
|
|
from PyQt5.QtGui import *
|
2017-03-17 17:17:17 +03:00
|
|
|
|
from PyQt5.QtWidgets import *
|
|
|
|
|
|
2017-03-15 15:58:26 +03:00
|
|
|
|
#import pymysql
|
2017-03-13 15:18:52 +03:00
|
|
|
|
import dm
|
|
|
|
|
|
2017-03-14 14:09:31 +03:00
|
|
|
|
class MyTable(QTableWidget):
|
2017-03-21 16:47:18 +03:00
|
|
|
|
def __init__(self, *args):
|
2017-03-14 14:09:31 +03:00
|
|
|
|
QTableWidget.__init__(self, *args)
|
2017-03-16 16:10:47 +03:00
|
|
|
|
self.resizeColumnsToContents()
|
|
|
|
|
self.horizontalHeader().setSortIndicatorShown(True)
|
|
|
|
|
self.horizontalHeader().setStretchLastSection(True)
|
|
|
|
|
self.horizontalHeader().setCascadingSectionResizes(True)
|
|
|
|
|
# равномерное изменение ширины столбцов
|
|
|
|
|
#self.horizontalHeader().setSectionResizeMode(1)
|
|
|
|
|
# изменение ширины столбцов по размеру текста
|
2017-03-20 12:38:14 +03:00
|
|
|
|
#self.horizontalHeader().setSectionResizeMode(3)
|
2017-03-22 17:17:46 +03:00
|
|
|
|
self.horizontalHeader().setStyleSheet("color: black; font-weight:bold; background-color: lightblue;")
|
2017-03-20 12:38:14 +03:00
|
|
|
|
self.setWordWrap(True)
|
|
|
|
|
self.setSortingEnabled(True)
|
2017-03-17 17:17:17 +03:00
|
|
|
|
|
|
|
|
|
# обработка нажатия мышой на таблице
|
|
|
|
|
self.doubleClicked.connect(self.on_click)
|
|
|
|
|
# self.doubleClicked.connect(self.contextMenuEvent(self.cursor()))
|
|
|
|
|
|
|
|
|
|
# показ контекстного меню
|
|
|
|
|
def contextMenuEvent(self, event):
|
|
|
|
|
Rmenu = QMenu(self)
|
2017-03-20 12:38:14 +03:00
|
|
|
|
addRecord = Rmenu.addAction("Добавить запись")
|
2017-03-17 17:17:17 +03:00
|
|
|
|
delRecord = Rmenu.addAction("Удалить запись")
|
|
|
|
|
relations = Rmenu.addAction("Показать связанные документы")
|
|
|
|
|
action = Rmenu.exec_(self.mapToGlobal(event.pos()))
|
|
|
|
|
if action == delRecord:
|
|
|
|
|
row = self.rowAt(event.pos().y())
|
|
|
|
|
col = self.columnAt(event.pos().x())
|
2017-03-21 16:47:18 +03:00
|
|
|
|
print("Удаляем row:%d, col:%d" % (row, col))
|
2017-03-17 17:17:17 +03:00
|
|
|
|
item = self.item(self.currentIndex().row(), self.currentIndex().column())
|
2017-03-21 16:47:18 +03:00
|
|
|
|
print("Запись" + item.text())
|
2017-03-20 16:05:59 +03:00
|
|
|
|
elif action == addRecord:
|
2017-03-21 16:47:18 +03:00
|
|
|
|
print("Добавить запись ")
|
|
|
|
|
addNewRecord()
|
|
|
|
|
|
2017-03-17 17:17:17 +03:00
|
|
|
|
def on_click(self):
|
|
|
|
|
print(self.cursor().pos().x())
|
|
|
|
|
#self.contextMenuEvent(self.cursor())
|
|
|
|
|
for currentQTableWidgetItem in self.selectedItems():
|
|
|
|
|
print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())
|
|
|
|
|
|
2017-03-20 12:38:14 +03:00
|
|
|
|
# Форма для добавления и редактирования
|
2017-03-22 17:17:46 +03:00
|
|
|
|
class EditForm(QMainWindow):
|
|
|
|
|
lblList = []
|
|
|
|
|
editList = []
|
2017-03-21 20:10:38 +03:00
|
|
|
|
def __init__(self, tblName, tblDescr):
|
2017-03-21 16:47:18 +03:00
|
|
|
|
super().__init__()
|
2017-03-22 17:17:46 +03:00
|
|
|
|
self.tblName = tblName
|
|
|
|
|
self.setWindowTitle("Добавление записи")
|
|
|
|
|
scroll_widget = QWidget()
|
|
|
|
|
self.general_layout = QVBoxLayout()
|
|
|
|
|
scroll_area = QScrollArea()
|
|
|
|
|
|
2017-03-21 16:47:18 +03:00
|
|
|
|
l = QVBoxLayout()
|
2017-03-21 20:10:38 +03:00
|
|
|
|
headBox = QHBoxLayout()
|
2017-03-22 17:17:46 +03:00
|
|
|
|
lblHeader = QLabel("<B>Таблица: " + tblDescr)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
l.addLayout(headBox)
|
2017-03-22 17:17:46 +03:00
|
|
|
|
#palet = QPalette(lblHeader.palette())
|
|
|
|
|
#lblHeader.setPalette(palet)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
headBox.addWidget(lblHeader)
|
|
|
|
|
hboxBtn = QHBoxLayout()
|
|
|
|
|
btnOk = QPushButton('Записать')
|
2017-03-22 17:17:46 +03:00
|
|
|
|
btnOk.clicked.connect(lambda: self.save())
|
2017-03-21 20:10:38 +03:00
|
|
|
|
btnCancel = QPushButton('Закрыть')
|
|
|
|
|
btnCancel.clicked.connect(lambda: self.close())
|
2017-03-22 17:17:46 +03:00
|
|
|
|
# цифровой валидатор, для проверки ввода
|
|
|
|
|
integerRegex = QRegExp("^[0-9]+$")
|
|
|
|
|
integerValidator = QRegExpValidator(integerRegex, self)
|
|
|
|
|
# список соответствия полей и QEdit
|
|
|
|
|
self.widgetsList = []
|
|
|
|
|
# добавляем динамически поля на форму в зависимости от типов данных
|
|
|
|
|
for item in dm.getFields(tblName):
|
|
|
|
|
#print(item)
|
|
|
|
|
fName = item[0]
|
|
|
|
|
fType = item[1]
|
|
|
|
|
fDescr = dm.getFieldDescription(tblName, fName)
|
|
|
|
|
hboxEdit = QHBoxLayout()
|
|
|
|
|
lbl = QLabel(fDescr)
|
|
|
|
|
# создаем поле ввода соответсвующее типу данных
|
|
|
|
|
if fType == 'datetime':
|
|
|
|
|
edit = QDateTimeEdit()
|
|
|
|
|
edit.setCalendarPopup(True)
|
|
|
|
|
edit.setFrame(False)
|
|
|
|
|
now = QDateTime.currentDateTime()
|
|
|
|
|
edit.setDateTime(now)
|
|
|
|
|
elif fType == 'date':
|
|
|
|
|
edit = QDateEdit()
|
|
|
|
|
edit.setCalendarPopup(True)
|
|
|
|
|
edit.setFrame(False)
|
|
|
|
|
now = QDate.currentDate()
|
|
|
|
|
edit.setDate(now)
|
|
|
|
|
elif fType == 'time':
|
|
|
|
|
edit = QTimeEdit()
|
|
|
|
|
edit.setCalendarPopup(True)
|
|
|
|
|
edit.setFrame(False)
|
|
|
|
|
now = QTime.currentTime()
|
|
|
|
|
edit.setTime(now)
|
|
|
|
|
elif fType == 'integer':
|
|
|
|
|
edit = QLineEdit()
|
|
|
|
|
# проверка на ввод цифр
|
|
|
|
|
edit.setValidator(integerValidator)
|
|
|
|
|
else:
|
|
|
|
|
edit = QLineEdit()
|
|
|
|
|
# создаём список полей и соответсвующих им QEdit
|
|
|
|
|
self.widgetsList.append([fName, edit])
|
|
|
|
|
|
|
|
|
|
hboxEdit.addWidget(lbl)
|
|
|
|
|
hboxEdit.addWidget(edit)
|
|
|
|
|
l.addLayout(hboxEdit)
|
|
|
|
|
print(self.widgetsList)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
hboxBtn.addWidget(btnOk)
|
|
|
|
|
hboxBtn.addWidget(btnCancel)
|
|
|
|
|
l.addLayout(hboxBtn)
|
|
|
|
|
|
2017-03-22 17:17:46 +03:00
|
|
|
|
self.general_layout.addLayout(l)
|
|
|
|
|
|
|
|
|
|
scroll_widget.setLayout(self.general_layout)
|
|
|
|
|
scroll_area.setWidget(scroll_widget)
|
|
|
|
|
self.setCentralWidget(scroll_area)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
|
2017-03-22 17:17:46 +03:00
|
|
|
|
def save(self):
|
|
|
|
|
listData = [self.tblName]
|
|
|
|
|
listFieldData = []
|
|
|
|
|
for item in self.widgetsList:
|
|
|
|
|
#print(item[0] + ' ' + item[1].text())
|
|
|
|
|
listFieldData.append([item[0], item[1].text()])
|
|
|
|
|
listData.append(listFieldData)
|
|
|
|
|
#print(listData)
|
|
|
|
|
dm.insertDataIntoBD(listData)
|
|
|
|
|
self.close()
|
2017-03-20 12:38:14 +03:00
|
|
|
|
|
|
|
|
|
|
2017-03-22 17:17:46 +03:00
|
|
|
|
|
|
|
|
|
class EditForm_(QMainWindow):
|
2017-03-21 20:10:38 +03:00
|
|
|
|
def __init__(self, tblName, tblDescr):
|
|
|
|
|
super().__init__()
|
2017-03-22 17:17:46 +03:00
|
|
|
|
self.setWindowTitle("Добавление записи")
|
2017-03-21 20:10:38 +03:00
|
|
|
|
scroll_widget = QWidget()
|
|
|
|
|
self.general_layout = QVBoxLayout()
|
|
|
|
|
scroll_area = QScrollArea()
|
|
|
|
|
|
|
|
|
|
l = QVBoxLayout()
|
|
|
|
|
headBox = QHBoxLayout()
|
2017-03-22 17:17:46 +03:00
|
|
|
|
lblHeader = QLabel("<B>Таблица: " + tblDescr)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
l.addLayout(headBox)
|
2017-03-22 17:17:46 +03:00
|
|
|
|
#palet = QPalette(lblHeader.palette())
|
|
|
|
|
#lblHeader.setPalette(palet)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
headBox.addWidget(lblHeader)
|
|
|
|
|
hboxBtn = QHBoxLayout()
|
|
|
|
|
btnOk = QPushButton('Записать')
|
2017-03-22 17:17:46 +03:00
|
|
|
|
btnOk.clicked.connect(lambda: self.save())
|
2017-03-21 20:10:38 +03:00
|
|
|
|
btnCancel = QPushButton('Закрыть')
|
|
|
|
|
btnCancel.clicked.connect(lambda: self.close())
|
2017-03-22 17:17:46 +03:00
|
|
|
|
|
|
|
|
|
# ПРОВЕРКА ВВОДА, добавить в цикл генерации формы в зависимости от типа поля
|
|
|
|
|
# grid_layout.addWidget(QLabel("Введите IP-адрес", self), 0, 0)
|
|
|
|
|
#
|
|
|
|
|
# ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" # Часть регулярного выржение
|
|
|
|
|
# # Само регулярное выражение
|
|
|
|
|
# ipRegex = QRegExp("^" + ipRange + "\\." + ipRange + "\\." + ipRange + "\\." + ipRange + "$")
|
|
|
|
|
# ipValidator = QRegExpValidator(ipRegex, self) # Валидатор для QLineEdit
|
|
|
|
|
#
|
|
|
|
|
# lineEdit = QLineEdit()
|
|
|
|
|
# lineEdit.setValidator(ipValidator) # Устанавливаем валидатор
|
|
|
|
|
|
2017-03-21 20:10:38 +03:00
|
|
|
|
i=0
|
|
|
|
|
for item in dm.getTableStructure(tblName):
|
2017-03-22 17:17:46 +03:00
|
|
|
|
#print(item)
|
|
|
|
|
hboxEdit = QHBoxLayout()
|
|
|
|
|
lbl = QLabel(item)
|
|
|
|
|
edit = QLineEdit()
|
|
|
|
|
hboxEdit.addWidget(lbl)
|
|
|
|
|
hboxEdit.addWidget(edit)
|
|
|
|
|
l.addLayout(hboxEdit)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
i = i+1
|
|
|
|
|
|
|
|
|
|
hboxBtn.addWidget(btnOk)
|
|
|
|
|
hboxBtn.addWidget(btnCancel)
|
|
|
|
|
l.addLayout(hboxBtn)
|
|
|
|
|
|
|
|
|
|
self.general_layout.addLayout(l)
|
|
|
|
|
|
|
|
|
|
scroll_widget.setLayout(self.general_layout)
|
|
|
|
|
scroll_area.setWidget(scroll_widget)
|
|
|
|
|
self.setCentralWidget(scroll_area)
|
|
|
|
|
|
2017-03-22 17:17:46 +03:00
|
|
|
|
def save(self):
|
|
|
|
|
print(self.children())
|
2017-03-13 15:18:52 +03:00
|
|
|
|
|
2017-03-21 16:47:18 +03:00
|
|
|
|
def addDataIntoTable(tbl_descr, tblDataWidget):
|
|
|
|
|
global tblList
|
|
|
|
|
# выбираем название таблицы по описанию
|
|
|
|
|
for i in tblList:
|
|
|
|
|
if i[1] == tbl_descr:
|
|
|
|
|
tbl_name = i[0]
|
|
|
|
|
#print(tbl_descr)
|
|
|
|
|
data = dm.selectData(tbl_name)
|
|
|
|
|
#print(data)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
fieldNames = dm.getTableStructure(tbl_name)
|
2017-03-22 17:17:46 +03:00
|
|
|
|
print(fieldNames)
|
2017-03-21 16:47:18 +03:00
|
|
|
|
# проверка на наличие записей в таблице
|
|
|
|
|
if data:
|
|
|
|
|
# количество строк
|
|
|
|
|
rows = len(data)
|
|
|
|
|
# КОЛИЧЕСТВО КОЛОНОК
|
|
|
|
|
cols = len(data[0])
|
|
|
|
|
else:
|
|
|
|
|
rows = 0
|
|
|
|
|
cols = len(fieldNames)
|
|
|
|
|
n = 0
|
|
|
|
|
tblDataWidget.setRowCount(rows)
|
|
|
|
|
tblDataWidget.setColumnCount(cols)
|
|
|
|
|
for item in fieldNames:
|
2017-03-22 17:17:46 +03:00
|
|
|
|
fName = item[0]
|
|
|
|
|
fDescr = item[1]
|
|
|
|
|
#fieldNames = item + ','
|
2017-03-21 16:47:18 +03:00
|
|
|
|
# установка заголовков столбцов таблицы
|
2017-03-22 17:17:46 +03:00
|
|
|
|
#item = '<b>' + item + '</b>'
|
|
|
|
|
tblDataWidget.setHorizontalHeaderItem(n, QTableWidgetItem(fDescr))
|
2017-03-21 16:47:18 +03:00
|
|
|
|
n = n + 1
|
|
|
|
|
|
|
|
|
|
n = 0
|
|
|
|
|
for key in data:
|
|
|
|
|
m = 0
|
|
|
|
|
for item in key:
|
|
|
|
|
# преобразуем все типы в строку
|
|
|
|
|
newitem = QTableWidgetItem(str(item))
|
|
|
|
|
tblDataWidget.setItem(m, n, newitem)
|
|
|
|
|
n += 1
|
|
|
|
|
m += 1
|
|
|
|
|
|
|
|
|
|
def showMenuToolbar(window):
|
|
|
|
|
newAction = QAction(QIcon('img/new.gif'), 'Добавить', window)
|
|
|
|
|
newAction.setShortcut('Ins')
|
|
|
|
|
newAction.setStatusTip('Добавить')
|
|
|
|
|
newAction.triggered.connect(addNewRecord)
|
|
|
|
|
|
|
|
|
|
deleteAction = QAction(QIcon('img/delete.gif'), 'Удалить', window)
|
|
|
|
|
deleteAction.setShortcut('Del')
|
|
|
|
|
deleteAction.setStatusTip('Удалить')
|
|
|
|
|
# deleteAction.triggered.connect(window.qqqq)
|
|
|
|
|
|
|
|
|
|
exitAction = QAction(QIcon('img/exit.gif'), 'Выход', window)
|
|
|
|
|
exitAction.setShortcut('Ctrl+Q')
|
|
|
|
|
exitAction.setStatusTip('Выход')
|
|
|
|
|
exitAction.triggered.connect(window.close)
|
|
|
|
|
|
|
|
|
|
cutAction = QAction(QIcon('img/cut.gif'), 'Вырезать', window)
|
|
|
|
|
cutAction.setShortcut('Ctrl+X')
|
|
|
|
|
cutAction.setStatusTip('Вырезать')
|
|
|
|
|
# cutAction.triggered.connect(window.close)
|
|
|
|
|
|
|
|
|
|
copyAction = QAction(QIcon('img/copy.gif'), 'Копировать', window)
|
|
|
|
|
copyAction.setShortcut('Ctrl+С')
|
|
|
|
|
copyAction.setStatusTip('Копировать')
|
|
|
|
|
# copyAction.triggered.connect(window.close)
|
|
|
|
|
|
|
|
|
|
pasteAction = QAction(QIcon('img/paste.gif'), 'Вставить', window)
|
|
|
|
|
pasteAction.setShortcut('Ctrl+V')
|
|
|
|
|
pasteAction.setStatusTip('Вставить')
|
|
|
|
|
# pasteAction.triggered.connect(window.close)
|
|
|
|
|
|
|
|
|
|
findAction = QAction(QIcon('img/find.gif'), 'Копировать', window)
|
|
|
|
|
findAction.setShortcut('Ctrl+F')
|
|
|
|
|
findAction.setStatusTip('Искать')
|
|
|
|
|
# findAction.triggered.connect(window.close)
|
|
|
|
|
|
|
|
|
|
printAction = QAction(QIcon('img/print.gif'), 'Печатать', window)
|
|
|
|
|
printAction.setShortcut('Ctrl+P')
|
|
|
|
|
printAction.setStatusTip('Печатать')
|
|
|
|
|
# printAction.triggered.connect(window.close)
|
|
|
|
|
|
|
|
|
|
window.statusBar()
|
|
|
|
|
|
|
|
|
|
menubar = window.menuBar()
|
|
|
|
|
fileMenu = menubar.addMenu('&Файл')
|
|
|
|
|
fileMenu.addAction(newAction)
|
|
|
|
|
fileMenu.addAction(deleteAction)
|
|
|
|
|
fileMenu.addAction(printAction)
|
|
|
|
|
fileMenu.addAction(exitAction)
|
|
|
|
|
|
|
|
|
|
editMenu = menubar.addMenu('&Редактирование')
|
|
|
|
|
editMenu.addAction(copyAction)
|
|
|
|
|
editMenu.addAction(cutAction)
|
|
|
|
|
editMenu.addAction(pasteAction)
|
|
|
|
|
editMenu.addAction(printAction)
|
|
|
|
|
|
|
|
|
|
helpMenu = menubar.addMenu('&Помощь')
|
|
|
|
|
|
|
|
|
|
# toolbar = window.addToolBar('Редактирование')
|
|
|
|
|
|
|
|
|
|
toolbar = window.addToolBar('Панель инструментов')
|
|
|
|
|
toolbar.addAction(newAction)
|
|
|
|
|
toolbar.addAction(deleteAction)
|
|
|
|
|
toolbar.addAction(copyAction)
|
|
|
|
|
toolbar.addAction(cutAction)
|
|
|
|
|
toolbar.addAction(pasteAction)
|
|
|
|
|
toolbar.addAction(findAction)
|
|
|
|
|
toolbar.addAction(printAction)
|
|
|
|
|
# toolbar.addAction(exitAction)
|
|
|
|
|
|
|
|
|
|
def addNewRecord():
|
|
|
|
|
global listTables, tblRelationsData
|
|
|
|
|
tblDescr = listTables.model().data(listTables.currentIndex())
|
|
|
|
|
for i in tblList:
|
|
|
|
|
if i[1] == tblDescr:
|
|
|
|
|
tblName = i[0]
|
|
|
|
|
|
|
|
|
|
print(tblName)
|
2017-03-21 20:10:38 +03:00
|
|
|
|
editForm = EditForm(tblName, tblDescr)
|
|
|
|
|
editForm.show()
|
2017-03-21 16:47:18 +03:00
|
|
|
|
#editForm.setParent(listTables)
|
|
|
|
|
#editForm.show()
|
|
|
|
|
#editForm.setParent(tblRelationsData)
|
|
|
|
|
#editForm = Example()
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
global tblList, listTables, tblRelationsData
|
2017-03-13 15:18:52 +03:00
|
|
|
|
app = QApplication(sys.argv)
|
2017-03-21 16:47:18 +03:00
|
|
|
|
mainWin = QMainWindow()
|
|
|
|
|
workArea = QWidget()
|
|
|
|
|
mainWin.setCentralWidget(workArea)
|
|
|
|
|
hbox = QHBoxLayout()
|
|
|
|
|
listTables = QListWidget()
|
|
|
|
|
listTables.setFrameShape(QFrame.StyledPanel)
|
|
|
|
|
listTables.setFixedWidth(200)
|
|
|
|
|
#tblData = QTableWidget()
|
|
|
|
|
tblData = MyTable()
|
|
|
|
|
tblData.setFrameShape(QFrame.StyledPanel)
|
|
|
|
|
tblRelationsData = QTableWidget()
|
|
|
|
|
tblRelationsData.setFrameShape(QFrame.StyledPanel)
|
|
|
|
|
splitter1 = QSplitter(Qt.Horizontal)
|
|
|
|
|
splitter1.addWidget(listTables)
|
|
|
|
|
splitter2 = QSplitter(Qt.Vertical)
|
|
|
|
|
splitter2.addWidget(tblData)
|
|
|
|
|
splitter2.addWidget(tblRelationsData)
|
|
|
|
|
splitter1.addWidget(splitter2)
|
|
|
|
|
hbox.addWidget(splitter1)
|
|
|
|
|
workArea.setLayout(hbox)
|
|
|
|
|
showMenuToolbar(mainWin)
|
|
|
|
|
listTables.itemClicked.connect(lambda: addDataIntoTable(listTables.model().data(listTables.currentIndex()), tblData))
|
|
|
|
|
# выводим список таблиц в левом поле
|
|
|
|
|
tblList = dm.initDBstructure()
|
|
|
|
|
for i in tblList:
|
|
|
|
|
listTables.addItem(i[1])
|
|
|
|
|
|
|
|
|
|
mainWin.setGeometry(300, 300, 800, 600)
|
|
|
|
|
mainWin.setWindowTitle('Data manipulator')
|
|
|
|
|
mainWin.show()
|
|
|
|
|
|
|
|
|
|
return app.exec_()
|
2017-03-20 16:34:45 +03:00
|
|
|
|
#
|
|
|
|
|
#
|
2017-03-21 16:47:18 +03:00
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|