Найти - Пользователи
Полная версия: QtSql как удалить нужную запись
Начало » GUI » QtSql как удалить нужную запись
1 2 3
apologize828
Привет! Это снова я))) Продолжаю изучать Qtsql и вопрос возник такой даже не столько по Qtsql наверно а скорее по объекту QComboBox:
В общем в базе есть таблица Запчасти и в ней есть поля (Наименование,Количество,Цена,Марка,Год)
Вот код:
#!usr/bin/python
#-*- coding: utf-8 -*-
from PyQt4 import QtSql
from message_bd_1 import My_Messqge

class Baza_Dannyh():
def create_connection(self):
db=QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("baza_avto_zapchasty_my_baza")
if not db.open():
my_message=My_Messqge()
my_message.show()
my_message.exec_()
return False

query=QtSql.QSqlQuery()
query.exec("CREATE TABLE IF NOT EXISTS zapchasty(id INTEGER PRIMARY KEY AUTOINCREMENT, naimenovanie VARCHAR(50), kolichestvo INTEGER, price FLOAT, marka VARCHAR(50), year INTEGER)")
return True
Пользуюсь как и раньше таким выводом из базы
def otobrazit_dannye(self):
n=self.my_mainwindow.my_table.rowCount()
for i in range(n):
self.my_mainwindow.my_table.removeRow(0)

query=QtSql.QSqlQuery()
query.exec("SELECT * FROM zapchasty")
while query.next():

item0=QtGui.QTableWidgetItem(str(query.value(0)))
item0.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
item1=QtGui.QTableWidgetItem(str(query.value(1)))
item1.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
item2=QtGui.QTableWidgetItem(str(query.value(2)))
item2.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
item3=QtGui.QTableWidgetItem(str(query.value(3)))
item3.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
item4=QtGui.QTableWidgetItem(str(query.value(4)))
item4.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
item5=QtGui.QTableWidgetItem(str(query.value(5)))
item5.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)

self.my_mainwindow.my_table.insertRow(0)
self.my_mainwindow.my_table.setItem(0,0,item0)
self.my_mainwindow.my_table.setItem(0,1,item1)
self.my_mainwindow.my_table.setItem(0,2,item2)
self.my_mainwindow.my_table.setItem(0,3,item3)
self.my_mainwindow.my_table.setItem(0,4,item4)
self.my_mainwindow.my_table.setItem(0,5,item5)
self.my_mainwindow.my_table.sortItems(0)
Но только теперь я еще добавляю марку и год выбирая их в сombobox
вот код добавления
   def add_zapis(self):
a=self.my_form_add_zapchasty.edit_naimenovanie.text()
b=self.my_form_add_zapchasty.edit_kolichestvo.value()
c=self.my_form_add_zapchasty.edit_price.value()
d=self.my_form_add_zapchasty.combobox_avto.currentText()
e=self.my_form_add_zapchasty.combobox_year.currentText()

query=QtSql.QSqlQuery()
query.prepare("INSERT INTO zapchasty(naimenovanie,kolichestvo,price,marka,year) VALUES(:naimen,:kolich,:pr,:mark,:year)")
query.bindValue(":naimen",a)
query.bindValue(":kolich",b)
query.bindValue(":pr",c)
query.bindValue(":mark",d)
query.bindValue(":year",e)
query.exec_()

print(d,e)#здесь проверил в консоль выводит нормально а вот дальше строка походу не срабатывает и ничего не отображается
self.otobrazit_dannye()
self.my_form_add_zapchasty.hide()
Без данных из combobox выводит данные(наименовани,количество,цена) нормально!!а вот из-за них вообще не отображает запись. Может я чето пропустил.
НЕ подскажешь че за косяк у меня такой что он не хочет работать с данными из комбаБокса?
dartNNN
Фуф, ну однако дела… На взгляд все должно работать (или хотябы ошибку выдавать). Потратил немного времени для воссоздания ситуации и был шокирован :) В записи
    self.my_mainwindow.my_table.setItem(0,0,item0)
item0 существует, все выглядит вполне корректно, но! Не добавляет! И даже ошибку гад не выдает!
Вобщем после танцев с бубном решил: ну его на…
Я как раз нашел, как удаление в QTableView запаять и плюнуть в лицо этому QTableWidget. Короче в двух словах:
Только что узрел на форуме http://www.forum.crossplatform.ru/index.php?showtopic=1946
Собственно для удаления надо посмотреть только 1 и предпоследний пост, остальное как дополнительный материал :)
Всетаки гугл хорошая вещь:)
apologize828
Фуф, ну однако дела… На взгляд все должно работать (или хотябы ошибку выдавать). Потратил немного времени для воссоздания ситуации и был шокирован :) В записи
self.my_mainwindow.my_table.setItem(0,0,item0)
item0 существует, все выглядит вполне корректно, но! Не добавляет! И даже ошибку гад не выдает!
Вобщем после танцев с бубном решил: ну его на…
Вот и я с бубном запарился шаманить))) И не говори ведь даже ошибки не показывает!интересно все же че за коза такая)))
Я как раз нашел, как удаление в QTableView запаять и плюнуть в лицо этому QTableWidget. Короче в двух словах:
Только что узрел на форуме http://www.forum.crossplatform.ru/index.php?showtopic=1946
Собственно для удаления надо посмотреть только 1 и предпоследний пост, остальное как дополнительный материал :)
Всетаки гугл хорошая вещь:)
Спасибо за ссылку!!!Я кстати уже читал эту страницу,просто я не брал ее в расчет потому что там все без SQL делается а я тогда хотел посмотреть как именно с помощью QsqlQueryModel сделать можно на SQL,да и ты прав гугл очень выручает))
Кстати ты не имел дело с такой штукой как sqlalchemy(просто много слышал,но пока руки не доходят).Вещь хорошая?стоит посмотреть?
dartNNN
Гы! Я тоже много слышал про sqlalchemy, но попробовать случая не было. Говорят вещь для сложных проектов лучше всего подходит, ну и соответственно на изучение много времени уйдет (как я понимаю)
Андрей Светлов
неправильно понимаете. Для сложных проектов, естественно, алхимия вполне подходит - но и для простых тоже годится.
По поводу сложности обучения - вас обманули. Или прочитать tutorial http://www.sqlalchemy.org/docs/05/ormtutorial.html - долго?
apologize828
dartNNN
Гы! Я тоже много слышал про sqlalchemy, но попробовать случая не было. Говорят вещь для сложных проектов лучше всего подходит, ну и соответственно на изучение много времени уйдет (как я понимаю)
Понятно короче как с Qtsql изучу потом гляну))
Короче решил последовать твоему совету и забил на QTableWidget)))
Взялся опять за QSqlQueryModel(). С добавлением в прошлый разобрался без проблем и теперь немного подумав все же придумал таки как сделать удаление и редактирование. Удаление сделал и работает без проблем а вот с обновлением возникла маленькая затупка(((хотя принцип тот же но я че-то заступарился на ровном месте((.
Вот накидал такую тему посмотри может подскажешь:
Код для отображения модели:
        
def refresh_table(self):
self.model=QtSql.QSqlQueryModel()
self.model.setQuery("SELECT * FROM zapchasty")

self.model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QObject.trUtf8(self.model,"№"))
self.model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QObject.trUtf8(self.model,"Серийник"))
self.model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QObject.trUtf8(self.model,"Наименование"))
self.model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QObject.trUtf8(self.model,"Количество"))
self.model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QObject.trUtf8(self.model,"Цена"))
self.model.setHeaderData(5, QtCore.Qt.Horizontal, QtCore.QObject.trUtf8(self.model,"Марка"))

self.my_form.table.setModel(self.model)
Код для добавления новой записи:
def add_zapis(self):
a=self.my_add.edit_serialnumber.text()
b=self.my_add.edit_naimenovanie.text()
c=self.my_add.edit_kolichestvo.value()
d=self.my_add.edit_price.value()
e=self.my_add.combobox_marka.currentText()

query=QtSql.QSqlQuery()
query.exec("INSERT INTO zapchasty(serialnumber,naimenovanie,kolichestvo,price,marka) VALUES(:serialnumber,:naimenovanie,:kolichestvo,:price,:marka)")
query.bindValue(":serialnumber",a)
query.bindValue(":naimenovanie",b)
query.bindValue(":kolichestvo",c)
query.bindValue(":price",d)
query.bindValue(":marka",e)
query.exec_()

self.refresh_table()
self.my_add.hide()
Ну и вот собственно удаление, короче идею понял:
    def delete_zapis(self):   
query=QtSql.QSqlQuery()
query.exec("SELECT * FROM zapchasty")
while query.next():
a=str(query.value(0))

if self.my_form.table.currentIndex().row()>=0:
query.exec("DELETE FROM zapchasty WHERE id=:id")
query.bindValue(":id",a)
query.exec_()

self.refresh_table()
Ну а вот с обновлением появилась такая проблема:Смысл такой же как и для удаления НО че то я туплю и у меня не получается следующее Когда я выбираю запись открывается форма и на ней отображаются все данные которые есть в выбранной записи и затем внеся изменения жмем save и должно все сохранится для записи c выбранным ID, но посмотри у меня теряется ID(Просто моя функция update отдельно от запроса где определяется ID )Вопрос такой: Как же мне замутить чтобы в функции update передать ID который я определил выше?В общем смотри:
Код для запуска формы редактирования
def zapysk_edit(self):
query=QtSql.QSqlQuery()
query.exec("SELECT * FROM zapchasty")
while query.next():
a=str(query.value(0))#Вот как я и для удаления нужный мне ID который нужен мне будет в следующей ф-ции!!!
b=str(query.value(1))
c=str(query.value(2))
d=str(query.value(3))
e=str(query.value(4))
f=str(query.value(5))

if self.my_form.table.currentIndex().row()>=0:
self.my_edit=Form_Edit_Zapchasty()

self.my_edit.edit_serialnumber.setText(b)
self.my_edit.edit_naimenovanie.setText(c)
self.my_edit.edit_kolichestvo.setValue(int(d))
self.my_edit.edit_price.setValue(float(e))
self.my_edit.combobox_marka.setItemText(0,f)

self.my_edit.show()

self.my_edit.button_save.clicked.connect(self.update_zapis)
И вот функция для обновления:
def update_zapis(self):    
b1=self.my_edit.edit_serialnumber.text()
c1=self.my_edit.edit_naimenovanie.text()
d1=self.my_edit.edit_kolichestvo.value()
e1=self.my_edit.edit_price.value()
f1=self.my_edit.combobox_marka.currentText()

query=QtSql.QSqlQuery()
query.exec("UPDATE zapchasty SET serialnumber=:serialnumber,naimenovanie=:naimenovanie,kolichestvo=:kolichestvo,price=:price,marka=:marka WHERE id=:id")
query.bindValue(":id",a)#Вот здесь мне нужен ID корторый выше!!!!
query.bindValue(":serialnumber",b1)
query.bindValue(":naimenovanie",c1)
query.bindValue(":kolichestvo",d1)
query.bindValue(":price",e1)
query.bindValue(":marka",f1)
query.exec_()

self.refresh_table()
self.my_edit.hide()
P.S. Может я вообще бред изобрел)))тогда помоги переделать для обновления,а то мозги уже кипят(
villager
тихий ужас
найдите книгу “Ю_В_Земсков_ Программирование на C++ с использованием библиотеки Qt4”, там по строчкам расписано все (по русски)
да и документацию стоит почитать

вот пример с удалением, немного усложненный - на одну модель два синхронизированных предствления.

#!/usr/bin/env python
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtSql import *

def createConnection():
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(":memory:")
if not db.open():
QMessageBox.critical(0, qApp.tr("Cannot open database"),
qApp.tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information "
"how to build it.\n\nClick Cancel to exit."),
QMessageBox.Cancle, QMessageBox.NoButton)
return False
query = QSqlQuery()
query.exec_("create table person(id int primary key, "
"firstname varchar(20), lastname varchar(20))")
query.exec_("insert into person values(101, 'Danny', 'Young')")
query.exec_("insert into person values(102, 'Christine', 'Holand')")
query.exec_("insert into person values(103, 'Lars', 'Gordon')")
query.exec_("insert into person values(104, 'Roberto', 'Robitaille')")
query.exec_("insert into person values(105, 'Maria', 'Papadopoulos')")
query.exec_("insert into person values(106, 'Ma', 'Papa')")
return True

def createView( title, model ):
return view

class Window(QWidget):

def __init__(self, parent = None):
QWidget.__init__(self, parent)

model = QSqlTableModel(self)
model.setTable("person")
model.setEditStrategy(QSqlTableModel.OnManualSubmit)
model.select()

model.setHeaderData(0, Qt.Horizontal, QVariant(QObject.tr(model, "ID")))
model.setHeaderData(1, Qt.Horizontal, QVariant(QObject.tr(model, "First name")))
model.setHeaderData(2, Qt.Horizontal, QVariant(QObject.tr(model, "Last name")))

view1 = QTableView(self)
view1.setModel(model)
view1.setViewportMargins (-100, -100, -100, -100)
view1.verticalScrollBar().hide()
view1.horizontalScrollBar().hide()
view1.setSelectionBehavior(QAbstractItemView.SelectRows)
view1.setContextMenuPolicy(Qt.ActionsContextMenu)

def delrow():
view1.model().removeRow(view1.currentIndex().row())
view1.model().submitAll()

a=QAction("delete", view1)
a.triggered.connect(delrow)
view1.addAction(a)

def listtbl():
c=QSqlQuery("select * from person")
c.last()
print "Total number records: ", c.at()+1

b=QAction("check", view1)
b.triggered.connect(listtbl)
view1.addAction(b)


view2 = QTableView(self)
view2.setModel(model)
view2.setSelectionBehavior(QAbstractItemView.SelectRows)
view1.selectRow(0)
view2.selectRow(0)
layout = QHBoxLayout()
layout.addWidget(view1)
layout.addWidget(view2)
self.setLayout(layout)
layout.setMargin( 1)
layout.setSpacing(0)

############################################
def selectionChanged1():
view2.selectRow(selectionModel1.currentIndex().row())
def selectionChanged2():
view1.selectRow(selectionModel2.currentIndex().row())

selectionModel1 = QItemSelectionModel(model, view1)
view1.setSelectionModel(selectionModel1)
self.connect(selectionModel1, SIGNAL("currentChanged(const QModelIndex &, const QModelIndex &)"),selectionChanged1)

selectionModel2 = QItemSelectionModel(model, view2)
view2.setSelectionModel(selectionModel2)
self.connect(selectionModel2, SIGNAL("currentChanged(const QModelIndex &, const QModelIndex &)"),selectionChanged2)

view2.connect(view1.verticalScrollBar(), SIGNAL("valueChanged(int)"),view2.verticalScrollBar(), SLOT("setValue(int)"))
view2.connect(view2.verticalScrollBar(), SIGNAL("valueChanged(int)"),view1.verticalScrollBar(), SLOT("setValue(int)"))
############################################

if __name__ == "__main__":
app = QApplication(sys.argv)
if not createConnection():
sys.exit(1)

window = Window()
window.show()
sys.exit(app.exec_())
dartNNN
Ну что ж начнем обсуждение.
Для начала несколько слов крестьянину (ничего, что я вас так называю?):
self.connect(selectionModel1,
SIGNAL("currentChanged(const QModelIndex &, const QModelIndex &)"),selectionChanged1)
Это подходит для qt3, но весь прогрессивный мир использует новый стиль qt4:
selectionModel1.currentChanged.connect(selectionChanged1)
Хотелось бы еще пожелать, чтобы вы выкладывали код подходящий для вопроса. Незачем усложнять и вывкладывать все, в том числе и подключение к базе и создание QTableView, если важны всего несколько строк. Кстати позабавила запись:
def createView( title, model ):
return view
Ну еще скажу про отступы (с которыми в вашем примере сложности), в питоне они знаете важны:) Это все таки затрудняет понимание. Надо ценить чужое время и силы. Но главное вы сделали, мне не пришлось далеко ходить за строчкой:
view1.model().removeRow(view1.currentIndex().row())
Именно она нужна мне для решения вопроса 828 извинений (ничего, что я тебя так называю?). Как я понимаю, ты все хочешь сделать через SQL и эта строчка тебе не очень нравится, но главное в ней вот это:
view1.currentIndex().row()
Номер выбраного столбца. Использовать его для SQL можно примерно так (только что придумал, не судите строго):
    row = view1.currentIndex().row()
modelIndex = view1.currentIndex()
modelIndex = modelIndex.sibling(row,0)
id = view1.model().data(modelIndex).toString()
Вот так можно получить значение id для текущей QTableView записи (твои методы меня настораживают:))
По-моему это какое-то извращение, но другие пути мне пока не ведомы. Ну а сохранить его можно как атрибут класса self.id (он будет доступен во всех функциях), но это тоже своего рода извр (уж извините за выражения), хотя наиболее очевидный (и пока единственный для меня :)) способ
Ну а теперь предлагаю обсудить твой код :) Собственно по функции refresh_table особых замечаний нет:)
В функции add_zapis edit_serialnumber - слишком длинное имя, возможно его (и похожие) можно было бы сократить serial_num на мой взгляд читается легче (чисто субъективное мнение)
В функции удаления вот такая запись:
        while query.next():
a=str(query.value(0))
Выглядит как бред:) Уж не знаю, что нужно сделать, чтобы такое написать, но с этим точно надо заканчивать :) Выше как раз на это и дал пример. Получить другие поля (кроме id) для текущей записи не составит труда? (т.к. и в других функциях ты делаешь так же)

Кстати ты не читал книгу “Совершенный код” (Стив Макконнел). Очень рекомендую, она вобщем про принципы программирования.
Ну все, вроде все сказал.
dartNNN
Забыл сказать спасибо Андрею Светлову. Не брался за изучение sqlAlchemy, думая что оно сложно, но теперь точно найду время.
villager
dartNNN
Хотелось бы еще пожелать, чтобы вы выкладывали код подходящий для вопроса. Незачем усложнять и вывкладывать все, в том числе и подключение к базе и создание QTableView, если важны всего несколько строк.
по мне лучше иметь готовый рабочий пример чем разбираться в в малопонятных кусках - скопировал и запустил. И Вам того же желаю.

Основа примера не моя, просто дописал туда удаление строки и проверку кол-ва записей. Соответственно и коннекты не переделывал (да простит меня прогрессивный мир:).Кстати новый стиль появился только с PyQt версии 4.5.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB