Rapid GUI Programming with Python and Qt

Slides:



Advertisements
Similar presentations
CC SQL Utilities.
Advertisements

Microsoft SQL Server 2008 From the Program menu choose: Microsoft SQL Server 2008 R2  SQL Server Management Studio. You may see a window indicating the.
Access - Project 1 l What Is a Database? –A Collection of Data –Organized in a manner to allow: »Access »Retrieval »Use of That Data.
NMED 3850 A Advanced Online Design February 25, 2010 V. Mahadevan.
Guide to Oracle10G1 Introduction To Forms Builder Chapter 5.
Maintenance Modifying the data –Add records –Delete records –Update records Modifying the design –Add fields into tables –Remove fields from a table –Change.
Manipulating MySQL Databases with PHP. PHP and mySQL2 Objectives Connect to MySQL from PHP Learn how to handle MySQL errors Execute SQL statements with.
Creating a Blank Database 1. Open up Microsoft Access 2. Click on Blank document button 3. On the right panel, Specify the location for saving your database.
Access Lecture 1 Database Overview and Creating Tables Create an Employee Table.
DAT702.  Standard Query Language  Ability to access and manipulate databases ◦ Retrieve data ◦ Insert, delete, update records ◦ Create and set permissions.
Phil Brewster  One of the first steps – identify the proper data types  Decide how data (in columns) should be stored and used.
Introduction To Databases IDIA 618 Fall 2014 Bridget M. Blodgett.
DAY 21: MICROSOFT ACCESS – CHAPTER 5 MICROSOFT ACCESS – CHAPTER 6 MICROSOFT ACCESS – CHAPTER 7 Akhila Kondai October 30, 2013.
MySql In Action Step by step method to create your own database.
Advance Computer Programming Java Database Connectivity (JDBC) – In order to connect a Java application to a database, you need to use a JDBC driver. –
PHP1-1 PHP & SQL Xingquan (Hill) Zhu
Microsoft Access Intro Class 1 Database Concepts.
A Guide to SQL, Eighth Edition Chapter Three Creating Tables.
Module 3: Table Selection
Session 5: Working with MySQL iNET Academy Open Source Web Development.
1 Chapter 8 – Working with Databases spring into PHP 5 by Steven Holzner Slides were developed by Jack Davis College of Information Science and Technology.
Database Systems Marcus Kaiser School of Computing Science Newcastle University.
Advanced Database Management System Lab no. 11. SQL Commands (for MySQL) –Update –Replace –Delete.
Chapter 7 PHP Interacts with Ms. Access (Open DataBase Connectivity (ODBC))
Copyright © 2003 Pearson Education, Inc. Slide 8-1 The Web Wizard’s Guide to PHP by David Lash.
PHP Programming with MySQL Slide 8-1 CHAPTER 8 Working with Databases and MySQL.
Web Application Development. Define ER model in QSEE Generate SQL Create Database mySQL Write Script to use TableEditor class Process to create A simple.
Web Application Development. Tools to create a simple web- editable database QSEE MySQL (or PHPMyAdmin) PHP TableEditor.
1 PHP and MySQL. 2 Topics  Querying Data with PHP  User-Driven Querying  Writing Data with PHP and MySQL PHP and MySQL.
Data-mining & Data As we used Excel that has capability to analyze data to find important information, the data-mining helps us to extract information.
Mr. Justin “JET” Turner CSCI 3000 – Fall 2015 CRN Section A – TR 9:30-10:45 CRN – Section B – TR 5:30-6:45.
Copyright © 2007, Oracle. All rights reserved. Managing Concurrent Requests.
PHP meets MySQL.
 A database is a collection of data that is organized so that its contents can easily be accessed, managed, and updated. What is Database?
INFO 344 Web Tools And Development CK Wang University of Washington Spring 2014.
Chapter 7 Working with Databases and MySQL PHP Programming with MySQL 2 nd Edition.
1 Working with MS SQL Server Textbook Chapter 14.
© FPT SOFTWARE – TRAINING MATERIAL – Internal use 04e-BM/NS/HDCV/FSOFT v2/3 Working with MSSQL Server Code:G0-C# Version: 1.0 Author: Pham Trung Hai CTD.
Lesson 2.  To help ensure accurate data, rules that check entries against specified values can be applied to a field. A validation rule is applied to.
SQL pepper. Why SQL File I/O is a great deal of code Optimal file organization and indexing is critical and a great deal of code and theory implementation.
15/10/20151 PHP & MySQL 'Slide materials are based on W3Schools PHP tutorial, 'PHP website 'MySQL website.
Introduction to MySQL Lab no. 10 Advance Database Management System.
PHP MySQL Introduction. MySQL is the most popular open-source database system. What is MySQL? MySQL is a database. The data in MySQL is stored in database.
Web Scripting [PHP] CIS166AE Wednesdays 6:00pm – 9:50pm Rob Loy.
DAY 12: DATABASE CONCEPT Tazin Afrin September 26,
Database Systems Microsoft Access Practical #1 Creating Tables Nos 215.
M1G Introduction to Database Development 2. Creating a Database.
1 Database Systems Introduction to Microsoft Access Part 2.
Database Fundamental & Design by A.Surasit Samaisut Copyrights : All Rights Reserved.
Visual Programing SQL Overview Section 1.
3 Copyright © 2004, Oracle. All rights reserved. Working in the Forms Developer Environment.
DATABASE CONNECTIVITY TO MYSQL. Introduction =>A real life application needs to manipulate data stored in a Database. =>A database is a collection of.
Pasewark & Pasewark Microsoft Office 2003: Introductory 1 INTRODUCTORY MICROSOFT ACCESS Lesson 4 – Finding and Ordering Data.
Lesson 4.  After a table has been created, you may need to modify it. You can make many changes to a table—or other database object—using its property.
Task #1 Create a relational database on computers in computer classroom 308, using MySQL server and any client. Create the same database, using MS Access.
Chapter 8 Manipulating MySQL Databases with PHP PHP Programming with MySQL 2 nd Edition.
Session 1 Module 1: Introduction to Data Integrity
MICROSOFT ACCESS – CHAPTER 5 MICROSOFT ACCESS – CHAPTER 6 MICROSOFT ACCESS – CHAPTER 7 Sravanthi Lakkimsety Mar 14,2016.
Introduction to Databases & SQL Ahmet Sacan. What you’ll need Firefox, SQLite plugin Mirdb and Targetscan databases.
Introduction to Database Programming with Python Gary Stewart
DAY 20: ACCESS CHAPTERS 5, 6, 7 Larry Reaves October 28,
2 Copyright © 2008, Oracle. All rights reserved. Building the Physical Layer of a Repository.
Chapter 12 Introducing Databases. Objectives What a database is and which databases are typically used with ASP.NET pages What SQL is, how it looks, and.
CS320 Web and Internet Programming SQL and MySQL
Database Keys and Constraints
Storing Images Connect to the server using the correct username and password. $conn = mysql_connect(“yourserver”, “joeuser”, “yourpass”); Create the database.
ISC440: Web Programming 2 Server-side Scripting PHP 3
CS3220 Web and Internet Programming SQL and MySQL
CS3220 Web and Internet Programming SQL and MySQL
Presentation transcript:

Rapid GUI Programming with Python and Qt Databases By Raed S. Rasheed

Databases PyQt provides a consistent cross-platform API for database access using the QtSql module and PyQt’s model/view architecture. Python also has its own completely different database API, called DB-API, but it isn’t needed with PyQt and is not covered here. The commercial edition of Qt comes with many database drivers, whereas the GPL edition has fewer due to licensing restrictions. The drivers that are available include ones for IBM’s DB2, Borland’s Interbase, MySQL, Oracle, ODBC (for Microsoft SQL Server), PostgreSQL, SQLite, and Sybase. However, like any aspect of PyQt, it is possible to create additional database drivers if one we need is not available.

Connecting to the Database To use PyQt’s SQL classes we must import the QtSql module: from PyQt4.QtSql import * A database connection is established by calling the static QSqlDatabase.addDatabase() method, with the name of the driver we want to use. Then we must set various attributes, such as the database’s name, the username, and the password. And finally, we must call open() to make the connection.

Connecting to the Database db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(filename) if not db.open(): QMessageBox.warning(None, "Phone Log", QString("Database Error: %1").arg(db.lastError().text())) sys.exit(1)

Executing SQL Queries query = QSqlQuery() query.exec_("""CREATE TABLE outcomes ( id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, name VARCHAR(40) NOT NULL)""")

Executing SQL Queries query.exec_("""CREATE TABLE calls ( id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, caller VARCHAR(40) NOT NULL, starttime DATETIME NOT NULL, endtime DATETIME NOT NULL, topic VARCHAR(80) NOT NULL, outcomeid INTEGER NOT NULL, FOREIGN KEY (outcomeid) REFERENCES outcomes)""")

The Phone Log database design Executing SQL Queries The Phone Log database design

Executing SQL Queries Now that we have created the tables, we can populate them with data. for name in ("Resolved", "Unresolved", "Calling back", "Escalate", "Wrong number"): query.exec_("INSERT INTO outcomes (name) VALUES ('%s')" % name)

Executing SQL Queries query.prepare("INSERT INTO calls (caller, starttime, endtime, " "topic, outcomeid) VALUES (?, ?, ?, ?, ?)") for name, start, end, topic, outcomeid in data: query.addBindValue(QVariant(QString(name))) query.addBindValue(QVariant(start)) # QDateTime query.addBindValue(QVariant(end)) # QDateTime query.addBindValue(QVariant(QString(topic))) query.addBindValue(QVariant(outcomeid)) # int query.exec_()

Executing SQL Queries We can use QSqlQuery to execute any arbitrary SQL statement. For example: query.exec_("DELETE FROM calls WHERE id = 12")

Executing SQL Queries We will conclude our coverage of QSqlQuery by looking at how to use it to execute SELECT statements, and how to iterate over the resultant records. DATETIME_FORMAT = "yyyy-MM-dd hh:mm" ID, CALLER, STARTTIME, ENDTIME, TOPIC, OUTCOMEID = range(6) query.exec_("SELECT id, caller, starttime, endtime, topic, " "outcomeid FROM calls ORDER by starttime")

Executing SQL Queries while query.next(): id = query.value(ID).toInt()[0] caller = unicode(query.value(CALLER).toString()) starttime = unicode(query.value(STARTTIME).toDateTime() \ .toString(DATETIME_FORMAT)) endtime = unicode(query.value(ENDTIME).toDateTime() \ topic = unicode(query.value(TOPIC).toString())

Executing SQL Queries outcomeid = query.value(OUTCOMEID).toInt()[0] subquery = QSqlQuery("SELECT name FROM outcomes " "WHERE id = %d" % outcomeid) outcome = "invalid foreign key" if subquery.next(): outcome = unicode(subquery.value(0).toString()) print "%02d: %s %s - %s %s [%s]" % (id, caller, starttime, endtime, topic, outcome)

Using Database Form Views The simplified Phone Log application

Using Database Form Views With the widgets in place, we create a QSqlTableModel. Since we did not specify a particular database connection, it uses the default one. We tell the model which able it is to work on and call select() to make it populate itself with data. We also choose to apply a sort order to the table. self.model = QSqlTableModel(self) self.model.setTable("calls") self.model.setSort(STARTTIME, Qt.AscendingOrder) self.model.select()

Using Database Form Views Now that we have suitable widgets and a model, we must somehow link them together. This is achieved by using a QDataWidgetMapper.. self.mapper = QDataWidgetMapper(self) self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self.mapper.setModel(self.model) self.mapper.addMapping(self.callerEdit, CALLER) self.mapper.addMapping(self.startDateTime, STARTTIME) self.mapper.addMapping(self.endDateTime, ENDTIME) self.mapper.addMapping(topicEdit, TOPIC) self.mapper.toFirst()

Using Database Form Views If the user navigates, we must remember the current row, since it is forgotten after calling submit(). Then, after saving the current record, we set the row to be the one appropriate for the navigation the user requested (but kept within bounds), and then use setCurrentIndex() to move to the appropriate record.

Using Database Form Views def saveRecord(self, where): row = self.mapper.currentIndex() self.mapper.submit() if where == PhoneLogDlg.FIRST: row = 0 elif where == PhoneLogDlg.PREV: row = 0 if row <= 1 else row - 1 elif where == PhoneLogDlg.NEXT:

Using Database Form Views row += 1 if row >= self.model.rowCount(): row = self.model.rowCount() - 1 elif where == PhoneLogDlg.LAST: self.mapper.setCurrentIndex(row)

Using Database Form Views row += 1 if row >= self.model.rowCount(): row = self.model.rowCount() - 1 elif where == PhoneLogDlg.LAST: self.mapper.setCurrentIndex(row)

Using Database Form Views We have chosen to always add new records at the end. To do this we find the row after the last one, save the current record, and then insert a new record at the last row in the model. Then we set the mapper’s current index to the new row, initialize a couple of fields, and give the caller field the focus, ready for the user to start typing.

Using Database Form Views def addRecord(self): row = self.model.rowCount() self.mapper.submit() self.model.insertRow(row) self.mapper.setCurrentIndex(row) now = QDateTime.currentDateTime() self.startDateTime.setDateTime(now) self.endDateTime.setDateTime(now) self.callerEdit.setFocus()

Using Database Form Views If the user clicks Delete we pick out some information from the current record and use it when we ask the user to confirm the deletion. If they confirm, we retrieve the current row, remove the row from the model, and call submitAll() to force the model to write back the change to the underlying data source (in this case the database). Then we finish up by navigating to the next record.

Using Database Form Views def deleteRecord(self): caller = self.callerEdit.text() starttime = self.startDateTime.dateTime().toString(DATETIME_FORMAT) if QMessageBox.question(self,QString("Delete"),QString("Delete call made by<br>%1 on %2?").arg(caller).arg(starttime),QMessageBox.Yes|QMessageBox.No) == QMessageBox.No: return row = self.mapper.currentIndex() self.model.removeRow(row) self.model.submitAll() if row + 1 >= self.model.rowCount(): row = self.model.rowCount() - 1 self.mapper.setCurrentIndex(row)

Using Database Table Views Probably the most natural and convenient way to present database data is to show database tables and views in GUI tables. This allows users to see many records at once, and it is particularly convenient for showing master–detail relationships. The Asset Manager database design

Using Database Table Views Probably the most natural and convenient way to present database data is to show database tables and views in GUI tables. This allows users to see many records at once, and it is particularly convenient for showing master–detail relationships.

Using Database Table Views The Asset Manager database design

Using Database Table Views class MainForm(QDialog): def __init__(self): super(MainForm, self).__init__() self.assetModel = QSqlRelationalTableModel(self) self.assetModel.setTable("assets") self.assetModel.setRelation(CATEGORYID,QSqlRelation("categories", "id", "name")) self.assetModel.setSort(ROOM, Qt.AscendingOrder) self.assetModel.setHeaderData(ID, Qt.Horizontal,QVariant("ID")) self.assetModel.setHeaderData(NAME, Qt.Horizontal,QVariant("Name")) self.assetModel.setHeaderData(CATEGORYID, Qt.Horizontal,QVariant("Category")) self.assetModel.setHeaderData(ROOM, Qt.Horizontal,QVariant("Room")) self.assetModel.select()

Using Database Table Views The view is a standard QTableView, but instead of setting a QSqlRelationalDelegate, we have set a custom delegate. We will detour to look at this in a moment. The selection mode is set so that users can navigate to individual fields; the selection behavior is that the row that has the focus is highlighted. We don’t want to show the ID field since it isn’t meaningful to the user, so we hide it.

Using Database Table Views self.assetView = QTableView() self.assetView.setModel(self.assetModel) self.assetView.setItemDelegate(AssetDelegate(self)) self.assetView.setSelectionMode(QTableView.SingleSelection) self.assetView.setSelectionBehavior(QTableView.SelectRows) self.assetView.setColumnHidden(ID, True) self.assetView.resizeColumnsToContents()

Using Database Table Views The heart of the createEditor() method is the code that sets up the QLineEdit for entering room numbers. Room numbers are four digits long, made up of a floor number, in the range 01–27 (but excluding 13), and a room number on the floor in the range 01–62. For example, 0231 is floor 2, room 31, but 0364 is invalid. The regular expression is sufficient for specifying valid room numbers, but it cannot set a minimum number of digits, since one, two, or three digits may be a valid prefix for a valid four digit room number. We have solved this by using an input mask that requires exactly four digits to be entered. For the other fields, we pass the work on to the base class.

Using Database Table Views def createEditor(self, parent, option, index): if index.column() == ROOM: editor = QLineEdit(parent) regex = QRegExp(r"(?:0[1-9]|1[0124-9]|2[0-7])“ r"(?:0[1-9]|[1-5][0-9]|6[012])") validator = QRegExpValidator(regex, parent) editor.setValidator(validator) editor.setInputMask("9999") editor.setAlignment(Qt.AlignRight|Qt.AlignVCenter) return editor else: return QSqlRelationalDelegate.createEditor(self, parent,option, index)

Using Database Table Views The code for creating the log model is almost the same as the code we used for the asset model. We use a QSqlRelationalTableModel because we have a foreign key field, and we provide our own column titles. self.logModel = QSqlRelationalTableModel(self) self.logModel.setTable("logs") self.logModel.setRelation(ACTIONID,QSqlRelation("actions", "id", "name")) self.logModel.setSort(DATE, Qt.AscendingOrder) self.logModel.setHeaderData(DATE, Qt.Horizontal,QVariant("Date")) self.logModel.setHeaderData(ACTIONID, Qt.Horizontal,QVariant("Action")) self.logModel.select()

Using Database Table Views self.logView = QTableView() self.logView.setModel(self.logModel) self.logView.setItemDelegate(LogDelegate(self)) self.logView.setSelectionMode(QTableView.SingleSelection) self.logView.setSelectionBehavior(QTableView.SelectRows) self.logView.setColumnHidden(ID, True) self.logView.setColumnHidden(ASSETID, True) self.logView.resizeColumnsToContents() self.logView.horizontalHeader().setStretchLastSection(True)