def test_overlay(self): container = QWidget() overlay = MessageOverlayWidget(parent=container) overlay.setWidget(container) overlay.setIcon(QStyle.SP_MessageBoxInformation) container.show() container.raise_() self._exec(500) self.assertTrue(overlay.isVisible()) overlay.setText("Hello world! It's so nice here") self._exec(500) button_ok = overlay.addButton(MessageOverlayWidget.Ok) button_close = overlay.addButton(MessageOverlayWidget.Close) button_help = overlay.addButton(MessageOverlayWidget.Help) self.assertTrue(all([button_ok, button_close, button_help])) self.assertIs(overlay.button(MessageOverlayWidget.Ok), button_ok) self.assertIs(overlay.button(MessageOverlayWidget.Close), button_close) self.assertIs(overlay.button(MessageOverlayWidget.Help), button_help) button = overlay.addButton("Click Me!", MessageOverlayWidget.AcceptRole) self.assertIsNot(button, None) self.assertTrue(overlay.buttonRole(button), MessageOverlayWidget.AcceptRole) self._exec(10000)
w.setLayout(l) addButton = QPushButton("Add random label\n note: \n the first added is permanent") l.addWidget(addButton) def addRandomLabel(): model.insertRow(model.rowCount(), Label("Label {}".format(model.rowCount() + 1), QColor(numpy.random.randint(0, 255), numpy.random.randint(0, 255), numpy.random.randint(0, 255)))) addButton.clicked.connect(addRandomLabel) model.makeRowPermanent(0) w.show() w.raise_() tableView = LabelListView() tableView.support_merges = True l.addWidget(tableView) tableView.setModel(model) tableView2 = LabelListView() tableView2.setModel(model) tableView2._table.setShowGrid(True) l.addWidget(tableView2) sys.exit(app.exec_())
def show(self): # For non-modal dialogs, show() is not enough to bring the window at the forefront, we have # to call raise() as well QWidget.showNormal(self) QWidget.raise_(self) QWidget.activateWindow(self)
class RemoconMain(QMainWindow): def __init__(self, parent, title, application): self._context = parent super(RemoconMain, self).__init__() self.initialised = False self.setObjectName('Remocon') self.host_name = "localhost" self.master_uri = "http://%s:11311" % (self.host_name) self.env_host_name = os.getenv("ROS_HOSTNAME") self.env_master_uri = os.getenv("ROS_MASTER_URI") if self.env_host_name == None: self.env_host_name = 'localhost' if self.env_master_uri == None: self.env_master_uri = "http://%s:11311" % (self.env_host_name) self.application = application self._widget_main = QWidget() self.rocon_master_list = {} self.cur_selected_rocon_master = None self.is_init = False path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../ui/remocon.ui") uic.loadUi(path, self._widget_main) utils.setup_home_dirs() self.rocon_master_list_cache_path = os.path.join(utils.get_settings_cache_home(), "rocon_master.cache") self.icon_paths = {} try: self.icon_paths['unknown'] = rocon_python_utils.ros.find_resource_from_string('rocon_icons/unknown', extension='png') except (rospkg.ResourceNotFound, ValueError): console.logerror("Remocon : couldn't find icons on the ros package path (install rocon_icons and rocon_bubble_icons") sys.exit(1) self.scripts_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../scripts/") #main widget self._widget_main.list_widget.setIconSize(QSize(50, 50)) self._widget_main.list_widget.itemDoubleClicked.connect(self._connect_rocon_master) # list item double click event self._widget_main.list_widget.itemClicked.connect(self._select_rocon_master) # list item double click event self._widget_main.add_concert_btn.pressed.connect(self._set_add_rocon_master) # add button event self._widget_main.delete_btn.pressed.connect(self._delete_rocon_master) # delete button event self._widget_main.delete_all_btn.pressed.connect(self._delete_all_rocon_masters) # delete all button event self._widget_main.refresh_btn.pressed.connect(self._refresh_rocon_master_list) # refresh all button event #init self._init() self._widget_main.show() self._widget_main.activateWindow() # give it the focus self._widget_main.raise_() # make sure it is on top def __del__(self): print '[RemoconMain]: Destroy' def _init(self): self._connect_dlg_isValid = False self.cur_selected_rocon_master = None self._refresh_rocon_master_list() self.is_init = True pass def _check_up(self): for k in self.rocon_master_list.values(): print("Concert: %s" % k) rocon_master_uri = k['master_uri'] host_name = k['host_name'] print "[_check_up]:MASTER_URI[%s], HOST_NAME[%s]" % (rocon_master_uri, host_name) output = subprocess.Popen([self.scripts_path + "rocon_remocon_check_up", rocon_master_uri, host_name], stdout=subprocess.PIPE) time_out_cnt = 0 while True: print "checking: " + rocon_master_uri result = output.poll() if time_out_cnt > 30: print "timeout: " + rocon_master_uri try: output.terminate() except: print "Error: output.terminate()" k['name'] = "Unknown" k['description'] = "Unknown." k['icon'] = "unknown.png" k['flag'] = '0' break elif result == 0: args = output.communicate()[0] k['name'] = args.split('\n')[0] k['description'] = args.split('\n')[1] k['icon'] = args.split('\n')[2] if k['name'] == "Unknown": k['flag'] = '0' else: k['flag'] = '1' break time.sleep(0.1) time_out_cnt += 1 def _read_cache(self): #read cache and display the rocon master list try: cache_rocon_master_info_list = open(self.rocon_master_list_cache_path, 'r') except: console.logdebug("Remocon : no cached settings found, moving on.") return lines = cache_rocon_master_info_list.readlines() for line in lines: if line.count("[index="): rocon_master_index = line[string.find(line, "[index=") + len("[index="):string.find(line, ",name=")] rocon_master_name = line[string.find(line, "name=") + len("name="):string.find(line, ",master_uri=")] rocon_master_uri = line[string.find(line, ",master_uri=") + len(",master_uri="):string.find(line, ",host_name=")] rocon_master_host_name = line[string.find(line, ",host_name=") + len(",host_name="):string.find(line, ",description=")] rocon_master_description = line[string.find(line, ",description=") + len(",description="):string.find(line, ",icon=")] rocon_master_icon = line[string.find(line, ",icon=") + len(",icon="):string.find(line, ",flag=")] rocon_master_flag = line[string.find(line, ",flag=") + len(",flag="):string.find(line, "]")] self.rocon_master_list[rocon_master_index] = {} self.rocon_master_list[rocon_master_index]['index'] = rocon_master_index self.rocon_master_list[rocon_master_index]['name'] = rocon_master_name self.rocon_master_list[rocon_master_index]['master_uri'] = rocon_master_uri self.rocon_master_list[rocon_master_index]['host_name'] = rocon_master_host_name self.rocon_master_list[rocon_master_index]['icon'] = rocon_master_icon self.rocon_master_list[rocon_master_index]['description'] = rocon_master_description self.rocon_master_list[rocon_master_index]['flag'] = rocon_master_flag cache_rocon_master_info_list.close() def _delete_all_rocon_masters(self): for k in self.rocon_master_list.values(): del self.rocon_master_list[k["index"]] self._update_rocon_master_list() def _delete_rocon_master(self): if self.cur_selected_rocon_master in self.rocon_master_list.keys(): del self.rocon_master_list[self.cur_selected_rocon_master] self._update_rocon_master_list() def _add_rocon_master(self, params): rocon_master_uri = str(params['param1'].toPlainText()) rocon_master_host_name = str(params['param2'].toPlainText()) rocon_master_index = str(uuid.uuid4()) self.rocon_master_list[rocon_master_index] = {} self.rocon_master_list[rocon_master_index]['index'] = rocon_master_index self.rocon_master_list[rocon_master_index]['name'] = "Unknown" self.rocon_master_list[rocon_master_index]['master_uri'] = rocon_master_uri self.rocon_master_list[rocon_master_index]['host_name'] = rocon_master_host_name self.rocon_master_list[rocon_master_index]['icon'] = "unknown.png" self.rocon_master_list[rocon_master_index]['description'] = "" self.rocon_master_list[rocon_master_index]['flag'] = "0" self._update_rocon_master_list() self._refresh_rocon_master_list() def _set_add_rocon_master(self): print '_add_rocon_master' if self._connect_dlg_isValid: print "Dialog is live!!" self._connect_dlg.done(0) #dialog self._connect_dlg = QDialog(self._widget_main) self._connect_dlg.setWindowTitle("Add Ros Master") self._connect_dlg.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) self._connect_dlg.setMinimumSize(350, 0) # dlg_rect = self._connect_dlg.geometry() #dialog layout ver_layout = QVBoxLayout(self._connect_dlg) ver_layout.setContentsMargins(9, 9, 9, 9) #param layout text_grid_sub_widget = QWidget() text_grid_layout = QGridLayout(text_grid_sub_widget) text_grid_layout.setColumnStretch(1, 0) text_grid_layout.setRowStretch(2, 0) #param 1 title_widget1 = QLabel("MASTER_URI: ") context_widget1 = QTextEdit() context_widget1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) context_widget1.setMinimumSize(0, 30) context_widget1.append(self.master_uri) #param 2 title_widget2 = QLabel("HOST_NAME: ") context_widget2 = QTextEdit() context_widget2.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) context_widget2.setMinimumSize(0, 30) context_widget2.append(self.host_name) #add param text_grid_layout.addWidget(title_widget1) text_grid_layout.addWidget(context_widget1) text_grid_layout.addWidget(title_widget2) text_grid_layout.addWidget(context_widget2) #add param layout ver_layout.addWidget(text_grid_sub_widget) #button layout button_hor_sub_widget = QWidget() button_hor_layout = QHBoxLayout(button_hor_sub_widget) params = {} params['param1'] = context_widget1 params['param2'] = context_widget2 #check box use_env_var_check = QCheckBox("Use environment variables") use_env_var_check.setCheckState(Qt.Unchecked) def set_use_env_var(data, text_widget1, text_widget2): if data == Qt.Unchecked: text_widget1.setText(self.master_uri) text_widget2.setText(self.host_name) elif data == Qt.Checked: self.master_uri = str(text_widget1.toPlainText()) self.host_name = str(text_widget2.toPlainText()) text_widget1.setText(self.env_master_uri) text_widget2.setText(self.env_host_name) def check_event(data): set_use_env_var(data, context_widget1, context_widget2) use_env_var_check.stateChanged.connect(check_event) ver_layout.addWidget(use_env_var_check) #button btn_call = QPushButton("Add") btn_cancel = QPushButton("Cancel") btn_call.clicked.connect(lambda: self._connect_dlg.done(0)) btn_call.clicked.connect(lambda: self._add_rocon_master(params)) btn_cancel.clicked.connect(lambda: self._connect_dlg.done(0)) #add button button_hor_layout.addWidget(btn_call) button_hor_layout.addWidget(btn_cancel) #add button layout ver_layout.addWidget(button_hor_sub_widget) self._connect_dlg.setVisible(True) self._connect_dlg.finished.connect(self._destroy_connect_dlg) self._connect_dlg_isValid = True def _refresh_rocon_master_list(self): print '_refresh_rocon_master_list' if self.is_init: self._update_rocon_master_list() self._read_cache() self._widget_main.list_info_widget.clear() self._check_up() self._update_rocon_master_list() def _update_rocon_master_list(self): print '_update_rocon_master_list' self._widget_main.list_widget.clear() try: cache_rocon_master_info_list = open(self.rocon_master_list_cache_path, 'w') except: print "No directory or file: %s" % (self.rocon_master_list_cache_path) return for k in self.rocon_master_list.values(): self._add_rocon_master_list_item(k) rocon_master_index = k['index'] rocon_master_name = k['name'] rocon_master_uri = k['master_uri'] rocon_master_host_name = k['host_name'] rocon_master_icon = k['icon'] rocon_master_description = k['description'] rocon_master_flag = k['flag'] rocon_master_elem = '[' rocon_master_elem += 'index=' + str(rocon_master_index) + ',' rocon_master_elem += 'name=' + str(rocon_master_name) + ',' rocon_master_elem += 'master_uri=' + str(rocon_master_uri) + ',' rocon_master_elem += 'host_name=' + str(rocon_master_host_name) + ',' rocon_master_elem += 'description=' + str(rocon_master_description) + ',' rocon_master_elem += 'icon=' + rocon_master_icon + ',' rocon_master_elem += 'flag=' + rocon_master_flag rocon_master_elem += ']\n' cache_rocon_master_info_list.write(rocon_master_elem) cache_rocon_master_info_list.close() def _add_rocon_master_list_item(self, rocon_master): print('_add_rocon_master_list_item [%s]' % rocon_master['name']) rocon_master_index = rocon_master['index'] rocon_master_name = rocon_master['name'] rocon_master_uri = rocon_master['master_uri'] rocon_master_host_name = rocon_master['host_name'] rocon_master_icon = rocon_master['icon'] rocon_master_description = rocon_master['description'] rocon_master['cur_row'] = str(self._widget_main.list_widget.count()) display_name = str(rocon_master_name) + "\n" + "[" + str(rocon_master_uri) + "]" self._widget_main.list_widget.insertItem(self._widget_main.list_widget.count(), display_name) #setting the list font font = self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).font() font.setPointSize(13) self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setFont(font) #setToolTip rocon_master_info = "" rocon_master_info += "rocon_master_index: " + str(rocon_master_index) + "\n" rocon_master_info += "rocon_master_name: " + str(rocon_master_name) + "\n" rocon_master_info += "master_uri: " + str(rocon_master_uri) + "\n" rocon_master_info += "host_name: " + str(rocon_master_host_name) + "\n" rocon_master_info += "description: " + str(rocon_master_description) self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setToolTip(rocon_master_info) #set icon if rocon_master_icon == "unknown.png": icon = QIcon(self.icon_paths['unknown']) self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon) elif len(rocon_master_icon): icon = QIcon(os.path.join(utils.get_icon_cache_home(), rocon_master_icon)) self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon) else: print rocon_master_name + ': No icon' pass def _select_rocon_master(self, Item): list_widget = Item.listWidget() for k in self.rocon_master_list.values(): if k["cur_row"] == str(list_widget.currentRow()): self.cur_selected_rocon_master = k['index'] break self._widget_main.list_info_widget.clear() info_text = "<html>" info_text += "<p>-------------------------------------------</p>" info_text += "<p><b>name: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['name']) + "</p>" info_text += "<p><b>master_uri: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['master_uri']) + "</p>" info_text += "<p><b>host_name: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['host_name']) + "</p>" info_text += "<p><b>description: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['description']) + "</p>" info_text += "<p>-------------------------------------------</p>" info_text += "</html>" self._widget_main.list_info_widget.appendHtml(info_text) def _destroy_connect_dlg(self): print "[Dialog] Destroy!!!" self._connect_dlg_isValid = False def _connect_rocon_master(self): rocon_master_name = str(self.rocon_master_list[self.cur_selected_rocon_master]['name']) rocon_master_uri = str(self.rocon_master_list[self.cur_selected_rocon_master]['master_uri']) rocon_master_host_name = str(self.rocon_master_list[self.cur_selected_rocon_master]['host_name']) rocon_master_index = str(self.cur_selected_rocon_master) if self.rocon_master_list[rocon_master_index]['flag'] == '0': # DJS: unused reply box? # reply = QMessageBox.warning(self, 'ERROR', "YOU SELECT NO CONCERT", QMessageBox.Ok|QMessageBox.Ok) return execute_path = self.scripts_path + 'rocon_remocon_sub' # command execute_path += " " + "'" + rocon_master_index + "'" # arg1 execute_path += " " + "'" + rocon_master_name + "'" # arg2 execute_path += " " + "'" + rocon_master_uri + "'" # arg3 execute_path += " " + "'" + rocon_master_host_name + "'" # arg4 self._widget_main.hide() os.execv(self.scripts_path + 'rocon_remocon_sub', ["", rocon_master_index, rocon_master_name, rocon_master_uri, rocon_master_host_name]) print "Spawning: %s" % (execute_path)
self.delayedValueChanged.emit( self.value() ) def setValueWithoutSignal(self, value): self._blocksignal = True self.setValue(value) self._blocksignal = False if __name__ == "__main__": from PyQt4.QtGui import QApplication, QWidget, QLabel, QVBoxLayout app = QApplication([]) label = QLabel() box = DelayedSpinBox(1000) def update_label(value): print "updating label to: {}".format(value) label.setText(str(value)) box.delayedValueChanged.connect( update_label ) layout = QVBoxLayout() layout.addWidget(label) layout.addWidget(box) widget = QWidget() widget.setLayout(layout) widget.show() widget.raise_() app.exec_()
class TestLayerWidget(ut.TestCase): """ Create two layers and add them to a LayerWidget. Then change one of the layer visibilities and verify that the layer widget appearance updates. At the time of this writing, the widget doesn't properly repaint the selected layer (all others repaint correctly). """ @classmethod def setUpClass(cls): if 'TRAVIS' in os.environ: # This test fails on Travis-CI for unknown reasons, # probably due to the variability of time.sleep(). # Skip it on Travis-CI. import nose raise nose.SkipTest cls.app = QApplication([]) cls.errors = False @classmethod def tearDownClass(cls): del cls.app def impl(self): try: # Change the visibility of the *selected* layer self.o2.visible = False # Make sure the GUI is caught up on paint events QApplication.processEvents() # We must sleep for the screenshot to be right. time.sleep(0.1) self.w.repaint() # Capture the window before we change anything beforeImg = QPixmap.grabWindow(self.w.winId()).toImage() # Change the visibility of the *selected* layer self.o2.visible = True self.w.repaint() # Make sure the GUI is caught up on paint events QApplication.processEvents() # We must sleep for the screenshot to be right. time.sleep(0.1) # Capture the window now that we've changed a layer. afterImg = QPixmap.grabWindow(self.w.winId()).toImage() # Optional: Save the files so we can inspect them ourselves... #beforeImg.save('before.png') #afterImg.save('after.png') # Before and after should NOT match. assert beforeImg != afterImg except: # Catch all exceptions and print them # We must finish so we can quit the app. import traceback traceback.print_exc() TestLayerWidget.errors = True qApp.quit() def test_repaint_after_visible_change(self): self.model = LayerStackModel() self.o1 = Layer([]) self.o1.name = "Fancy Layer" self.o1.opacity = 0.5 self.model.append(self.o1) self.o2 = Layer([]) self.o2.name = "Some other Layer" self.o2.opacity = 0.25 self.model.append(self.o2) self.view = LayerWidget(None, self.model) self.view.show() self.view.updateGeometry() self.w = QWidget() self.lh = QHBoxLayout(self.w) self.lh.addWidget(self.view) self.w.setGeometry(100, 100, 300, 300) self.w.show() self.w.raise_() # Run the test within the GUI event loop QTimer.singleShot(500, self.impl) self.app.exec_() # Were there errors? assert not TestLayerWidget.errors, "There were GUI errors/failures. See above."
widget = QWidget() gridLayout = QGridLayout() widget.setLayout(gridLayout) activeLabelA = Active_QLabel( widget, QPixmap(umbra.ui.common.getResourcePath(UiConstants.developmentIcon)), QPixmap( umbra.ui.common.getResourcePath(UiConstants.developmentHoverIcon)), QPixmap( umbra.ui.common.getResourcePath( UiConstants.developmentActiveIcon))) activeLabelB = Active_QLabel( widget, QPixmap(umbra.ui.common.getResourcePath(UiConstants.preferencesIcon)), QPixmap( umbra.ui.common.getResourcePath(UiConstants.preferencesHoverIcon)), QPixmap( umbra.ui.common.getResourcePath( UiConstants.preferencesActiveIcon)), checkable=True, checked=True) for activeLabel in (activeLabelA, activeLabelB): gridLayout.addWidget(activeLabel) widget.show() widget.raise_() sys.exit(application.exec_())
mainWindow = QWidget() def showShortcuts(): mgrDlg = ShortcutManagerDlg(mainWindow) for (group, name), keyseq in sorted(mgr.get_keyseq_reversemap().items()): print group + "." + name + " : " + keyseq mainLayout = QVBoxLayout() btn = QPushButton("Show shortcuts") btn.clicked.connect(showShortcuts) mainLayout.addWidget(btn) mainWindow.setLayout(mainLayout) mainWindow.show() mainWindow.raise_() def trigger(name): print "Shortcut triggered:", name ActionInfo = ShortcutManager.ActionInfo def registerShortcuts(mgr): mgr.register( "1", ActionInfo("Group 1", "Shortcut 1A", "Shortcut 1A", partial(trigger, "A"), mainWindow, None)) mgr.register( "2", ActionInfo("Group 1", "Shortcut 1B", "Shortcut 1B",
"Add random label\n note: \n the first added is permanent") l.addWidget(addButton) def addRandomLabel(): model.insertRow( model.rowCount(), Label( "Label {}".format(model.rowCount() + 1), QColor(numpy.random.randint(0, 255), numpy.random.randint(0, 255), numpy.random.randint(0, 255)))) addButton.clicked.connect(addRandomLabel) model.makeRowPermanent(0) w.show() w.raise_() tableView = LabelListView() tableView.support_merges = True l.addWidget(tableView) tableView.setModel(model) tableView2 = LabelListView() tableView2.setModel(model) tableView2._table.setShowGrid(True) l.addWidget(tableView2) sys.exit(app.exec_())
app = QApplication([]) mainWindow = QWidget() def showShortcuts(): mgrDlg = ShortcutManagerDlg(mainWindow) for (group, name), keyseq in sorted(mgr.get_keyseq_reversemap().items()): print group + "." + name + " : " + keyseq mainLayout = QVBoxLayout() btn = QPushButton("Show shortcuts") btn.clicked.connect( showShortcuts ) mainLayout.addWidget(btn) mainWindow.setLayout(mainLayout) mainWindow.show() mainWindow.raise_() def trigger(name): print "Shortcut triggered:",name ActionInfo = ShortcutManager.ActionInfo def registerShortcuts(mgr): mgr.register( "1", ActionInfo( "Group 1", "Shortcut 1A", "Shortcut 1A", partial(trigger, "A"), mainWindow, None ) ) mgr.register( "2", ActionInfo( "Group 1", "Shortcut 1B",
class TestLayerWidget( ut.TestCase ): """ Create two layers and add them to a LayerWidget. Then change one of the layer visibilities and verify that the layer widget appearance updates. At the time of this writing, the widget doesn't properly repaint the selected layer (all others repaint correctly). """ @classmethod def setUpClass(cls): if 'TRAVIS' in os.environ: # This test fails on Travis-CI for unknown reasons, # probably due to the variability of time.sleep(). # Skip it on Travis-CI. import nose raise nose.SkipTest cls.app = QApplication([]) cls.errors = False @classmethod def tearDownClass(cls): del cls.app def impl(self): try: # Change the visibility of the *selected* layer self.o2.visible = False # Make sure the GUI is caught up on paint events QApplication.processEvents() # We must sleep for the screenshot to be right. time.sleep(0.1) self.w.repaint() # Capture the window before we change anything beforeImg = QPixmap.grabWindow( self.w.winId() ).toImage() # Change the visibility of the *selected* layer self.o2.visible = True self.w.repaint() # Make sure the GUI is caught up on paint events QApplication.processEvents() # We must sleep for the screenshot to be right. time.sleep(0.1) # Capture the window now that we've changed a layer. afterImg = QPixmap.grabWindow( self.w.winId() ).toImage() # Optional: Save the files so we can inspect them ourselves... #beforeImg.save('before.png') #afterImg.save('after.png') # Before and after should NOT match. assert beforeImg != afterImg except: # Catch all exceptions and print them # We must finish so we can quit the app. import traceback traceback.print_exc() TestLayerWidget.errors = True qApp.quit() def test_repaint_after_visible_change(self): self.model = LayerStackModel() self.o1 = Layer([]) self.o1.name = "Fancy Layer" self.o1.opacity = 0.5 self.model.append(self.o1) self.o2 = Layer([]) self.o2.name = "Some other Layer" self.o2.opacity = 0.25 self.model.append(self.o2) self.view = LayerWidget(None, self.model) self.view.show() self.view.updateGeometry() self.w = QWidget() self.lh = QHBoxLayout(self.w) self.lh.addWidget(self.view) self.w.setGeometry(100, 100, 300, 300) self.w.show() self.w.raise_() # Run the test within the GUI event loop QTimer.singleShot(500, self.impl ) self.app.exec_() # Were there errors? assert not TestLayerWidget.errors, "There were GUI errors/failures. See above."