1 from PyQt4.QtCore import *
2 from PyQt4.QtGui import *
3 from PyQt4.QtSql import *
5 class EditPerson(QWidget):
6 def __init__(self, parent=None, db=None):
7 QWidget.__init__(self,parent)
10 self.model = QSqlTableModel(self, self.db)
11 self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
12 self.model.setTable("people")
14 self.model.setHeaderData(self.model.fieldIndex("forename"), Qt.Horizontal, QVariant("First Name"))
15 self.model.setHeaderData(self.model.fieldIndex("surname"), Qt.Horizontal, QVariant("Last Name"))
17 self.tableview = QTableView(self)
18 self.tableview.setSelectionBehavior(QAbstractItemView.SelectRows)
19 self.tableview.setSelectionMode(QAbstractItemView.SingleSelection)
20 self.tableview.setEditTriggers(QAbstractItemView.NoEditTriggers)
21 self.tableview.setModel(self.model)
23 for i in xrange(self.model.columnCount()):
24 self.tableview.hideColumn(i)
25 self.tableview.showColumn(self.model.fieldIndex("forename"))
26 self.tableview.showColumn(self.model.fieldIndex("surname"))
27 self.tableview.resizeColumnsToContents()
29 self.setWindowTitle("Edit records")
30 self.toplayout = QHBoxLayout() # Master layout
32 self.leftpanel = QVBoxLayout() # Contains user search and select
33 self.search_label = QLabel("F&ilter by name:")
34 self.search_bar = QLineEdit()
35 self.search_label.setBuddy(self.search_bar)
36 self.searchpair = QHBoxLayout()
37 self.searchpair.addWidget(self.search_label)
38 self.searchpair.addWidget(self.search_bar)
39 self.leftpanel.addLayout(self.searchpair)
40 self.leftpanel.addWidget(self.tableview)
42 self.rightpanel = QVBoxLayout() # Contains fields and buttons
46 self.rightpanel.addLayout(self.formlayout)
47 self.rightpanel.addLayout(self.buttonlayout)
49 self.toplayout.addLayout(self.leftpanel)
50 self.toplayout.addSpacing(10)
51 self.toplayout.addLayout(self.rightpanel)
53 self.setLayout(self.toplayout)
60 self.current_record = QSqlRecord()
63 self.netid_lab = QLabel("NetID:")
64 self.year_lab = QLabel("Year:")
65 self.month_lab = QLabel("Month:")
66 self.day_lab = QLabel("Day:")
67 self.firstname_lab = QLabel("Preferred name:")
68 self.surname_lab = QLabel("Last name:")
69 self.email_lab = QLabel("Email:")
70 self.phone_lab = QLabel("Phone:")
71 self.major_lab = QLabel("Major:")
72 self.hometown_lab = QLabel("Hometown:")
73 self.room_lab = QLabel("Room number:")
74 self.bday_lab = QLabel("Birthday:")
75 self.dorm_lab = QLabel("Dorm:")
76 self.photo = QLabel("No record selected")
77 self.photo.setScaledContents(False)
78 self.currentimage = QImage()
79 self.displayimage = QImage()
80 self.displaypixmap = QPixmap()
81 self.photo.setAlignment(Qt.AlignCenter)
82 self.pb_changephoto = QPushButton("Select &photo")
83 self.pb_changephoto.setEnabled(False)
85 self.surname = QLineEdit()
86 self.firstname = QLineEdit()
87 self.phone = QLineEdit()
88 self.email = QLineEdit()
89 self.major = QLineEdit()
90 self.netid = QLineEdit()
92 self.year = QComboBox()
93 self.month = QComboBox()
94 self.day = QComboBox()
96 self.dorm = QComboBox()
97 self.room = QLineEdit()
98 # Fill the comboboxes with values, set valid field types
99 years = QStringList(["1983","1984","1985","1986","1987","1988","1989","1990","1991","1992","1993","1994"])
100 months = QStringList(["January","February","March","April","May","June","July","August","September","October","November","December"])
101 days = QStringList(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"])
102 dorms = QStringList(["Clements","Lechner","McFadden"])
103 self.year.addItems(years)
104 self.month.addItems(months)
105 self.day.addItems(days)
106 self.dorm.addItems(dorms)
107 self.phone.setInputMask("(999)-999-9999")
108 self.major.setMaxLength(4)
109 self.room.setMaxLength(3)
110 # Create and fill the UI
111 self.formlayout = QGridLayout()
112 self.bday_layout = QHBoxLayout()
113 self.bday_layout.addWidget(self.year)
114 self.bday_layout.addWidget(self.month)
115 self.bday_layout.addWidget(self.day)
116 self.formlayout.addWidget(self.netid_lab, 0, 0)
117 self.formlayout.addWidget(self.netid, 0, 1)
118 self.formlayout.addWidget(self.firstname_lab, 1, 0)
119 self.formlayout.addWidget(self.firstname, 1, 1)
120 self.formlayout.addWidget(self.surname_lab, 2, 0)
121 self.formlayout.addWidget(self.surname, 2, 1)
122 self.formlayout.addWidget(self.email_lab, 3, 0)
123 self.formlayout.addWidget(self.email, 3, 1)
124 self.formlayout.addWidget(self.phone_lab, 4, 0)
125 self.formlayout.addWidget(self.phone, 4, 1)
126 self.formlayout.addWidget(self.bday_lab,5,0)
127 self.formlayout.addLayout(self.bday_layout,5,1)
128 self.formlayout.addWidget(self.major_lab, 6, 0)
129 self.formlayout.addWidget(self.major, 6, 1)
130 self.formlayout.addWidget(self.dorm_lab, 7, 0)
131 self.formlayout.addWidget(self.dorm, 7, 1)
132 self.formlayout.addWidget(self.room_lab, 8, 0)
133 self.formlayout.addWidget(self.room, 8, 1)
134 self.formlayout.addWidget(self.photo,9,0,1,2)
135 self.formlayout.addWidget(self.pb_changephoto,10,0,1,2)
136 self.buttonlayout = QHBoxLayout()
137 self.pb_cancel = QPushButton("&Cancel")
138 self.pb_save = QPushButton("&Save")
139 self.pb_saveclose = QPushButton("Save && Clos&e")
140 self.pb_reset = QPushButton("&Reset")
141 self.pb_save.setEnabled(False)
142 self.pb_saveclose.setEnabled(False)
143 self.pb_reset.setEnabled(False)
144 self.buttonlayout.addWidget(self.pb_reset)
145 self.buttonlayout.addWidget(self.pb_cancel)
146 self.buttonlayout.addWidget(self.pb_save)
147 self.buttonlayout.addWidget(self.pb_saveclose)
148 def setupActions(self):
149 # Update filtered table
150 QObject.connect(self.search_bar, SIGNAL("textChanged(QString)"), self.updateTable )
151 # Selecting a record loads it for editing
152 QObject.connect(self.tableview.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.selectionChanged )
153 # Map buttons to actions
154 QObject.connect(self.pb_reset, SIGNAL("clicked()"), self.resetPressed )
155 QObject.connect(self.pb_cancel, SIGNAL("clicked()"), self.closePressed )
156 QObject.connect(self.pb_saveclose, SIGNAL("clicked()"), self.saveClosePressed )
157 QObject.connect(self.pb_save, SIGNAL("clicked()"), self.savePressed )
158 QObject.connect(self.pb_changephoto, SIGNAL("clicked()"), self.changePhoto )
159 # Changes to the record enable buttons
160 QObject.connect(self.netid, SIGNAL("textEdited(QString)"), self.formChanged )
161 QObject.connect(self.firstname, SIGNAL("textEdited(QString)"), self.formChanged )
162 QObject.connect(self.surname, SIGNAL("textEdited(QString)"), self.formChanged )
163 QObject.connect(self.email, SIGNAL("textEdited(QString)"), self.formChanged )
164 QObject.connect(self.phone, SIGNAL("textEdited(QString)"), self.formChanged )
165 QObject.connect(self.major, SIGNAL("textEdited(QString)"), self.formChanged )
166 QObject.connect(self.room, SIGNAL("textEdited(QString)"), self.formChanged )
167 QObject.connect(self.year, SIGNAL("currentIndexChanged(int)"), self.formChanged )
168 QObject.connect(self.month, SIGNAL("currentIndexChanged(int)"), self.formChanged )
169 QObject.connect(self.day, SIGNAL("currentIndexChanged(int)"), self.formChanged )
170 QObject.connect(self.dorm, SIGNAL("currentIndexChanged(int)"), self.formChanged )
172 def formChanged(self):
173 # Do this only if a record has been selected
174 if not self.current_record.isEmpty():
175 self.pb_reset.setEnabled(True)
176 self.pb_save.setEnabled(True)
177 self.pb_saveclose.setEnabled(True)
178 def selectionChanged(self, selected, deselected):
179 items = selected.indexes()
181 self.current_row = items[0].row() # this is the row of the current selected item
182 self.current_record = self.model.record(items[0].row())
185 # Fill fields with data from selected record
186 self.netid.setText(self.current_record.field("netid").value().toString())
187 self.firstname.setText(self.current_record.field("forename").value().toString())
188 self.surname.setText(self.current_record.field("surname").value().toString())
189 self.email.setText(self.current_record.field("email").value().toString())
190 self.phone.setText(self.current_record.field("phone").value().toString())
191 self.major.setText(self.current_record.field("major").value().toString())
192 self.room.setText(self.current_record.field("room").value().toString())
193 bday = str(self.current_record.field("birthday").value().toString()).split("-")
194 self.year.setCurrentIndex(self.year.findText(bday[0]))
195 self.month.setCurrentIndex(int(bday[1]) - 1)
196 self.day.setCurrentIndex(int(bday[2]) - 1)
197 self.dorm.setCurrentIndex(self.dorm.findText(self.current_record.field("dorm").value().toString()))
198 self.pb_reset.setEnabled(False)
199 self.pb_save.setEnabled(False)
200 self.pb_saveclose.setEnabled(False)
201 ba = self.current_record.field("photo").value().toByteArray()
203 self.currentimage = QImage()
204 self.currentimage.loadFromData(ba)
205 self.displayimage = self.currentimage.scaled(self.photo.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
206 self.displaypixmap = QPixmap.fromImage(self.displayimage)
207 self.photo.setPixmap(self.displaypixmap)
209 self.photo.setText("No photo available")
210 self.pb_changephoto.setEnabled(True)
212 def updateTable(self, text):
214 self.model.setFilter("")
219 patterns = [] # can't use list comprehensions for this one because setValue returns void
221 f = QSqlField("input",QVariant.String)
222 f.setValue(QVariant(QString("%" + i + "%")))
224 escapedpatterns = [ self.model.database().driver().formatValue(wc, False) for wc in patterns]
225 filters = [ str(QString("(surname LIKE %1 OR forename LIKE %2)").arg(wc).arg(wc)) for wc in escapedpatterns]
226 filterString = " AND ".join(filters)
227 self.model.setFilter(QString(filterString))
229 if self.model.rowCount() == 1:
230 self.tableview.selectRow(0)
231 def resetPressed(self):
232 self.current_record = self.model.record(self.current_row)
234 self.pb_reset.setEnabled(False)
235 self.pb_save.setEnabled(False)
236 self.pb_saveclose.setEnabled(False)
237 print "Resetting form"
238 def closePressed(self):
240 self.model.revertAll()
241 # Wipe contents of all lineedits, destroy current_record and current_index
242 self.search_bar.clear()
243 self.current_record = QSqlRecord()
244 self.current_index = -1
246 self.firstname.clear()
251 self.year.setCurrentIndex(0)
252 self.month.setCurrentIndex(0)
253 self.day.setCurrentIndex(0)
254 self.dorm.setCurrentIndex(0)
256 self.photo.setText("No record selected")
258 self.emit(SIGNAL("done()"))
259 def savePressed(self):
261 self.current_record.setValue("netid",QVariant(self.netid.text()))
262 self.current_record.setValue("forename",QVariant(self.firstname.text()))
263 self.current_record.setValue("surname",QVariant(self.surname.text()))
264 self.current_record.setValue("email",QVariant(self.email.text()))
265 self.current_record.setValue("phone",QVariant(self.phone.text()))
266 self.current_record.setValue("major",QVariant(self.major.text()))
267 self.current_record.setValue("room",QVariant(self.room.text()))
268 self.current_record.setValue("dorm",QVariant(self.dorm.currentText()))
269 y = self.year.currentText().toInt()[0]
270 m = self.month.currentIndex() + 1
271 d = self.day.currentText().toInt()[0]
273 self.current_record.setValue("birthday", QVariant(bday.toString(Qt.ISODate)) )
274 self.current_record.setValue("mtime", QVariant(QDateTime.currentDateTime().toString(Qt.ISODate)) ) # update modification time
276 self.model.setRecord(self.current_row, self.current_record)
277 self.model.submitAll()
278 self.updateTable(self.search_bar.text()) # Reselect from the DB
279 self.pb_reset.setEnabled(False)
280 self.pb_save.setEnabled(False)
281 self.pb_saveclose.setEnabled(False)
282 def saveClosePressed(self):
285 def changePhoto(self):
286 fileName = QFileDialog.getOpenFileName(self, "Select Photo", ".", "Images (*.jpg *.png)" )
287 if not fileName.isEmpty():
288 print "opening", fileName
289 self.currentimage = QImage()
290 self.currentimage.load(fileName)
291 self.displayimage = self.currentimage.scaled(self.photo.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
292 self.displaypixmap = QPixmap.fromImage(self.displayimage)
293 self.photo.setPixmap(self.displaypixmap)
296 buffer.open(QIODevice.WriteOnly)
297 self.currentimage.save(buffer, "JPG")
299 self.current_record.setValue("photo",QVariant(ba))
300 self.pb_reset.setEnabled(True)
301 self.pb_save.setEnabled(True)
302 self.pb_saveclose.setEnabled(True)
305 if __name__ == "__main__":
306 a = QApplication([""])