From 838be31a8f4acb994f2e141873188a0f4b959178 Mon Sep 17 00:00:00 2001 From: Florian Schweikert Date: Wed, 14 Mar 2012 22:32:18 +0100 Subject: [PATCH] replaced get_departures with DataModel in pyside --- gotovienna-qml | 121 ++++++++++++++++++++++-------------------------- gotovienna/realtime.py | 8 +++- qml/ResultRealtime.qml | 23 +++------ 3 files changed, 67 insertions(+), 85 deletions(-) diff --git a/gotovienna-qml b/gotovienna-qml index d2dc8fa..033f537 100755 --- a/gotovienna-qml +++ b/gotovienna-qml @@ -9,8 +9,8 @@ __license__ = 'GNU General Public License v3 or later' from datetime import datetime -from PySide.QtCore import QAbstractListModel, QModelIndex, QObject, Slot, Signal -from PySide.QtGui import QApplication +from PySide.QtCore import QAbstractListModel, QModelIndex, QObject, Slot, Signal, Qt +from PySide.QtGui import QApplication, QTextItem from PySide.QtDeclarative import QDeclarativeView from gotovienna.utils import * @@ -81,38 +81,53 @@ class AboutInfo(QObject): def getLicense(self): return __license__ -class GotoViennaListModel(QAbstractListModel): - def __init__(self, objects=None): - QAbstractListModel.__init__(self) - if objects is None: - objects = [] - self._objects = objects - self.setRoleNames({0: 'modelData'}) - - def set_objects(self, objects): - self._objects = objects - - def get_objects(self): - return self._objects - - def get_object(self, index): - return self._objects[index.row()] - - def rowCount(self, parent=QModelIndex()): - return len(self._objects) +class DepartureModel(QAbstractListModel): + LINE_ROLE = Qt.UserRole + 1 + DIRECTION_ROLE = Qt.UserRole + 2 + STATION_ROLE = Qt.UserRole + 3 + TIME_ROLE = Qt.UserRole + 4 + LOWFLOOR_ROLE = Qt.UserRole + 5 + + def __init__(self, parent=None): + super(DepartureModel, self).__init__(parent) + self._data = [] + + self.keys = {} + self.keys[DepartureModel.LINE_ROLE] = 'line' + self.keys[DepartureModel.DIRECTION_ROLE] = 'direction' + self.keys[DepartureModel.STATION_ROLE] = 'station' + self.keys[DepartureModel.TIME_ROLE] = 'time' + self.keys[DepartureModel.LOWFLOOR_ROLE] = 'lowfloor' + self.setRoleNames(self.keys) + + def rowCount(self, index): + return len(self._data) def data(self, index, role): - if index.isValid(): - if role == 0: - return self.get_object(index) - return None - + if not index.isValid(): + return None + + if index.row() > len(self._data): + return None + + departure = self._data[index.row()] + + if self.keys.has_key(role): + return departure[self.keys[role]] + else: + return None + + def setDepartures(self, dep): + self.beginResetModel() + self._data = dep + self.endResetModel() class Gui(QObject): - def __init__(self): + def __init__(self, depModel): QObject.__init__(self) self.itip = ITipParser() self.lines = [] + self.departureModel = depModel # Read line names in categorized/sorted order for _, lines in categorize_lines(self.itip.lines): @@ -150,13 +165,13 @@ class Gui(QObject): threading.Thread(target=load_async).start() - def map_departure(self, dep): - """ prepare departure list for qml gui - """ - dep['lowfloor'] = 1 if dep['lowfloor'] else 0 - dep['realtime'] = 1 if dep['realtime'] else 0 - dep['time'] = dep['ftime'] - return dep + #def map_departure(self, dep): + # """ prepare departure list for qml gui + # """ + # dep['lowfloor'] = 1 if dep['lowfloor'] else 0 + # dep['realtime'] = 1 if dep['realtime'] else 0 + # dep['time'] = dep['ftime'] + # return dep departuresLoaded = Signal() @@ -184,8 +199,7 @@ class Gui(QObject): @Slot(str) def load_departures(self, url): def load_async(): - self.current_departures = map(self.map_departure, \ - self.itip.get_departures(url)) + self.departureModel.setDepartures(self.itip.get_departures(url)) #print self.current_departures self.departuresLoaded.emit() @@ -194,9 +208,7 @@ class Gui(QObject): @Slot(str) def load_station_departures(self, station): def load_async(): - self.current_departures = map(self.map_departure, \ - sort_departures(self.itip.get_departures_by_station(station))) - #print self.current_departures + self.departureModel.setDepartures(sort_departures(self.itip.get_departures_by_station(station))) self.departuresLoaded.emit() threading.Thread(target=load_async).start() @@ -233,10 +245,6 @@ class Gui(QObject): def get_lines(self): return self.lines - @Slot(result='QVariant') - def get_departures(self): - return self.current_departures - @Slot(float, float, result='QStringList') def get_nearby_stations(self, lat, lon): try: @@ -245,27 +253,6 @@ class Gui(QObject): # No/wrong stations.db file return [] - @Slot(str, str) - def search(self, line, station): - line = line.upper() - station = station.decode('utf-8') - print line, station - - if line not in self.lines: - return "Invalid line" - - try: - stations = sorted(self.itip.get_stations(line).items()) - print stations - headers, stations = zip(*stations) - print headers - print stations - details = [(direction, name, url) for direction, stops in stations - for name, url in stops if match_station(station, name)] - print details - except urllib2.URLError as e: - print e.message - return e.message if __name__ == '__main__': app = QApplication(sys.argv) @@ -274,16 +261,18 @@ if __name__ == '__main__': aboutInfo = AboutInfo() config = Config() + departureModel = DepartureModel() # instantiate the Python object - itip = Gui() + itip = Gui(departureModel) # expose the object to QML context = view.rootContext() context.setContextProperty('itip', itip) context.setContextProperty('aboutInfo', aboutInfo) context.setContextProperty('config', config) - + context.setContextProperty('resultModel', departureModel) + if os.path.abspath(__file__).startswith('/usr/bin/'): # Assume system-wide installation, QML from /usr/share/ view.setSource('/usr/share/gotovienna/qml/main.qml') diff --git a/gotovienna/realtime.py b/gotovienna/realtime.py index ad43db2..a7ccde2 100644 --- a/gotovienna/realtime.py +++ b/gotovienna/realtime.py @@ -194,8 +194,12 @@ class ITipParser: if msg and len(msg) > 0 and unicode(msg[0].text).find(u'technischen St') > 0: print '\n'.join(map(lambda x: x.text.replace(' ', ''), msg)) return [] - - lines = bs.find('form', {'name': 'mainform'}).table.findAll('tr')[1] + + mainform = bs.find('form', {'name': 'mainform'}) + if not mainform: + return [] + + lines = mainform.table.findAll('tr')[1] if len(lines.findAll('td', {'class': 'info'})) > 0: station = lines.span.text.replace(' ', '') diff --git a/qml/ResultRealtime.qml b/qml/ResultRealtime.qml index 1ec034a..c5a1c4f 100644 --- a/qml/ResultRealtime.qml +++ b/qml/ResultRealtime.qml @@ -42,15 +42,6 @@ Item { onDeparturesLoaded: { busy = false - departuresModel.clear() - - var departures = itip.get_departures() - - for (var d in departures) { - console.log('time: ' + departures[d].time) - var row = {'line': departures[d].line, 'station': departures[d].station, 'destination': departures[d].direction, 'departure': departures[d].time, 'lowfloor': departures[d].lowfloor} - departuresModel.append(row) - } } } @@ -75,7 +66,7 @@ Item { spacing: 10 Text { id: l - text: line // <---- + text: model.line // <---- anchors.verticalCenter: parent.verticalCenter //width: 70 font.pixelSize: UIConstants.FONT_XLARGE @@ -89,7 +80,7 @@ Item { Text { id: s - text: station // <---- + text: model.station // <---- width: parent.parent.parent.width - l.width - dep.width - 15 elide: Text.ElideRight font.pixelSize: UIConstants.FONT_LARGE @@ -99,7 +90,7 @@ Item { Text { id: d - text: destination // <---- + text: model.direction // <---- width: parent.parent.parent.width - l.width - dep.width - 15 elide: Text.ElideRight color: !theme.inverted ? UIConstants.COLOR_SECONDARY_FOREGROUND : UIConstants.COLOR_INVERTED_SECONDARY_FOREGROUND @@ -116,10 +107,10 @@ Item { Text { id: dep // FIXME strange int float transformation appears - text: departure + text: model.time anchors.right: parent.right anchors.rightMargin: UIConstants.DEFAULT_MARGIN - font.italic: lowfloor == 1 + font.italic: lowfloor font.bold: true font.pixelSize: UIConstants.FONT_XLARGE font.family: ExtrasConstants.FONT_FAMILY_LIGHT @@ -166,9 +157,7 @@ Item { } } - model: ListModel { - id: departuresModel - } + model: resultModel delegate: departureDelegate visible: !resultRealtime.busy && isCorrectInput() -- 1.7.9.5