很抱歉這篇文章的長度。我嘗試了大約 10 種不同的方法來解決我的問題,但沒有運氣。我想給出最可能的背景關系。
我是 Pyqt5 的新手。我正在制作一個聯系人應用程式,我能夠使用 pyqt5 GUI 應用程式將資料輸入到 sqlite3 'contacts.db' 檔案中。我在應用程式的左側有 GUI 輸入欄位。我一直卡住的地方是如何在 GUI 應用程式右側的顯示框中顯示“contacts.db”檔案的內容?
這是一個螢屏截圖:

到目前為止,這是我的代碼:
import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import QSize
from sqlite3 import *
class MainWindow(QMainWindow):
# Creating Main drop window
def __init__(self):
QMainWindow.__init__(self)
# Sets dimentions for main drop window
self.setMinimumSize(QSize(1000, 425))
# Sets title for main drop window
self.setWindowTitle("Contacts")
def firstname():
# Creates a label for first field
self.nameLabel1 = QLabel(self)
# Creates label text for first label
self.nameLabel1.setText('First Name: ')
# Creates first field
self.line1 = QLineEdit(self)
# Sets placement for first field
self.line1.move(95, 50)
# Sets size for first field
self.line1.resize(200, 32)
# Sets placement for first label
self.nameLabel1.move(20, 50)
firstname()
def lastname():
self.nameLabel2 = QLabel(self)
self.nameLabel2.setText('Last Name: ')
self.line2 = QLineEdit(self)
self.line2.move(95, 100)
self.line2.resize(200, 32)
self.nameLabel2.move(20, 100)
lastname()
def email():
self.nameLabel3 = QLabel(self)
self.nameLabel3.setText('Email: ')
self.line3 = QLineEdit(self)
self.line3.move(95, 150)
self.line3.resize(200, 32)
self.nameLabel3.move(20, 150)
email()
def phone():
self.nameLabel4 = QLabel(self)
self.nameLabel4.setText('Phone: ')
self.line4 = QLineEdit(self)
self.line4.move(95, 200)
self.line4.resize(200, 32)
self.nameLabel4.move(20, 200)
phone()
def phone():
self.nameLabel5 = QLabel(self)
self.nameLabel5.setText('Location: ')
self.line5 = QLineEdit(self)
self.line5.move(95, 250)
self.line5.resize(200, 32)
self.nameLabel5.move(20, 250)
phone()
def button():
# Creates button, and button label
pybutton1 = QPushButton('Add Contact', self)
# Creates framwork for button funtion
pybutton1.clicked.connect(self.clickMethod1)
# Sets button size
pybutton1.resize(200,32)
# Sets button placement
pybutton1.move(95, 325)
button()
# Creates action that will be preformed when first button is pressed
def clickMethod1(self):
conn = connect('Contacts.db')
c = conn.cursor()
first = self.line1.text()
last = self.line2.text()
email = self.line3.text()
phone = self.line4.text()
loc = self.line5.text()
c.execute(f"""INSERT INTO contacts VALUES('{first}',
'{last}', '{email}', '{phone}', '{loc}')
""")
conn.commit()
conn.close()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit( app.exec_() )
要制作我擁有的相同資料庫,您可以在 python 中運行它:
from sqlite3 import *
conn = connect('Contacts.db')
c = conn.cursor()
# Make table
def make():
c.execute("""CREATE TABLE IF NOT EXISTS contacts(
first TEXT,
last TEXT,
email TEXT,
phone TEXT,
location TEXT
)""")
make()
conn.commit()
conn.close()
非常感謝您的幫助!
uj5u.com熱心網友回復:
Qt 已經通過QtSql模塊提供了對 SQL 的支持,因此您通常不需要使用單獨的 sql 模塊進行通用使用。
資料使用模型加載,并最終使用視圖顯示(閱讀更多關于Qt的模型/視圖編程范例。
您基本上執行以下操作:
- 加載資料庫引擎;
- 選擇一個資料庫;
- 創建一個模型(通常是一個QSqlTableModel);
- 創建一個視圖(通常是一個QTableView);
- 為該視圖設定模型,使用
setModel();
在下面的示例中,您可以看到模型已連接到資料庫,并且由于修改是直接對模型進行的,因此表會隨之自動更新。
請注意,我重新撰寫了您的代碼,因為它有很多問題:首先,QMainWindow 應該始終有一個中央小部件,然后您還應該始終使用布局管理器而不是任意大小和位置;我還洗掉了 中的函式,__init__因為它們是不必要的,只會使代碼分散注意力。
from PyQt5 import QtCore, QtWidgets, QtSql
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
central = QtWidgets.QWidget()
mainLayout = QtWidgets.QGridLayout(central)
mainLayout.setColumnStretch(0, 1)
mainLayout.setColumnStretch(1, 2)
formLayout = QtWidgets.QFormLayout()
mainLayout.addLayout(formLayout, 0, 0)
self.firstNameEdit = QtWidgets.QLineEdit()
self.lastNameEdit = QtWidgets.QLineEdit()
self.emailEdit = QtWidgets.QLineEdit()
self.phoneEdit = QtWidgets.QLineEdit()
self.locEdit = QtWidgets.QLineEdit()
formLayout.addRow('First name:', self.firstNameEdit)
formLayout.addRow('Last name:', self.lastNameEdit)
formLayout.addRow('Email:', self.emailEdit)
formLayout.addRow('Phone:', self.phoneEdit)
formLayout.addRow('Location:', self.locEdit)
self.addButton = QtWidgets.QPushButton('Add contact', enabled=False)
mainLayout.addWidget(self.addButton, 1, 0)
self.table = QtWidgets.QTableView()
mainLayout.addWidget(self.table, 0, 1, 2, 1)
self.table.setEditTriggers(self.table.NoEditTriggers)
self.setCentralWidget(central)
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('Contacts.db')
self.model = QtSql.QSqlTableModel()
self.model.setTable('contacts')
self.model.select()
self.table.setModel(self.model)
self.mandatoryFields = self.firstNameEdit, self.lastNameEdit
self.otherFields = self.emailEdit, self.phoneEdit, self.locEdit
self.allFields = self.mandatoryFields self.otherFields
for field in self.allFields:
field.textChanged.connect(self.validate)
self.addButton.clicked.connect(self.addRecord)
def addRecord(self):
record = self.model.record()
for i, field in enumerate(self.allFields):
record.setValue(i, field.text())
row = self.model.rowCount()
self.model.insertRow(row)
self.model.setRecord(row, record)
def validate(self):
for field in self.mandatoryFields:
if not field.text():
self.addButton.setEnabled(False)
return
for field in self.otherFields:
if field.text():
break
else:
self.addButton.setEnabled(False)
return
self.addButton.setEnabled(True)
另請注意,Qt 提供了一個非常方便的類QDataWidgetMapper,它允許將單個小部件與模型的欄位連接起來。通過這種方式,您可以在用戶選擇索引時自動更新欄位,或使用所有欄位更新資料庫。
這是上面代碼的一個稍微修改的版本,實作了映射器(為簡單起見,我再次發布整個代碼,因為修改太復雜了):
from PyQt5 import QtCore, QtWidgets, QtSql
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
central = QtWidgets.QWidget()
mainLayout = QtWidgets.QGridLayout(central)
mainLayout.setColumnStretch(0, 1)
mainLayout.setColumnStretch(1, 2)
formLayout = QtWidgets.QFormLayout()
mainLayout.addLayout(formLayout, 0, 0)
self.firstNameEdit = QtWidgets.QLineEdit()
self.lastNameEdit = QtWidgets.QLineEdit()
self.emailEdit = QtWidgets.QLineEdit()
self.phoneEdit = QtWidgets.QLineEdit()
self.locEdit = QtWidgets.QLineEdit()
formLayout.addRow('First name:', self.firstNameEdit)
formLayout.addRow('Last name:', self.lastNameEdit)
formLayout.addRow('Email:', self.emailEdit)
formLayout.addRow('Phone:', self.phoneEdit)
formLayout.addRow('Location:', self.locEdit)
self.updateButton = QtWidgets.QPushButton('Update contact', enabled=False)
self.addButton = QtWidgets.QPushButton('Add contact', enabled=False)
buttonLayout = QtWidgets.QHBoxLayout()
buttonLayout.addWidget(self.updateButton)
buttonLayout.addWidget(self.addButton)
mainLayout.addLayout(buttonLayout, 1, 0)
self.table = QtWidgets.QTableView()
mainLayout.addWidget(self.table, 0, 1, 2, 1)
self.table.setEditTriggers(self.table.NoEditTriggers)
self.setCentralWidget(central)
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('Contacts.db')
self.model = QtSql.QSqlTableModel()
self.model.setTable('contacts')
self.model.select()
self.table.setModel(self.model)
self.table.setSelectionMode(self.table.SingleSelection)
self.mandatoryFields = self.firstNameEdit, self.lastNameEdit
self.otherFields = self.emailEdit, self.phoneEdit, self.locEdit
self.allFields = self.mandatoryFields self.otherFields
self.mapper = QtWidgets.QDataWidgetMapper()
self.mapper.setModel(self.model)
self.mapper.setSubmitPolicy(self.mapper.ManualSubmit)
for i, field in enumerate(self.allFields):
field.textChanged.connect(self.validate)
self.mapper.addMapping(field, i)
self.addButton.clicked.connect(self.addRecord)
self.updateButton.clicked.connect(self.updateRecord)
self.table.selectionModel().selectionChanged.connect(self.selectionChanged)
self.mapper.currentIndexChanged.connect(self.validate)
self.table.doubleClicked.connect(self.doubleClicked)
self.table.viewport().installEventFilter(self)
def eventFilter(self, obj, event):
if event.type() == event.MouseButtonPress:
# clear all fields when clicking on an empty area of the table
index = self.table.indexAt(event.pos())
if not index.isValid():
self.table.selectionModel().select(
index, QtCore.QItemSelectionModel.ClearAndSelect)
return super().eventFilter(obj, event)
def doubleClicked(self, index):
widget = self.mapper.mappedWidgetAt(index.column())
if widget:
widget.setFocus()
def selectedRow(self):
selected = self.table.selectedIndexes()
if selected:
return selected[-1].row()
return -1
def selectionChanged(self):
row = self.selectedRow()
self.mapper.setCurrentIndex(row)
if row < 0:
for field in self.allFields:
field.setText('')
self.validate()
def addRecord(self):
# we cannot use submit(), as it will use the *current* index, nor we can
# insert the new row and set the new index, as it would clear all fields
record = self.model.record()
for i, field in enumerate(self.allFields):
record.setValue(i, field.text())
row = self.model.rowCount()
self.model.insertRow(row)
self.model.setRecord(row, record)
self.table.selectionModel().select(self.model.index(row, 0),
QtCore.QItemSelectionModel.ClearAndSelect)
def updateRecord(self):
row = self.selectedRow()
if row < 0:
self.updateButton.setEnabled(False)
return
self.mapper.submit()
def validate(self):
valid = True
for field in self.mandatoryFields:
if not field.text():
valid = False
break
else:
for field in self.otherFields:
if field.text():
break
else:
valid = False
self.addButton.setEnabled(valid)
self.updateButton.setEnabled(valid and bool(self.table.selectedIndexes()))
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/394255.html
