def testInfoIcon(self): iw = QWidget() layout = QHBoxLayout() layout.setMargin(100) ii = InfoIcon('hover popup text', iw) layout.addWidget(ii) iw.setLayout(layout) iw.setWindowModality(Qt.ApplicationModal) iw.show() QTest.mouseMove(iw, iw.pos()) self.assertEqual(QToolTip.text(), 'Name is not unique') QTest.mouseMove(ii) # why is this necessary? QTest.qWait(250) QTest.mouseMove(ii) QTest.qWait(2000) self.assertEqual(QToolTip.text(), 'hover popup text')
def testInfoIcon(self): iw = QWidget() layout = QHBoxLayout() layout.setMargin(100) ii = InfoIcon('hover popup text', iw) layout.addWidget(ii) iw.setLayout(layout) iw.setWindowModality(Qt.ApplicationModal) iw.show() QTest.mouseMove(iw, iw.pos()) self.assertEqual(QToolTip.text(), '') QTest.mouseMove(ii) # why is this necessary? QTest.qWait(250) QTest.mouseMove(ii) QTest.qWait(2000) self.assertEqual(QToolTip.text(), 'hover popup text')
class _TitleBar(QToolBar): """Widget title bar. Contains standard dock widget buttons and allows to add new buttons and widgets """ def __init__(self, parent, *args): QToolBar.__init__(self, parent, *args) self.setSizePolicy( QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Maximum ) ) self._dock = parent self.aClose = QToolBar.addAction(self, self.style().standardIcon( QStyle.SP_TitleBarCloseButton ), "") self.setMovable( False ) self.setFloatable( False ) self.aClose.triggered.connect(self._dock.close) textHeight = QFontMetrics(self.font()).height() self.setIconSize(QSize(textHeight, textHeight)) # a fake spacer widget self._spacer = QWidget( self ) self._spacer.setSizePolicy( QSizePolicy( QSizePolicy.Expanding, QSizePolicy.MinimumExpanding ) ) self.addWidget( self._spacer ) def paintEvent(self, event ): """QToolBar.paintEvent reimplementation Draws buttons, dock icon and text """ rect = self._spacer.rect() painter = QPainter( self ) transform = QTransform() transform.translate(self._spacer.pos().x(), self._spacer.pos().y()) painter.setTransform( transform ) """ Not supported currently if self._dock.features() & QDockWidget.DockWidgetVerticalTitleBar : transform = QTransform() rect.setSize( QSize( rect.height(), rect.width() ) ) transform.rotate( -90 ) transform.translate( -rect.width(), 0 ) painter.setTransform( transform ) """ # icon / title optionB = QStyleOptionButton() optionB.initFrom( self._dock ) optionB.rect = rect optionB.text = self._dock.windowTitle() optionB.iconSize = self.iconSize() optionB.icon = self._dock.windowIcon() self.style().drawControl( QStyle.CE_PushButtonLabel, optionB, painter, self._dock ) def minimumSizeHint(self): """QToolBar.minimumSizeHint implementation """ return QToolBar.sizeHint(self) def sizeHint(self): """QToolBar.sizeHint implementation """ wis = self.iconSize() size = QToolBar.sizeHint(self) fm = QFontMetrics ( self.font() ) if self._dock.features() & QDockWidget.DockWidgetVerticalTitleBar : size.setHeight(size.height() + fm.width( self._dock.windowTitle() ) + wis.width()) else: size.setWidth(size.width() + fm.width( self._dock.windowTitle() ) + wis.width()) return size def addAction(self, action): """QToolBar.addAction implementation Adjusts indexes for behaving like standard empty QTitleBar """ return self.insertAction(self.aClose, action) def addSeparator(self): """QToolBar.addAction implementation Adjusts indexes for behaving like standard empty QTitleBar """ return self.insertSeparator(self.aClose) def addWidget(self, widget): """QToolBar.addAction implementation Adjusts indexes for behaving like standard empty QTitleBar """ return self.insertWidget(self.aClose, widget)
class RemoconSub(QMainWindow): def __init__(self, parent, title, application, rocon_master_index="", rocon_master_name="", rocon_master_uri='localhost', host_name='localhost'): self.rocon_master_index = rocon_master_index self.rocon_master_uri = rocon_master_uri self.rocon_master_name = rocon_master_name self.host_name = host_name self._context = parent self.application = application super(RemoconSub, self).__init__(parent) self.initialised = False self._widget_app_list = QWidget() self._widget_role_list = QWidget() self.rocon_master_list = {} self.cur_selected_role = 0 self.app_list = {} self.cur_selected_app = None self.remocon_info = RemoconInfo(stop_app_postexec_fn=self._set_stop_app_button) path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../ui/applist.ui") uic.loadUi(path, self._widget_app_list) path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../ui/rolelist.ui") uic.loadUi(path, self._widget_role_list) utils.setup_home_dirs() self.rocon_master_list_cache_path = os.path.join(utils.get_settings_cache_home(), "rocon_master.cache") self.scripts_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../scripts/") #role list widget self._widget_role_list.role_list_widget.setIconSize(QSize(50, 50)) self._widget_role_list.role_list_widget.itemDoubleClicked.connect(self._select_role_list) self._widget_role_list.back_btn.pressed.connect(self._back_role_list) self._widget_role_list.refresh_btn.pressed.connect(self._refresh_role_list) #app list widget self._widget_app_list.app_list_widget.setIconSize(QSize(50, 50)) self._widget_app_list.app_list_widget.itemDoubleClicked.connect(self._start_app) self._widget_app_list.back_btn.pressed.connect(self._uninit_app_list) self._widget_app_list.app_list_widget.itemClicked.connect(self._select_app_list) # rocon master item click event self._widget_app_list.stop_app_btn.pressed.connect(self._stop_app) self._widget_app_list.refresh_btn.pressed.connect(self._refresh_app_list) self._widget_app_list.stop_app_btn.setDisabled(True) #init self._init() def _init(self): self._init_role_list() # Ugly Hack : our window manager is not graying out the button when an app closes itself down and the appropriate # callback (_set_stop_app_button) is fired. It does otherwise though so it looks like the window manager # is getting confused when the original program doesn't have the focus. # # Taking control of it ourselves works... self._widget_app_list.stop_app_btn.setStyleSheet(QString.fromUtf8("QPushButton:disabled { color: gray }")) self._widget_role_list.show() self.initialised = True ################################################################################################################ ##role list widget ################################################################################################################ def _init_role_list(self): if not self.remocon_info._connect(self.rocon_master_name, self.rocon_master_uri, self.host_name): return False self._refresh_role_list() return True def _uninit_role_list(self): print "[RemoconSub]_uninit_role_list" self.remocon_info._shutdown() self.cur_selected_role = 0 def _select_role_list(self, Item): print '_select_role_list: ' + Item.text() self.cur_selected_role = str(Item.text()) self.remocon_info._select_role(self.cur_selected_role) self._widget_app_list.show() self._widget_app_list.move(self._widget_role_list.pos()) self._widget_role_list.hide() self._init_app_list() def _back_role_list(self): self._uninit_role_list() execute_path = self.scripts_path + 'rocon_remocon' # command execute_path += " " + "'" + self.host_name + "'" # arg1 os.execv(self.scripts_path + 'rocon_remocon', ['', self.host_name]) print "Spawning: %s" % (execute_path) def _refresh_role_list(self): self._widget_role_list.role_list_widget.clear() role_list = self.remocon_info.get_role_list() #set list widget item (reverse order because we push them on the top) for role in reversed(role_list): self._widget_role_list.role_list_widget.insertItem(0, role) #setting the list font font = self._widget_role_list.role_list_widget.item(0).font() font.setPointSize(13) self._widget_role_list.role_list_widget.item(0).setFont(font) ################################################################################################################ ##app list widget ################################################################################################################ def _init_app_list(self): self._refresh_app_list() def _uninit_app_list(self): self._widget_role_list.show() self._widget_role_list.move(self._widget_app_list.pos()) self._widget_app_list.hide() def _refresh_app_list(self): self.app_list = {} self.app_list = self.remocon_info._get_app_list() self._widget_app_list.app_list_widget.clear() index = 0 for k in self.app_list.values(): k['index'] = index index = index + 1 self._widget_app_list.app_list_widget.insertItem(0, k['display_name']) #setting the list font font = self._widget_app_list.app_list_widget.item(0).font() font.setPointSize(13) self._widget_app_list.app_list_widget.item(0).setFont(font) #setting the icon app_icon = k['icon'] print("Icon: %s" % app_icon) if app_icon == "unknown.png": icon = QIcon(self.icon_paths['unknown']) self._widget_app_list.app_list_widget.item(0).setIcon(icon) elif len(app_icon): icon = QIcon(os.path.join(utils.get_icon_cache_home(), app_icon)) self._widget_app_list.app_list_widget.item(0).setIcon(icon) else: print self.rocon_master_name + ': No icon' pass def _select_app_list(self, Item): list_widget = Item.listWidget() cur_index = list_widget.count() - list_widget.currentRow() - 1 for k in self.app_list.values(): if(k['index'] == cur_index): self.cur_selected_app = k break self._widget_app_list.app_info.clear() info_text = "<html>" info_text += "<p>-------------------------------------------</p>" info_text += "<p><b>name: </b>" + self.cur_selected_app['name'] + "</p>" info_text += "<p><b> ---------------------</b>" + "</p>" info_text += "<p><b>compatibility: </b>" + self.cur_selected_app['compatibility'] + "</p>" info_text += "<p><b>display name: </b>" + self.cur_selected_app['display_name'] + "</p>" info_text += "<p><b>description: </b>" + self.cur_selected_app['description'] + "</p>" info_text += "<p><b>namespace: </b>" + self.cur_selected_app['namespace'] + "</p>" info_text += "<p><b>max: </b>" + str(self.cur_selected_app['max']) + "</p>" info_text += "<p><b> ---------------------</b>" + "</p>" info_text += "<p><b>remappings: </b>" + str(self.cur_selected_app['remappings']) + "</p>" info_text += "<p><b>parameters: </b>" + str(self.cur_selected_app['parameters']) + "</p>" info_text += "</html>" self._widget_app_list.app_info.appendHtml(info_text) self._set_stop_app_button() def _set_stop_app_button(self): ''' This can be used by the underlying listeners to check, and if needed, toggle the state of the stop app button whenever a running app terminates itself. ''' if not self.app_list: return try: if self.cur_selected_app["launch_list"]: console.logdebug("Remocon : enabling stop app button") self._widget_app_list.stop_app_btn.setDisabled(False) else: console.logdebug("Remocon : disabling stop app button") self._widget_app_list.stop_app_btn.setEnabled(False) except KeyError: pass # do nothing def _stop_app(self): print "Stop app: " + str(self.cur_selected_app['name']) if self.remocon_info._stop_app(self.cur_selected_app['hash']): self._set_stop_app_button() #self._widget_app_list.stop_app_btn.setDisabled(True) def _start_app(self): print "Start app: " + str(self.cur_selected_app['name']) if self.remocon_info._start_app(self.cur_selected_app['hash']): self._widget_app_list.stop_app_btn.setDisabled(False)
class _TitleBar(QToolBar): """Widget title bar. Contains standard dock widget buttons and allows to add new buttons and widgets """ def __init__(self, parent, *args): QToolBar.__init__(self, parent, *args) self.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)) self._dock = parent self.aClose = QToolBar.addAction( self, self.style().standardIcon(QStyle.SP_TitleBarCloseButton), "") self.setMovable(False) self.setFloatable(False) self.aClose.triggered.connect(self._dock.close) textHeight = QFontMetrics(self.font()).height() self.setIconSize(QSize(textHeight, textHeight)) # a fake spacer widget self._spacer = QWidget(self) self._spacer.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding)) self.addWidget(self._spacer) def paintEvent(self, event): """QToolBar.paintEvent reimplementation Draws buttons, dock icon and text """ rect = self._spacer.rect() painter = QPainter(self) transform = QTransform() transform.translate(self._spacer.pos().x(), self._spacer.pos().y()) painter.setTransform(transform) """ Not supported currently if self._dock.features() & QDockWidget.DockWidgetVerticalTitleBar : transform = QTransform() rect.setSize(QSize(rect.height(), rect.width())) transform.rotate(-90) transform.translate(-rect.width(), 0) painter.setTransform(transform) """ # icon / title optionB = QStyleOptionButton() optionB.initFrom(self._dock) optionB.rect = rect optionB.text = self._dock.windowTitle() optionB.iconSize = self.iconSize() optionB.icon = self._dock.windowIcon() self.style().drawControl(QStyle.CE_PushButtonLabel, optionB, painter, self._dock) def minimumSizeHint(self): """QToolBar.minimumSizeHint implementation """ return QToolBar.sizeHint(self) def sizeHint(self): """QToolBar.sizeHint implementation """ wis = self.iconSize() size = QToolBar.sizeHint(self) fm = QFontMetrics(self.font()) if self._dock.features() & QDockWidget.DockWidgetVerticalTitleBar: size.setHeight(size.height() + fm.width(self._dock.windowTitle()) + wis.width()) else: size.setWidth(size.width() + fm.width(self._dock.windowTitle()) + wis.width()) return size def addAction(self, action): """QToolBar.addAction implementation Adjusts indexes for behaving like standard empty QTitleBar """ return self.insertAction(self.aClose, action) def addSeparator(self): """QToolBar.addAction implementation Adjusts indexes for behaving like standard empty QTitleBar """ return self.insertSeparator(self.aClose) def addWidget(self, widget): """QToolBar.addAction implementation Adjusts indexes for behaving like standard empty QTitleBar """ return self.insertWidget(self.aClose, widget)