Форум сайта python.su
Что ж, полностью переписал все функции. Согласен с тем, что прошлый код был ужасен.
Сейчас мне осталось решить два основных вопроса. Первый напишу сейчас, а второй после решения первого - выложу тогда весь код.
Итак. Первый вопрос.
Хочу оптимизировать вот такой код:
# сбор данных для 1 строки db_tb_i = dict(Первый = self.pole_1.text(), Второй = self.pole_2.text(), Третий = self.pole_3.text(), Четвёртый = self.pole_4.text()) # конец: сбор данных
self.polya = [self.pole_1,self.pole_2,self.pole_3,self.pole_4]
for i in range(0,columnCount): db_tb_i = dict(zip(i in columnName, (i in self.polya).text()))
lst_polya = list(map(text(), self.polya)) for i in range(0,columnCount): db_tb_i = dict(zip(i in columnName, i in lst_polya))
Отредактировано Kyrym (Авг. 11, 2017 13:03:10)
Офлайн
KyrymO_o. Я порям в замешательстве долго пытался понять что эта кнструкция должна делать.
Сначала я хотел сделать словарь таким образом:
Kyrymмап с методами класса так не работает, надо писать по другому
Не получилось. Тогда вот так:
Т.е. методы не работают с map или надо надо написать по-другому?
class Pole: # класс моделирующий lineEdit def __init__(self, text): self._text = text def text(self): return self._text columnName = ["Первый", "Второй", "Третий", "Четвёртый"] polya = list(Pole('Текст в поле {}'.format(i)) for i in range(1, 5)) # первый вариант без зипа db_tb_i1 = {columnName[i]: polya[i].text() for i in range(len(columnName))} # второй вариант с зипом db_tb_i2 = dict(zip((key for key in columnName ),(pole.text() for pole in polya))) # третий вариант с мапом lst_polya = list(map(lambda pole: pole.text(), polya)) print('текст в полях:',lst_polya) db_tb_i3 = dict(zip(columnName, lst_polya)) print('первый вариант:', db_tb_i1) print('второй вариант:', db_tb_i2) print('третий вариант:', db_tb_i3) >>> текст в полях: ['Текст в поле 1', 'Текст в поле 2', 'Текст в поле 3', 'Текст в поле 4'] первый вариант: {'Первый': 'Текст в поле 1', 'Третий': 'Текст в поле 3', 'Четвёртый': 'Текст в поле 4', 'Второй': 'Текст в поле 2'} второй вариант: {'Первый': 'Текст в поле 1', 'Третий': 'Текст в поле 3', 'Четвёртый': 'Текст в поле 4', 'Второй': 'Текст в поле 2'} третий вариант: {'Первый': 'Текст в поле 1', 'Третий': 'Текст в поле 3', 'Четвёртый': 'Текст в поле 4', 'Второй': 'Текст в поле 2'}
Kyrymну смотрите, если у вас будет с десяток строчек, то пик справиться, а если хртябы пару тысяч, то нужно будет думать на чемто другим..
А вообще для моих текущих целей pickl'a вполне достаточно. Тем более, что теперь я сохраняю базу по нажатии клавиши.
[code python][/code]
Офлайн
PEHDOMЭто не удивительно, если учесть, что я сначала хотел написать вариант через “for i in range(0,columnCount):”, а потом забыл его убрать, когда применил zip.
Я прям в замешательстве долго пытался понять что эта кнструкция должна делать.
db_tb_i = dict(zip(columnName, [polya.text() for polya in self.polya]))
Отредактировано Kyrym (Авг. 11, 2017 15:05:49)
Офлайн
Это я протупил, это по сути второй вариант, только я чето затупил что columnName и так список.
[code python][/code]
Офлайн
Вот что получилось в итоге:
import sys import pickle from PyQt4 import QtGui, QtCore # ЦВЕТА ПОЛЕЙ sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 10pt 'Courier New'") sss = ("background-color: #456173; color: #f2f2f0; font: 10pt 'Arial'") sss_err = ("background-color: #456173; color: #ff6161; font: bold 10pt 'Courier New'") # ПОДКЛЮЧЕНИЕ БД try: # если файл существует with open('database4.db', 'rb') as F: # открываем файл try: db_tb = pickle.load(F) # читаем содержимое в переменную db except EOFError: # если файл пустой db_tb = [] except FileNotFoundError: # если файл не существует F = open('database4.db', 'wb') # создаём пустой файл F.close() db_tb = [] # в файле нет данных # ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ columnName = ["Первый", "Второй", "Третий", "Четвёртый"] # заголовки табл rowCount = len(db_tb) # число строк columnCount = len(columnName) # число столбцов rowHeight = 20 # высота строки # ГРАФИКА class Window(QtGui.QWidget): # Класс Window наследует класс QWidget def __init__(self, parent=None): # Создаёт конструктор класса, parent - ссылка на родительский эл-т QtGui.QWidget.__init__(self, parent) super().__init__(parent, QtCore.Qt.Window) self.setMinimumSize(400, 600) # Ширина и высота окна self.resize(600, 800) # шир / выс окна self.setWindowTitle('Возможности таблицы QTableWidget') # Заголовок self.setWindowIcon(QtGui.QIcon('icon.png')) # Иконка # БЛОК РАЗМЕТКИ self.vbox_os = QtGui.QVBoxLayout() # Создали объект вертикальный контейнер self.grid = QtGui.QGridLayout() # создание сетки self.grid.setSpacing(5) # >>> ИСХОДНЫЕ ДАННЫЕ self.pole_1 = QtGui.QLineEdit('') self.pole_1.setStyleSheet(sss) self.grid.addWidget(self.pole_1, 0,0) # --- self.pole_2 = QtGui.QLineEdit('') self.pole_2.setStyleSheet(sss) self.grid.addWidget(self.pole_2, 0,1) # --- self.pole_3 = QtGui.QLineEdit('') self.pole_3.setStyleSheet(sss) self.grid.addWidget(self.pole_3, 0,2) # --- self.pole_4 = QtGui.QLineEdit('') self.pole_4.setStyleSheet(sss) self.grid.addWidget(self.pole_4, 0,3) # --- self.button_prnt = QtGui.QPushButton('Принт ДБ') self.button_prnt.clicked.connect(self.on_prnt) self.grid.addWidget(self.button_prnt, 1,0) # --- self.button_add = QtGui.QPushButton('Добавить в табл.') self.button_add.clicked.connect(self.on_add_row) self.grid.addWidget(self.button_add, 1,1) # --- self.button_del_row = QtGui.QPushButton('Удалить стр') self.button_del_row.clicked.connect(self.on_del_row) self.grid.addWidget(self.button_del_row, 1,2) # --- self.button_save_db = QtGui.QPushButton('Сохранить БД') self.button_save_db.clicked.connect(self.save_in_file) self.grid.addWidget(self.button_save_db, 1,3) # --- --- self.button_edit_row = QtGui.QPushButton('Редактировать стр') self.button_edit_row.clicked.connect(self.on_edit_row) self.grid.addWidget(self.button_edit_row, 2,0) # --- self.button_save_row = QtGui.QPushButton('Сохранить стр') self.button_save_row.clicked.connect(self.on_save_row) self.grid.addWidget(self.button_save_row, 2,1) # --- self.button_up_row = QtGui.QPushButton('Вверх стр') self.button_up_row.clicked.connect(self.on_up_row) self.grid.addWidget(self.button_up_row, 2,2) # --- self.button_down_row = QtGui.QPushButton('Вниз стр') self.button_down_row.clicked.connect(self.on_down_row) self.grid.addWidget(self.button_down_row, 2,3) self.polya = [self.pole_1,self.pole_2,self.pole_3,self.pole_4] # >>> КОНЕЦ: ИСХОДНЫЕ ДАННЫЕ self.vbox_os.addLayout(self.grid) # --- self.table = QtGui.QTableWidget() # Таблица self.createTable(columnName, rowCount, columnCount, rowHeight) self.vbox_os.addWidget(self.table) # Таблица 1 # --- self.lbl_predup = QtGui.QLabel() self.lbl_predup.setStyleSheet(sss_err) self.vbox_os.addWidget(self.lbl_predup) # --- self.pole_vivod = QtGui.QTextEdit() self.pole_vivod.setStyleSheet(sss_vivod) self.vbox_os.addWidget(self.pole_vivod) # --- self.setLayout(self.vbox_os) # установка рабочей области def createTable(self, columnName, rowCount, columnCount, rowHeight): # создание таблицы '''создаем строки и столбцы в таблице columnName - подписи шапки таблицы rowCount - количество строк таблицы columnCount - количество столбцов таблицы rowHeight - высота строки''' # Режим растяжения таблицы по вертикали и горизонтали self.table.verticalHeader().setResizeMode(QtGui.QHeaderView.Fixed) self.table.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) # Режим выделения. Выделяем только строки. Выделяем только одну строку. self.table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.table.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) # Стилизуем шапку таблицы self.table.horizontalHeader().setStyleSheet("QHeaderView::section{font-weight:bold; color:#46647F; height:26px}"); # self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) # Запрет редактирования таблицы self.table.setEditTriggers(QtGui.QAbstractItemView.CurrentChanged) # выделение элемента self.table.setEditTriggers(QtGui.QAbstractItemView.DoubleClicked) self.table.setRowCount(rowCount) # Устанавливаем количество строк self.table.setColumnCount(columnCount) # Устанавливаем количество столбцов i = 0 # формируем подписи шапки: for name in columnName: item = QtGui.QTableWidgetItem() item.setText(name) self.table.setHorizontalHeaderItem(i,item) i+=1 # Устанавливаем высоту строк for i in range(0, rowCount): self.table.setRowHeight(i, rowHeight) self.table.setColumnWidth(2, 50) # СИГНАЛЫ И ДОП СВОЙСТВА self.table.itemChanged.connect(self.cell_tabl_in_db) # сохр изменений в ячейке self.table.cellChanged.connect(self.predup) # предупреждение об изменении ячейки # АВТОЗАПУСК self.on_start() # ЛОГИКА def on_start(self): self.table.blockSignals(True) # блокировка сигналов for i in range(0,rowCount): # вставить базу данных в таблицу for j in range(0,columnCount): self.db_in_cell_tabl(i,j) self.table.blockSignals(False) # отмена блокировки сигналов def on_add_row (self): # добавить строку в базу # сбор данных для 1 строки db_tb_i = dict(zip(columnName, [polya.text() for polya in self.polya])) # конец: сбор данных db_tb.append(db_tb_i) # данные для новой строки табл row_index = len(db_tb)-1 self.table.insertRow(row_index) self.paste_row(row_index,db_tb_i) self.predup() def paste_row(self, row,text): self.table.blockSignals(True) # блокировка сигналов self.table.setRowHeight(row, rowHeight) # высота строки for j in range(0,columnCount): # в таблицу вставляем значения self.db_in_cell_tabl(row,j) self.table.blockSignals(False) # отмена блокировки сигналов self.clear_polya() # очищаем поля def db_in_cell_tabl(self, i,j): # из базы данных в ячейку item = QtGui.QTableWidgetItem() item.setText(db_tb[i][columnName[j]]) self.table.setItem(i,j,item) def cell_tabl_in_db(self): # из ячейки табл в базу данных i = self.table.currentRow() # индекс выделенной строки j = self.table.currentColumn() # индекс выделенной строки text = self.table.item(i,j).text() # извлечь текст из ячейки db_tb[i][columnName[j]] = text # текст в базу def predup (self): # предупреждение об изменении данных ячейки self.lbl_predup.setText('Изменения не сохранены') def on_up_row (self): # перемещение строки вверх row_index = self.table.currentRow() # индекс выделенной строки if row_index == 0: pass else: db_tb.insert(row_index-1,db_tb[row_index]) # вставить строку в базу del db_tb[row_index+1] # удалить старую строку из базы self.table.insertRow(row_index-1) # вставить строку в табл self.table.removeRow(row_index+1) # удалить старую строку из табл self.paste_row(row_index-1,db_tb[row_index-1]) self.table.selectRow(row_index-1) self.predup() def on_down_row (self): # перемещение строки вниз row_index = self.table.currentRow() # индекс выделенной строки if row_index+1 == len(db_tb): pass else: db_tb.insert(row_index+2,db_tb[row_index]) # вставить строку в базу del db_tb[row_index] # удалить старую строку из базы self.table.insertRow(row_index+2) # вставить строку в табл self.table.removeRow(row_index) # удалить старую строку из табл self.paste_row(row_index+1,db_tb[row_index+1]) self.table.selectRow(row_index+1) # выделяет передвинутую строку self.predup() def on_del_row (self): row_index = self.table.currentRow() # индекс выделенной строки del db_tb[row_index] # удалить строку в базе self.table.removeRow(row_index) # удалить строку в таблице self.predup() def on_edit_row(self): # правка строки в полях ввода row_index = self.table.currentRow() # индекс выделенной строки db_tb_i = db_tb[row_index] for i in range(0,len(self.polya)): # вставить строку из таблицы в поля self.polya[i].setText(db_tb_i[columnName[i]]) def on_save_row(self): # изм строку в полях отправить в таблицу # сбор данных для 1 строки db_tb_i = dict(zip(columnName, [polya.text() for polya in self.polya])) # конец: сбор данных row_index = self.table.currentRow() # индекс выделенной строки db_tb[row_index].update(db_tb_i) # обновление словаря self.paste_row(row_index,db_tb_i) self.clear_polya() self.predup() def save_in_file(self): # сохранить базу в файл with open('database4.db', 'wb') as f: pickle.dump(db_tb, f) self.lbl_predup.setText('') def clear_polya(self): # очистить поля ввода for i in range(0,len(self.polya)): self.polya[i].clear() def on_prnt(self): # вывод БД в Shell for i in range(0,len(db_tb)): print(i,':',db_tb[i],sep='') self.pole_vivod.append(''.join([str(i),':',str(db_tb[i])])) # КОНЕЦ if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = Window() # создаёт экземпляр окна из класса window.move(40, 20) # сдвиг окна от верхнего левого угла экрана pal = window.palette() pal.setBrush(QtGui.QPalette.Window, QtGui.QBrush(QtGui.QColor("#222831"))) window.setPalette(pal) # передаёт изменёный цвет окну window.show() # запускает окно sys.exit(app.exec_())
Офлайн
# сбор данных для 1 строки db_tb_i = dict(Первый = self.pole_1.text(), Второй = self.pole_2.text(), Третий = self.pole_3.text(), Четвёртый = self.pole_4.text())
db_tb_i = { x:y.text() for x in columnName for y in self.polya }
Отредактировано Rodegast (Авг. 11, 2017 16:29:25)
Офлайн
RodegastТ.е. язык питона написали наркоманы, будем знать…
ИХМО так словари только наркоманы создают.
RodegastRodegast, я Вас прошу в моих темах ничего не писать, потому что, цитируя Вашу подпись, мне “правда не нравится”.
А получился просто классический пример того как не надо делать.
Офлайн
> я Вас прошу в моих темах ничего не писать
Так Я и так стараюсь обходить твои темы стороной, но иной раз сдержаться очень трудно.
> цитируя Вашу подпись, мне “правда не нравится”
Ты бы сначала уточнил за что я “заранее извиняюсь”, а потом бы подумал стоит ли мою подпись цитировать.
Офлайн
Было бы что уточнять… Первое и второе предложение не связаны. Второе предложение, в котором допущено 2 ошибки, означает: “Если кому-то не нравится, что я пишу, то заранее извините”.
Офлайн
> Если кому-то не нравится, что я пишу, то заранее извините
Не совсем так. Это значит что если я к примеру начну писать всю правду о твоём “коде”, то у тебя может начаться лёгкое психическое расстройство. Вот специально для таких случаев и добавлена эта фраза.
Офлайн