class BackGround: """ class that provides a timer that checks on background processes, and method for adding new background workers. all workers should provide following methods: ui(),bg() """ def __init__(self): self.workers = {} self.checkTimer = QTimer() self.checkTimer.connect(self.checkTimer, SIGNAL("timeout()"), self.check) self.checkTimer.start(500) def check(self): for worker in self.workers.keys(): if not self.workers[worker].THREAD.isAlive(): self.workers[worker].ui() if self.workers[worker].SENDER: self.workers[worker].SENDER.setEnabled(True) del self.workers[worker] else: self.workers[worker].status() def add(self, worker, sender=None): if self.workers.has_key(str(worker)): # only add unique workers! return False worker.THREAD = Thread(args = [worker], target = worker.bg) worker.THREAD.start() if sender: sender.setEnabled(False) worker.SENDER = sender self.workers[str(worker)] = worker return True
class BackGround: """ class that provides a timer that checks on background processes, and method for adding new background workers. all workers should provide following methods: ui(),bg() """ def __init__(self): self.workers = {} self.checkTimer = QTimer() self.checkTimer.connect(self.checkTimer, SIGNAL("timeout()"), self.check) self.checkTimer.start(500) def check(self): for worker in self.workers.keys(): if not self.workers[worker].THREAD.isAlive(): self.workers[worker].ui() if self.workers[worker].SENDER: self.workers[worker].SENDER.setEnabled(True) del self.workers[worker] else: self.workers[worker].status() def add(self, worker, sender=None): if self.workers.has_key(str(worker)): # only add unique workers! return False worker.THREAD = Thread(args=[worker], target=worker.bg) worker.THREAD.start() if sender: sender.setEnabled(False) worker.SENDER = sender self.workers[str(worker)] = worker return True
class updateCheckWorker: """ class that provides new version checking in background """ def __init__(self, notifier): from pyqlogger import VERSION self.notifier = notifier self.notified = LooseVersion(VERSION) self.Timer = QTimer() self.Timer.connect(self.Timer, SIGNAL("timeout()"), self.work) self.Timer.start(60*60*1000) def work(self): try: req = urllib2.urlopen('http://pyqlogger.berlios.de/ver.php') line = req.readline() newver = LooseVersion( line.strip() ) if newver > self.notified : self.notified = newver self.notifier.info("New version %s is available at the site!"%(str(newver))) except: pass
class updateCheckWorker: """ class that provides new version checking in background """ def __init__(self, notifier): from pyqlogger import VERSION self.notifier = notifier self.notified = LooseVersion(VERSION) self.Timer = QTimer() self.Timer.connect(self.Timer, SIGNAL("timeout()"), self.work) self.Timer.start(60 * 60 * 1000) def work(self): try: req = urllib2.urlopen('http://pyqlogger.berlios.de/ver.php') line = req.readline() newver = LooseVersion(line.strip()) if newver > self.notified: self.notified = newver self.notifier.info("New version %s is available at the site!" % (str(newver))) except: pass
class qSlicerMultiVolumeExplorerSimplifiedModuleWidget: def __init__(self, parent=None): logging.debug( "qSlicerMultiVolumeExplorerSimplifiedModuleWidget:init() called") if not parent or not hasattr(parent, "layout"): self.parent = slicer.qMRMLWidget() self.parent.setLayout(QVBoxLayout()) else: self.parent = parent self.layout = self.parent.layout() self._bgMultiVolumeNode = None self._fgMultiVolumeNode = None self.styleObserverTags = [] self.sliceWidgetsPerStyle = {} self.chartPopupWindow = None self.chartPopupSize = QSize(600, 300) self.chartPopupPosition = QPoint(0, 0) def hide(self): self.widget.hide() def show(self): self.widget.show() def setup(self): self.widget = QWidget() layout = QGridLayout() self.widget.setLayout(layout) self.layout.addWidget(self.widget) self.widget.show() self.layout = layout self.setupInputFrame() self.setupFrameControlFrame() self.setupAdditionalFrames() self.setupPlottingFrame() self.setFramesEnabled(False) self.timer = QTimer() self.timer.setInterval(50) self.setupConnections() # initialize slice observers (from DataProbe.py) # keep list of pairs: [observee,tag] so they can be removed easily self.styleObserverTags = [] # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic self.sliceWidgetsPerStyle = {} self.refreshObservers() def setupInputFrame(self, parent=None): if not parent: parent = self.layout self.bgMultiVolumeSelector = slicer.qMRMLNodeComboBox() self.bgMultiVolumeSelector.nodeTypes = ['vtkMRMLMultiVolumeNode'] self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene) self.bgMultiVolumeSelector.addEnabled = 0 self._bgMultiVolumeSelectorLabel = QLabel('Input multivolume') inputFrameWidget = QWidget() self.inputFrameLayout = QFormLayout() inputFrameWidget.setLayout(self.inputFrameLayout) self.inputFrameLayout.addRow(self._bgMultiVolumeSelectorLabel, self.bgMultiVolumeSelector) parent.addWidget(inputFrameWidget) def setupFrameControlFrame(self): # TODO: initialize the slider based on the contents of the labels array self.frameSlider = ctk.ctkSliderWidget() self.frameSlider.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.frameLabel = QLabel('Current frame number') self.playButton = QPushButton('Play') self.playButton.toolTip = 'Iterate over multivolume frames' self.playButton.checkable = True frameControlHBox = QHBoxLayout() frameControlHBox.addWidget(self.frameLabel) frameControlHBox.addWidget(self.frameSlider) frameControlHBox.addWidget(self.playButton) self.inputFrameLayout.addRow(frameControlHBox) def setupAdditionalFrames(self): pass def setupPlottingFrame(self, parent=None): if not parent: parent = self.layout self.plottingFrameWidget = QWidget() self.plottingFrameLayout = QGridLayout() self.plottingFrameWidget.setLayout(self.plottingFrameLayout) self._multiVolumeIntensityChart = MultiVolumeIntensityChartView() self.popupChartButton = QPushButton("Undock chart") self.popupChartButton.setCheckable(True) self.plottingFrameLayout.addWidget( self._multiVolumeIntensityChart.chartView) self.plottingFrameLayout.addWidget(self.popupChartButton) parent.addWidget(self.plottingFrameWidget) def setupConnections(self): self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged) self.bgMultiVolumeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onBackgroundInputChanged) self.playButton.connect('toggled(bool)', self.onPlayButtonToggled) self.frameSlider.connect('valueChanged(double)', self.onSliderChanged) self.timer.connect('timeout()', self.goToNext) self.popupChartButton.connect('toggled(bool)', self.onDockChartViewToggled) def onDockChartViewToggled(self, checked): if checked: self.chartPopupWindow = QDialog() self.chartPopupWindow.setWindowFlags( PythonQt.QtCore.Qt.WindowStaysOnTopHint) layout = QGridLayout() self.chartPopupWindow.setLayout(layout) layout.addWidget(self._multiVolumeIntensityChart.chartView) layout.addWidget(self.popupChartButton) self.chartPopupWindow.finished.connect(self.dockChartView) self.chartPopupWindow.resize(self.chartPopupSize) self.chartPopupWindow.move(self.chartPopupPosition) self.chartPopupWindow.show() self.popupChartButton.setText("Dock chart") self._multiVolumeIntensityChart.chartView.show() else: self.chartPopupWindow.close() def dockChartView(self): self.chartPopupSize = self.chartPopupWindow.size self.chartPopupPosition = self.chartPopupWindow.pos self.plottingFrameLayout.addWidget( self._multiVolumeIntensityChart.chartView) self.plottingFrameLayout.addWidget(self.popupChartButton) self.popupChartButton.setText("Undock chart") self.popupChartButton.disconnect('toggled(bool)', self.onDockChartViewToggled) self.popupChartButton.checked = False self.popupChartButton.connect('toggled(bool)', self.onDockChartViewToggled) def onSliderChanged(self, frameId): if self._bgMultiVolumeNode is None: return newValue = int(frameId) self.setCurrentFrameNumber(newValue) def onVCMRMLSceneChanged(self, mrmlScene): logging.debug( "qSlicerMultiVolumeExplorerSimplifiedModuleWidget:onVCMRMLSceneChanged" ) self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene) self.onBackgroundInputChanged() def refreshGUIForNewBackgroundImage(self): self._multiVolumeIntensityChart.reset() self.setFramesEnabled(True) if self._fgMultiVolumeNode and self._bgMultiVolumeNode: Helper.SetBgFgVolumes(self._bgMultiVolumeNode.GetID(), self._fgMultiVolumeNode.GetID()) else: Helper.SetBgVolume(self._bgMultiVolumeNode.GetID()) self.refreshFrameSlider() self._multiVolumeIntensityChart.bgMultiVolumeNode = self._bgMultiVolumeNode self.refreshObservers() def getBackgroundMultiVolumeNode(self): return self.bgMultiVolumeSelector.currentNode() def onBackgroundInputChanged(self): self._bgMultiVolumeNode = self.getBackgroundMultiVolumeNode() if self._bgMultiVolumeNode is not None: self.refreshGUIForNewBackgroundImage() else: self.setFramesEnabled(False) def onPlayButtonToggled(self, checked): if self._bgMultiVolumeNode is None: return if checked: self.timer.start() self.playButton.text = 'Stop' else: self.timer.stop() self.playButton.text = 'Play' def processEvent(self, observee, event): # logging.debug("processing event %s" % event) if self._bgMultiVolumeNode is None: return # TODO: use a timer to delay calculation and compress events if event == 'LeaveEvent': # reset all the readouts # TODO: reset the label text return if not self.sliceWidgetsPerStyle.has_key(observee): return interactor = observee.GetInteractor() self.createChart(self.sliceWidgetsPerStyle[observee], interactor.GetEventPosition()) def createChart(self, sliceWidget, position): self._multiVolumeIntensityChart.createChart(sliceWidget, position) def setCurrentFrameNumber(self, frameNumber): mvDisplayNode = self._bgMultiVolumeNode.GetDisplayNode() mvDisplayNode.SetFrameComponent(frameNumber) def setFramesEnabled(self, enabled): pass def refreshObservers(self): """ When the layout changes, drop the observers from all the old widgets and create new observers for the newly created widgets""" self.removeObservers() # get new slice nodes layoutManager = slicer.app.layoutManager() sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass( 'vtkMRMLSliceNode') for nodeIndex in xrange(sliceNodeCount): # find the widget for each node in scene sliceNode = slicer.mrmlScene.GetNthNodeByClass( nodeIndex, 'vtkMRMLSliceNode') sliceWidget = layoutManager.sliceWidget(sliceNode.GetLayoutName()) if sliceWidget: # add observers and keep track of tags style = sliceWidget.sliceView().interactorStyle() self.sliceWidgetsPerStyle[style] = sliceWidget events = ("MouseMoveEvent", "EnterEvent", "LeaveEvent") for event in events: tag = style.AddObserver(event, self.processEvent) self.styleObserverTags.append([style, tag]) def removeObservers(self): for observee, tag in self.styleObserverTags: observee.RemoveObserver(tag) self.styleObserverTags = [] self.sliceWidgetsPerStyle = {} def refreshFrameSlider(self): self.frameSlider.minimum = 0 if not self._bgMultiVolumeNode: self.frameSlider.maximum = 0 return nFrames = self._bgMultiVolumeNode.GetNumberOfFrames() self.frameSlider.maximum = nFrames - 1 def goToNext(self): currentElement = self.frameSlider.value currentElement += 1 if currentElement > self.frameSlider.maximum: currentElement = 0 self.frameSlider.value = currentElement
from ctk import * from qt import QTimer w = ctkMatrixWidget() w.show() if not _ctkPythonConsoleInstance.isInteractive: #QTimer().singleShot(0, app(), SLOT('quit()')) t = QTimer() t.setInterval(250) t.connect('timeout()', app(), 'quit()') t.start()
class qSlicerMultiVolumeExplorerSimplifiedModuleWidget: def __init__(self, parent=None): logging.debug("qSlicerMultiVolumeExplorerSimplifiedModuleWidget:init() called") if not parent or not hasattr(parent, "layout"): self.parent = slicer.qMRMLWidget() self.parent.setLayout(QVBoxLayout()) else: self.parent = parent self.layout = self.parent.layout() self._bgMultiVolumeNode = None self._fgMultiVolumeNode = None self.styleObserverTags = [] self.sliceWidgetsPerStyle = {} self.chartPopupWindow = None self.chartPopupSize = QSize(600, 300) self.chartPopupPosition = QPoint(0,0) def hide(self): self.widget.hide() def show(self): self.widget.show() def setup(self): self.widget = QWidget() layout = QGridLayout() self.widget.setLayout(layout) self.layout.addWidget(self.widget) self.widget.show() self.layout = layout self.setupInputFrame() self.setupFrameControlFrame() self.setupAdditionalFrames() self.setupPlottingFrame() self.setFramesEnabled(False) self.timer = QTimer() self.timer.setInterval(50) self.setupConnections() # initialize slice observers (from DataProbe.py) # keep list of pairs: [observee,tag] so they can be removed easily self.styleObserverTags = [] # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic self.sliceWidgetsPerStyle = {} self.refreshObservers() def setupInputFrame(self, parent=None): if not parent: parent = self.layout self.bgMultiVolumeSelector = slicer.qMRMLNodeComboBox() self.bgMultiVolumeSelector.nodeTypes = ['vtkMRMLMultiVolumeNode'] self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene) self.bgMultiVolumeSelector.addEnabled = 0 self._bgMultiVolumeSelectorLabel = QLabel('Input multivolume') inputFrameWidget = QWidget() self.inputFrameLayout = QFormLayout() inputFrameWidget.setLayout(self.inputFrameLayout) self.inputFrameLayout.addRow(self._bgMultiVolumeSelectorLabel, self.bgMultiVolumeSelector) parent.addWidget(inputFrameWidget) def setupFrameControlFrame(self): # TODO: initialize the slider based on the contents of the labels array self.frameSlider = ctk.ctkSliderWidget() self.frameLabel = QLabel('Current frame number') self.playButton = QPushButton('Play') self.playButton.toolTip = 'Iterate over multivolume frames' self.playButton.checkable = True frameControlHBox = QHBoxLayout() frameControlHBox.addWidget(self.frameLabel) frameControlHBox.addWidget(self.frameSlider) frameControlHBox.addWidget(self.playButton) self.inputFrameLayout.addRow(frameControlHBox) def setupAdditionalFrames(self): pass def setupPlottingFrame(self, parent=None): if not parent: parent = self.layout self.plottingFrameWidget = QWidget() self.plottingFrameLayout = QGridLayout() self.plottingFrameWidget.setLayout(self.plottingFrameLayout) self._multiVolumeIntensityChart = MultiVolumeIntensityChartView() self.popupChartButton = QPushButton("Undock chart") self.popupChartButton.setCheckable(True) self.plottingFrameLayout.addWidget(self._multiVolumeIntensityChart.chartView) self.plottingFrameLayout.addWidget(self.popupChartButton) parent.addWidget(self.plottingFrameWidget) def setupConnections(self): self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged) self.bgMultiVolumeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onBackgroundInputChanged) self.playButton.connect('toggled(bool)', self.onPlayButtonToggled) self.frameSlider.connect('valueChanged(double)', self.onSliderChanged) self.timer.connect('timeout()', self.goToNext) self.popupChartButton.connect('toggled(bool)', self.onDockChartViewToggled) def onDockChartViewToggled(self, checked): if checked: self.chartPopupWindow = QDialog() self.chartPopupWindow.setWindowFlags(PythonQt.QtCore.Qt.WindowStaysOnTopHint) layout = QGridLayout() self.chartPopupWindow.setLayout(layout) layout.addWidget(self._multiVolumeIntensityChart.chartView) layout.addWidget(self.popupChartButton) self.chartPopupWindow.finished.connect(self.dockChartView) self.chartPopupWindow.resize(self.chartPopupSize) self.chartPopupWindow.move(self.chartPopupPosition) self.chartPopupWindow.show() self.popupChartButton.setText("Dock chart") self._multiVolumeIntensityChart.chartView.show() else: self.chartPopupWindow.close() def dockChartView(self): self.chartPopupSize = self.chartPopupWindow.size self.chartPopupPosition = self.chartPopupWindow.pos self.plottingFrameLayout.addWidget(self._multiVolumeIntensityChart.chartView) self.plottingFrameLayout.addWidget(self.popupChartButton) self.popupChartButton.setText("Undock chart") self.popupChartButton.disconnect('toggled(bool)', self.onDockChartViewToggled) self.popupChartButton.checked = False self.popupChartButton.connect('toggled(bool)', self.onDockChartViewToggled) def onSliderChanged(self, frameId): if self._bgMultiVolumeNode is None: return newValue = int(frameId) self.setCurrentFrameNumber(newValue) def onVCMRMLSceneChanged(self, mrmlScene): logging.debug("qSlicerMultiVolumeExplorerSimplifiedModuleWidget:onVCMRMLSceneChanged") self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene) self.onBackgroundInputChanged() def refreshGUIForNewBackgroundImage(self): self._multiVolumeIntensityChart.reset() self.setFramesEnabled(True) if self._fgMultiVolumeNode and self._bgMultiVolumeNode: Helper.SetBgFgVolumes(self._bgMultiVolumeNode.GetID(), self._fgMultiVolumeNode.GetID()) else: Helper.SetBgVolume(self._bgMultiVolumeNode.GetID()) self.refreshFrameSlider() self._multiVolumeIntensityChart.bgMultiVolumeNode = self._bgMultiVolumeNode self.refreshObservers() def getBackgroundMultiVolumeNode(self): return self.bgMultiVolumeSelector.currentNode() def onBackgroundInputChanged(self): self._bgMultiVolumeNode = self.getBackgroundMultiVolumeNode() if self._bgMultiVolumeNode is not None: self.refreshGUIForNewBackgroundImage() else: self.setFramesEnabled(False) def onPlayButtonToggled(self, checked): if self._bgMultiVolumeNode is None: return if checked: self.timer.start() self.playButton.text = 'Stop' else: self.timer.stop() self.playButton.text = 'Play' def processEvent(self, observee, event): # logging.debug("processing event %s" % event) if self._bgMultiVolumeNode is None: return # TODO: use a timer to delay calculation and compress events if event == 'LeaveEvent': # reset all the readouts # TODO: reset the label text return if not self.sliceWidgetsPerStyle.has_key(observee): return interactor = observee.GetInteractor() self.createChart(self.sliceWidgetsPerStyle[observee], interactor.GetEventPosition()) def createChart(self, sliceWidget, position): self._multiVolumeIntensityChart.createChart(sliceWidget, position) def setCurrentFrameNumber(self, frameNumber): mvDisplayNode = self._bgMultiVolumeNode.GetDisplayNode() mvDisplayNode.SetFrameComponent(frameNumber) def setFramesEnabled(self, enabled): pass def refreshObservers(self): """ When the layout changes, drop the observers from all the old widgets and create new observers for the newly created widgets""" self.removeObservers() # get new slice nodes layoutManager = slicer.app.layoutManager() sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLSliceNode') for nodeIndex in xrange(sliceNodeCount): # find the widget for each node in scene sliceNode = slicer.mrmlScene.GetNthNodeByClass(nodeIndex, 'vtkMRMLSliceNode') sliceWidget = layoutManager.sliceWidget(sliceNode.GetLayoutName()) if sliceWidget: # add observers and keep track of tags style = sliceWidget.sliceView().interactorStyle() self.sliceWidgetsPerStyle[style] = sliceWidget events = ("MouseMoveEvent", "EnterEvent", "LeaveEvent") for event in events: tag = style.AddObserver(event, self.processEvent) self.styleObserverTags.append([style,tag]) def removeObservers(self): for observee,tag in self.styleObserverTags: observee.RemoveObserver(tag) self.styleObserverTags = [] self.sliceWidgetsPerStyle = {} def refreshFrameSlider(self): self.frameSlider.minimum = 0 if not self._bgMultiVolumeNode: self.frameSlider.maximum = 0 return nFrames = self._bgMultiVolumeNode.GetNumberOfFrames() self.frameSlider.maximum = nFrames - 1 def goToNext(self): currentElement = self.frameSlider.value currentElement += 1 if currentElement > self.frameSlider.maximum: currentElement = 0 self.frameSlider.value = currentElement
from ctk import * from qt import QTimer # Test display of a CTK widget w = ctkMatrixWidget() w.show() # Test command execution using Python manager pythonManager = _ctkPythonManagerInstance pythonManager.executeString("variableInPythonConsole=523") try: print("variableInPythonConsole was successfully set to {0}".format( variableInPythonConsole)) except: print "PythonManager.executeString failed" qt.QApplication.exit(1) if not _ctkPythonConsoleInstance.isInteractive: #QTimer().singleShot(0, app(), SLOT('quit()')) t = QTimer() t.setInterval(250) t.connect('timeout()', app(), 'quit()') t.start()
from ctk import * from qt import QTimer # Test display of a CTK widget w = ctkMatrixWidget() w.show() # Test command execution using Python manager pythonManager = _ctkPythonManagerInstance pythonManager.executeString("variableInPythonConsole=523") try: print ("variableInPythonConsole was successfully set to {0}".format(variableInPythonConsole)) except: print "PythonManager.executeString failed" qt.QApplication.exit(1) if not _ctkPythonConsoleInstance.isInteractive: # QTimer().singleShot(0, app(), SLOT('quit()')) t = QTimer() t.setInterval(250) t.connect("timeout()", app(), "quit()") t.start()
class KTVMainWindow(KParts.MainWindow): """Implements the main KatchTV application window.""" def __init__(self, title): """Initialises a new window object.""" self._stopped = True KParts.MainWindow.__init__(self, None, str(title)) self.setCaption(config.appFullVersion) self._initWidgets() self.__mediaManager = Media.Manager() self.__downloadTimer = QTimer() self.__downloadTimer.connect(self.__downloadTimer,SIGNAL(str(u"timeout()")), self.__updateDownloads) self.browser.goToURL(u'katchtv:welcome:') def saveAll(self): self.__mediaManager._saveItems() def __updateDownloads(self): self.__mediaManager.beginNewDownloads() def enableThreads(self): # start everything, and mark as running self.__downloadTimer.start(config.updateDownloadsTimerMillisecs) self.bmarksList.enableThreads() self._stopped = False def disableThreads(self): # stop in the order of slowest to fastest, hoping it'll # all finish around the same time self.bmarksList.disableThreads() self.__mediaManager.stop() self.__downloadTimer.stop() self._stopped = True def getMediaManager(self): return self.__mediaManager def isStopped(self): """Returns True if the application should not run yet (ie, if it has not been fully initialised).""" return self._stopped def _initWidgets(self): """Initialises all of the main widgets in the window.""" global appRoot appIconPath = os.path.join(appRoot, "images/miniicon.png") self.setIcon(QPixmap(appIconPath)) self.mainBox = QHBox(self) self.mainSplitter = QSplitter(self.mainBox) self.bmarksListBox = QVBox(self.mainSplitter) self.bmarksListBox.setMaximumWidth(250) self.bmarksList = KTVBookmarksListView.KTVBookmarksListView(self.bmarksListBox, self) QObject.connect(self.bmarksList, SIGNAL(str(u'doubleClicked(QListViewItem *)')), self._bookmarkChosen) self.browserBox = QVBox(self.mainSplitter) self.browser = KTVHTMLPart.KTVHTMLPart(self.browserBox, self) self.setCentralWidget(self.mainBox) self._buttonBox = QHBox(self.bmarksListBox) self._addButton = QPushButton(u"&Add", self._buttonBox, str(u"")) QObject.connect(self._addButton, SIGNAL(str(u'clicked()')), self._addItem) self._deleteButton = QPushButton(u"&Delete", self._buttonBox, str(u"")) QObject.connect(self._deleteButton, SIGNAL(str(u'clicked()')), self._deleteItem) self._backButton = QPushButton(u"&Back", self.bmarksListBox, str(u"")) QObject.connect(self._backButton, SIGNAL(str(u'clicked()')), self._back) self._helpButton = QPushButton(u"&Help", self.bmarksListBox, str(u"")) QObject.connect(self._helpButton, SIGNAL(str(u'clicked()')), self._help) self.statusBar().message(u"KatchTV is now ready for use.") def _help(self): """A hook (a Qt signal slot, actually) which is called when the user clicks the "Help" button. Loads the manual into the browser.""" self.browser.goToURL(u'katchtv:help:') def _back(self): """A hook (a Qt signal slot) which is called when the user clicks the "Back" button. Navigates one step back through the browser history.""" self.browser.loadPreviousPage() def _addItem(self): """A hook (Qt signal slot) which is called when the user clicks the "Add" button. Presents a dialog, asking the user for the feed URI to add.""" validURI = False firstTry = True while not validURI: if firstTry: uri, confirmed = KInputDialog.text(u"Add Feed Bookmark", QString(u"Please enter the channel's feed URI (or URL) here.")) uri = unicode(uri) else: uri, confirmed = KInputDialog.text(u"Add Feed Bookmark", u"The URI you entered was invalid. Please try again, or cancel.", QString(uri)) uri = unicode(uri) firstTry = False if confirmed: validURI = utils.isAFeed(uri) else: # user cancelled the input return feed = Feed.FeedCache.getFeedFromURINoLock(uri) self.bmarksList.addChannel(feed) def _deleteItem(self): """A hook (Qt signal slot) which is called when the user clicks the Delete button. Deletes the selected item, if that item is a subscribed channel. Otherwise, informs the user that they cannot delete the item.""" self.bmarksList.delCurrentItem() def _bookmarkChosen(self, item): """A hook (Qt signal slot) which is called when the user double-clicks on an item in the listview. Checks if the item has a URI column entry, and if so, navigates to it.""" title = item.text(KTVBookmarksListView.COL_NAME) uri = item.text(KTVBookmarksListView.COL_URI) if title != u'' and uri != u'': self.browser.goToURL(uri) def getBookmarksList(self): return self.bmarksList