PyQt4で作るRSSリーダー
調子に乗ってRSSリーダーを作ってみましたよ。
RSSの解析には以下のスクリプトを使用しました。
http://www.mnot.net/python/RSS.py
これ、そのままではWindows上で動かない。
signalモジュールが引っかかってしまうのだけど、
今回はあえなくコメントアウトに。
30行目付近でsignalを使っている部分をコメントアウト
#signal.signal(signal.SIGALRM, self._timeout) #signal.alarm(timeout) #try: p.parse(str(url)) # URIs are ascii #finally: #signal.alarm(0) return dh
RSSリーダーはやっぱ3ペインだよねーということで、
リストモデルも作ってしまった。
Qt4からは、ModelViewフレームワークがあるので、
結構楽チン。
from PyQt4 import QtCore, QtGui from RSS import ns, CollectionChannel, TrackingChannel import sys class Site: def __init__(self, name, url): self.name = name self.url = url self.fetched = False self.items = def listItems(self): if not self.fetched: tc = TrackingChannel() tc.parse(self.url) RSS10_TITLE = (ns.rss10, 'title') RSS10_DESC = (ns.rss10, 'description') items = tc.listItems() for item in items: item_data = tc.getItem(item) description = item_data.get(RSS10_DESC, "(none)") title = item_data.get(RSS10_TITLE, "(none)") self.items.append({'title':title, 'description':description}) self.fetched = True return self.items class SiteListModel (QtCore.QAbstractListModel): def __init__(self,parent=None): QtCore.QAbstractListModel.__init__(self, parent) self.sites = def addSite(self, site): self.sites.append(site) def removeSite(self, site): self.sites.remove(site) def rowCount(self, parentIndex): return len(self.sites) def data(self, index, role): if not index.isValid(): return QtCore.QVariant() if role == QtCore.Qt.DisplayRole: site = self.sites[index.row()] return QtCore.QVariant(site.name) return QtCore.QVariant() class SiteItemModel (QtCore.QAbstractListModel): def __init__(self, site, parent=None): QtCore.QAbstractListModel.__init__(self, parent) self.site = site self.site.listItems() def rowCount(self, parentIndex): return len(self.site.items) def data(self, index, role): if not index.isValid(): return QtCore.QVariant() if role == QtCore.Qt.DisplayRole: title = unicode(self.site.items[index.row()]["title"], 'utf-8') return QtCore.QVariant(title) return QtCore.QVariant() class MainWindow (QtGui.QMainWindow): def __init__(self, sites, parent=None): QtGui.QMainWindow.__init__(self, parent) self.mainSplitter = QtGui.QSplitter(QtCore.Qt.Vertical, self) self.splitter = QtGui.QSplitter(self.mainSplitter) self.mainSplitter.addWidget(self.splitter) self.rssView = QtGui.QTextEdit(self.mainSplitter) self.rssView.setReadOnly(True) self.mainSplitter.addWidget(self.rssView) self.setCentralWidget(self.mainSplitter) self.siteListModel = SiteListModel(self) self.siteListModel.sites = sites self.siteListView = QtGui.QListView(self.splitter) self.siteListView.setModel(self.siteListModel) self.rssListView = QtGui.QListView(self.splitter) self.splitter.addWidget(self.siteListView) self.splitter.addWidget(self.rssListView) self.connect(self.siteListView, QtCore.SIGNAL('activated(const QModelIndex &)'), self.siteSelected) self.connect(self.rssListView, QtCore.SIGNAL('activated(const QModelIndex &)'), self.rssSelected) def siteSelected(self, index): site = self.siteListModel.sites[index.row()] self.siteItemModel = SiteItemModel(site, self) self.rssListView.setModel(self.siteItemModel) def rssSelected(self, index): rss = self.siteItemModel.site.items[index.row()] self.rssView.setHtml(unicode(rss["description"], 'utf-8')) def main(): sites = [Site("vlog", "http://vlog.blog32.fc2.com/?xml"), Site("python language web", "http://www.python.org/channews.rdf")] app = QtGui.QApplication(sys.argv) win = MainWindow(sites) win.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
所要時間は1時間ちょい。