def __init__(self, parent, i): QtWidgets.QWizardPage.__init__(self, parent) self._i = i # Create label for description self._text_label = QtWidgets.QLabel(self) self._text_label.setTextFormat(QtCore.Qt.RichText) self._text_label.setWordWrap(True) # Create label for image self._comicLabel = QtWidgets.QLabel(self) pm = QtGui.QPixmap() if "logo" in self._image_filename: pm.load( os.path.join( pyzo.pyzoDir, "resources", "appicons", self._image_filename ) ) elif self._image_filename: pm.load( os.path.join(pyzo.pyzoDir, "resources", "images", self._image_filename) ) self._comicLabel.setPixmap(pm) self._comicLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) # Layout theLayout = QtWidgets.QVBoxLayout(self) self.setLayout(theLayout) # theLayout.addWidget(self._text_label) theLayout.addStretch() theLayout.addWidget(self._comicLabel) theLayout.addStretch()
def __init__(self, parent=None): QtWidgets.QDialog.__init__(self, parent) self.setWindowTitle("Install a conda env?") self.setModal(True) text = "Pyzo is only an editor. To execute code, you need a Python environment.\n\n" text += "Do you want Pyzo to install a Python environment (miniconda)?\n" text += "If not, you must arrange for a Python interpreter yourself" if not sys.platform.startswith("win"): text += " or use the system Python" text += "." text += "\n(You can always launch the installer from the shell menu.)" self._label = QtWidgets.QLabel(text, self) self._no = QtWidgets.QPushButton("No thanks (dont ask again)") self._yes = QtWidgets.QPushButton("Yes, please install Python!") self._no.clicked.connect(self.reject) self._yes.clicked.connect(self.accept) vbox = QtWidgets.QVBoxLayout(self) hbox = QtWidgets.QHBoxLayout() self.setLayout(vbox) vbox.addWidget(self._label, 1) vbox.addLayout(hbox, 0) hbox.addWidget(self._no, 2) hbox.addWidget(self._yes, 2) self._yes.setDefault(1)
def __init__(self, name, other): super().__init__() self.widget = other layout = QtWidgets.QHBoxLayout() layout.addWidget( QtWidgets.QLabel(text=name.capitalize().strip() + " :")) layout.addWidget(other) self.setLayout(layout)
def __init__(self, parent=None): super().__init__(parent) # File encoding self.file_encoding = QtWidgets.QLabel(self) self.file_encoding.setFixedWidth(100) self.insertPermanentWidget(0, self.file_encoding, 0) # Cursor position self.cursor_pos = QtWidgets.QLabel(self) self.cursor_pos.setFixedWidth(190) self.insertPermanentWidget(1, self.cursor_pos, 0)
def __init__(self, parent): # Do not pass parent, because is a sublayout QtWidgets.QVBoxLayout.__init__(self) # Create sub-widget self._edit1 = QtWidgets.QLineEdit(parent) self._edit1.textEdited.connect(self.onEditChanged) if sys.platform.startswith("win"): self._edit1.setPlaceholderText("C:\\path\\to\\script.py") else: self._edit1.setPlaceholderText("/path/to/script.py") # self._edit2 = QtWidgets.QTextEdit(parent) self._edit2.zoomOut(1) self._edit2.setMaximumHeight(80) self._edit2.setMinimumWidth(200) self._edit2.textChanged.connect(self.onEditChanged) # Layout self.setSpacing(1) self.addWidget(self._edit1) self.addWidget(self._edit2) # Create radio widget for system default t = translate("shell", "Use system default") self._radio_system = QtWidgets.QRadioButton(t, parent) self._radio_system.toggled.connect(self.onCheckChanged) self.addWidget(self._radio_system) if self.DISABLE_SYSTEM_DEFAULT: self._radio_system.hide() # Create radio widget for file t = translate("shell", "File to run at startup") self._radio_file = QtWidgets.QRadioButton(t, parent) self._radio_file.toggled.connect(self.onCheckChanged) self.addWidget(self._radio_file) # Create radio widget for code t = translate("shell", "Code to run at startup") self._radio_code = QtWidgets.QRadioButton(t, parent) self._radio_code.toggled.connect(self.onCheckChanged) self.addWidget(self._radio_code) # The actual value of this shell config attribute self._value = "" # A buffered version, so that clicking the text box does not # remove the value at once self._valueFile = "" self._valueCode = "\n"
def __init__(self, parent): super().__init__(parent) self._label = QtWidgets.QLabel("hello world") self._label.setTextFormat(QtCore.Qt.RichText) self._label.setWordWrap(True) # self._label.setOpenExternalLinks(True) self._label.linkActivated.connect(self.handle_link) font = self._label.font() font.setPointSize(font.pointSize() + 2) self._label.setFont(font) layout = QtWidgets.QVBoxLayout() self.setLayout(layout) layout.addWidget(self._label, 1)
def _export_pdf(self): """Exports the code as pdf, and opens file manager""" if self.editor is not None: if True: filename = QtWidgets.QFileDialog.getSaveFileName( None, "Export PDF", os.path.expanduser("~"), "*.pdf *.ps") if isinstance(filename, tuple): # PySide filename = filename[0] if not filename: return self.printer.setOutputFileName(filename) else: d = QtWidgets.QPrintDialog(self.printer) d.setWindowTitle("Print code") d.setOption(d.PrintSelection, self.editor.textCursor().hasSelection()) d.setOption(d.PrintToFile, True) ok = d.exec_() if ok != d.Accepted: return try: self._print() self.editor.print_(self.printer) except Exception as print_error: print(print_error)
def onLanguageChange(self): languageName = self._langBox.currentText() if pyzo.config.settings.language == languageName: return # Save new language pyzo.config.settings.language = languageName setLanguage(pyzo.config.settings.language) # Notify user text = translate( "wizard", """ The language has been changed for this wizard. Pyzo needs to restart for the change to take effect application-wide. """, ) m = QtWidgets.QMessageBox(self) m.setWindowTitle(translate("wizard", "Language changed")) m.setText(text) m.setIcon(m.Information) m.exec_() # Get props of current wizard geo = self.wizard().geometry() parent = self.wizard().parent() # Close ourself! self.wizard().close() # Start new one w = PyzoWizard(parent) w.setGeometry(geo) w.show()
def __init__(self, parent): QtWidgets.QTreeWidget.__init__(self, parent) self._config = parent._config # Set header stuff self.setHeaderHidden(False) self.setColumnCount(3) self.setHeaderLabels([ pyzo.translate("pyzoWorkspace", "Name"), pyzo.translate("pyzoWorkspace", "Type"), pyzo.translate("pyzoWorkspace", "Repr"), ]) # self.setColumnWidth(0, 100) self.setSortingEnabled(True) # Nice rows self.setAlternatingRowColors(True) self.setRootIsDecorated(False) # Create proxy self._proxy = WorkspaceProxy() self._proxy.haveNewData.connect(self.fillWorkspace) # For menu self.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu) self._menu = QtWidgets.QMenu() self._menu.triggered.connect(self.contextMenuTriggered) # Bind to events self.itemActivated.connect(self.onItemExpand) self._startUpVariables = ["In", "Out", "exit", "get_ipython", "quit"]
def showMenu(self, pos): menu = self._browser.createStandardContextMenu() help = QtWidgets.QAction( pyzo.icons.help, pyzo.translate("pyzoInteractiveHelp", "Help on this"), menu) help.triggered.connect(partial(self.helpOnThis, pos=pos)) menu.insertAction(menu.actions()[0], help) menu.exec(self.mapToGlobal(pos))
def __init__(self, parent, i): BasePyzoWizardPage.__init__(self, parent, i) # Create label and checkbox t1 = translate("wizard", "This wizard can be opened using 'Help > Pyzo wizard'") # t2 = translate('wizard', "Show this wizard on startup") self._label_info = QtWidgets.QLabel(t1, self) # self._check_show = QtWidgets.QCheckBox(t2, self) # self._check_show.stateChanged.connect(self._setNewUser) # Create language switcher self._langLabel = QtWidgets.QLabel(translate("wizard", "Select language"), self) # self._langBox = QtWidgets.QComboBox(self) self._langBox.setEditable(False) # Fill index, theIndex = -1, -1 cur = pyzo.config.settings.language for lang in sorted(LANGUAGES): index += 1 self._langBox.addItem(lang) if lang == LANGUAGE_SYNONYMS.get(cur, cur): theIndex = index # Set current index if theIndex >= 0: self._langBox.setCurrentIndex(theIndex) # Bind signal self._langBox.activated.connect(self.onLanguageChange) # Init check state # if pyzo.config.state.newUser: # self._check_show.setCheckState(QtCore.Qt.Checked) # Create sublayout layout = QtWidgets.QHBoxLayout() layout.addWidget(self._langLabel, 0) layout.addWidget(self._langBox, 0) layout.addStretch(2) self.layout().addLayout(layout) # Add to layout self.layout().addSpacing(10) self.layout().addWidget(self._label_info)
def __init__(self, engine): super().__init__() self._engine = engine layout = QtWidgets.QVBoxLayout(self) add_button = QtWidgets.QPushButton("Add") del_button = QtWidgets.QPushButton("Delete") self._view = QtWidgets.QListView() layout.addWidget(self._view) layout2 = QtWidgets.QHBoxLayout() layout2.addWidget(add_button) layout2.addWidget(del_button) layout.addLayout(layout2) self._model = QtCore.QStringListModel() self._view.setModel(self._model) self._model.setStringList(self._engine.registeredDocumentations()) add_button.clicked.connect(self.add_doc) del_button.clicked.connect(self.del_doc)
def __init__(self, parent): # Create sub-widget self._edit = QtWidgets.QTextEdit(parent) self._edit.zoomOut(1) self._edit.setMaximumHeight(80) self._edit.setMinimumWidth(200) self._edit.textChanged.connect(self.onEditChanged) # Instantiate ShellinfoWithSystemDefault.__init__(self, parent, self._edit)
def openColorDialog(self): """A simple function that opens a QColorDialog and link the dialog current color selection to the QLineEdit text """ dlg = QtWidgets.QColorDialog(self) dlg.setWindowTitle("Pick a color for the " + self.name.lower()) dlg.setCurrentColor(QtGui.QColor(self.text())) dlg.currentColorChanged.connect(lambda clr: self.setText(clr.name())) dlg.setModal(False) dlg.exec_()
def __init__(self, parent, distro=None): QtWidgets.QWidget.__init__(self, parent) self.setMinimumSize(360, 256) # Ensure title fits nicely # Create label widget and costumize self._label = QtWidgets.QLabel(self) self._label.setTextFormat(QtCore.Qt.RichText) self._label.setOpenExternalLinks(True) self._label.setWordWrap(True) self._label.setMargin(20) # Set font size (absolute value) font = self._label.font() font.setPointSize(11) # (font.pointSize()+1) self._label.setFont(font) # Build text_title = translate( "splash", "This is <b>Pyzo</b><br />the Python IDE for scientific computing") text_version = translate("splash", "Version") text_os = translate( "splash", "Pyzo is open source software and freely available for everyone.") text = splash_text.format( version=pyzo.__version__, text_title=text_title, text_version=text_version, text_os=text_os, ) # Set text self._label.setText(text) layout = QtWidgets.QVBoxLayout(self) self.setLayout(layout) layout.addStretch(1) layout.addWidget(self._label, 0) layout.addStretch(1)
def __init__(self, parent): QtWidgets.QWidget.__init__(self, parent) # Get config toolId = self.__class__.__name__.lower( ) + "2" # This is v2 of the file browser if toolId not in pyzo.config.tools: pyzo.config.tools[toolId] = ssdf.new() self.config = pyzo.config.tools[toolId] # Ensure three main attributes in config for name in ["expandedDirs", "starredDirs"]: if name not in self.config: self.config[name] = [] # Ensure path in config if "path" not in self.config or not isdir(self.config.path): self.config.path = op.expanduser("~") # Check expandedDirs and starredDirs. # Make path objects and remove invalid dirs. Also normalize case, # should not be necessary, but maybe the config was manually edited. expandedDirs, starredDirs = [], [] for d in self.config.starredDirs: if "path" in d and "name" in d and "addToPythonpath" in d: if isdir(d.path): d.path = op.normcase(cleanpath(d.path)) starredDirs.append(d) for p in set([str(p) for p in self.config.expandedDirs]): if isdir(p): p = op.normcase(cleanpath(p)) # Add if it is a subdir of a starred dir for d in starredDirs: if p.startswith(d.path): expandedDirs.append(p) break self.config.expandedDirs, self.config.starredDirs = expandedDirs, starredDirs # Create browser(s). self._browsers = [] for i in [0]: self._browsers.append(Browser(self, self.config)) # Layout layout = QtWidgets.QVBoxLayout(self) self.setLayout(layout) layout.addWidget(self._browsers[0]) layout.setSpacing(0) # set margins margin = pyzo.config.view.widgetMargin layout.setContentsMargins(margin, margin, margin, margin)
def __init__(self, parent): QtWidgets.QWidget.__init__(self, parent) # create toolbar self._toolbar = QtWidgets.QToolBar(self) self._toolbar.setMaximumHeight(26) self._toolbar.setIconSize(QtCore.QSize(16, 16)) # create stack self._stack = QtWidgets.QStackedWidget(self) # Populate toolbar self._shellButton = ShellControl(self._toolbar, self._stack) self._debugmode = 0 self._dbs = DebugStack(self._toolbar) # self._toolbar.addWidget(self._shellButton) self._toolbar.addSeparator() # self._toolbar.addWidget(self._dbc) -> delayed, see addContextMenu() self._interpreterhelp = InterpreterHelper(self) # widget layout layout = QtWidgets.QVBoxLayout() layout.setSpacing(0) # set margins margin = pyzo.config.view.widgetMargin layout.setContentsMargins(margin, margin, margin, margin) layout.addWidget(self._toolbar) layout.addWidget(self._stack, 0) layout.addWidget(self._interpreterhelp, 0) self.setLayout(layout) # make callbacks self._stack.currentChanged.connect(self.onCurrentChanged) self.showInterpreterHelper()
def addTab(self, title, text, rich=True): # Create label to show info label = QtWidgets.QTextEdit(self) label.setLineWrapMode(label.WidgetWidth) label.setReadOnly(True) # Set text if rich: label.setHtml(text) else: label.setText(text) # Add to tab bar self._tabs.addTab(label, title) # Done return label
def loadTool(self, toolId, splitWith=None): """Load a tool by creating a dock widget containing the tool widget.""" # A tool id should always be lower case toolId = toolId.lower() # Close old one if toolId in self._activeTools: old = self._activeTools[toolId].widget() self._activeTools[toolId].setWidget(QtWidgets.QWidget(pyzo.main)) if old: old.close() old.deleteLater() # Get tool class (returns None on failure) toolClass = self.getToolClass(toolId) if toolClass is None: return # Already loaded? reload! if toolId in self._activeTools: self._activeTools[toolId].reload(toolClass) return # Obtain name from buffered list of names for toolDes in self._toolInfo: if toolDes.id == toolId: name = toolDes.name break else: name = toolId # Make sure there is a config entry for this tool if not hasattr(pyzo.config.tools, toolId): pyzo.config.tools[toolId] = ssdf.new() # Create dock widget and add in the main window dock = ToolDockWidget(pyzo.main, self) dock.setTool(toolId, name, toolClass) if splitWith and splitWith in self._activeTools: otherDock = self._activeTools[splitWith] pyzo.main.splitDockWidget(otherDock, dock, QtCore.Qt.Horizontal) else: pyzo.main.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) # Add to list self._activeTools[toolId] = dock self.updateToolInstances()
def __add_checkBox(self, key, name): """this is a helper method to create a QCheckBox it adds the created widget (as a TitledWidget) to the layout and register a setter and listen to changes """ checkBox = QtWidgets.QCheckBox() self.setters[key] = lambda val, check=checkBox: check.setCheckState( val == "yes") checkBox.stateChanged.connect(lambda state, key=key: self.__update( key, "yes" if state else "no")) self.layout.addWidget(TitledWidget(name, checkBox))
def __init__(self, name, *args, **kwargs): """The name is displayed in the QColorDialog""" super().__init__(*args, **kwargs) self.name = name self.button = QtWidgets.QToolButton(self) self.button.setIcon(QtGui.QIcon(pyzo.icons.cog)) self.button.setStyleSheet("border: 0px; padding: 0px") self.button.clicked.connect(self.openColorDialog) frameWidth = self.style().pixelMetric( QtWidgets.QStyle.PM_DefaultFrameWidth) buttonSize = self.button.sizeHint() self.setStyleSheet("QLineEdit {padding-right: %dpx; }" % (buttonSize.width() + frameWidth + 1))
def __init__(self, parent): QtWidgets.QWidget.__init__(self, parent) # logger widget self._logger_shell = PyzoLoggerShell(self) # set layout self.layout = QtWidgets.QVBoxLayout(self) self.layout.addWidget(self._logger_shell, 1) # spacing of widgets self.layout.setSpacing(0) # set margins margin = pyzo.config.view.widgetMargin self.layout.setContentsMargins(margin, margin, margin, margin) self.setLayout(self.layout)
def __init__(self, parent=None): QtWidgets.QDialog.__init__(self, parent) self.setWindowTitle("Install miniconda") self.setModal(True) self.resize(500, 500) text = translate( "bootstrapconda", "This will download and install miniconda on your computer.", ) self._label = QtWidgets.QLabel(text, self) self._scipystack = QtWidgets.QCheckBox( translate("bootstrapconda", "Also install scientific packages"), self ) self._scipystack.setChecked(True) self._path = QtWidgets.QLineEdit(default_conda_dir, self) self._progress = QtWidgets.QProgressBar(self) self._outputLine = QtWidgets.QLabel(self) self._output = QtWidgets.QPlainTextEdit(self) self._output.setReadOnly(True) self._button = QtWidgets.QPushButton("Install", self) self._outputLine.setSizePolicy( QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed ) vbox = QtWidgets.QVBoxLayout(self) self.setLayout(vbox) vbox.addWidget(self._label, 0) vbox.addWidget(self._path, 0) vbox.addWidget(self._scipystack, 0) vbox.addWidget(self._progress, 0) vbox.addWidget(self._outputLine, 0) vbox.addWidget(self._output, 1) vbox.addWidget(self._button, 0) self._button.clicked.connect(self.go) self.addOutput(translate("bootstrapconda", "Waiting to start installation.\n")) self._progress.setVisible(False) self.lineFromStdOut.connect(self.setStatus)
def __add_comboBox(self, key, name, *items): """this is a helper method to create a comboBox it adds the created widget (as a TitledWidget) to the layout and register a setter and listen to changes """ combo = QtWidgets.QComboBox() combo.addItems(items) combo.currentTextChanged.connect( lambda txt, key=key: self.__update(key, txt)) # Note: those setters may become problematic if # someone use the synonyms (defined in codeeditor/style.py) # i.e. a stylement is of form "linestyle:dashline" # instead of the "linestyle:dashed" self.setters[key] = lambda txt, cmb=combo: cmb.setCurrentText( txt.capitalize()) self.layout.addWidget(TitledWidget(name, combo))
def __init__(self, parent): QtWidgets.QScrollArea.__init__(self, parent) # Init the scroll area self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) self.setWidgetResizable(True) self.setFrameShape(QtWidgets.QFrame.NoFrame) # Create widget and a layout self._content = QtWidgets.QWidget(parent) self._formLayout = QtWidgets.QFormLayout(self._content) # Collect classes of widgets to instantiate classes = [] for t in self.INFO_KEYS: className = "ShellInfo_" + t.key cls = globals()[className] classes.append((t, cls)) # Instantiate all classes self._shellInfoWidgets = {} for t, cls in classes: # Instantiate and store instance = cls(self._content) self._shellInfoWidgets[t.key] = instance # Create label label = QtWidgets.QLabel(t, self._content) label.setToolTip(t.tt) # Add to layout self._formLayout.addRow(label, instance) # Add delete button t = translate("shell", "Delete ::: Delete this shell configuration") label = QtWidgets.QLabel("", self._content) instance = QtWidgets.QPushButton(pyzo.icons.cancel, t, self._content) instance.setToolTip(t.tt) instance.setAutoDefault(False) instance.clicked.connect(self.parent().parent().onTabClose) deleteLayout = QtWidgets.QHBoxLayout() deleteLayout.addWidget(instance, 0) deleteLayout.addStretch(1) # Add to layout self._formLayout.addRow(label, deleteLayout) # Apply layout self._formLayout.setSpacing(15) self._content.setLayout(self._formLayout) self.setWidget(self._content)
def SetItems(parentItem, fictiveObjects, level): level += 1 for object in fictiveObjects: type = object.type if type not in showTypes and type != "nameismain": continue # Construct text if type == "import": text = "→ %s (%s)" % (object.name, object.text) elif type == "todo": text = object.name elif type == "nameismain": text = object.text elif type == "class": text = object.name elif type == "def": text = object.name + "()" elif type == "attribute": text = "- " + object.name elif type in ("cell", "##", "#%%", "# %%"): type = "cell" text = "## " + object.name + " " * 120 else: text = "%s %s" % (type, object.name) # Create item thisItem = QtWidgets.QTreeWidgetItem(parentItem, [text]) color = QtGui.QColor(colours[object.type]) thisItem.setForeground(0, QtGui.QBrush(color)) font = thisItem.font(0) font.setBold(True) if type == "cell": font.setUnderline(True) thisItem.setFont(0, font) thisItem.linenr = object.linenr # Is this the current item? if ln and object.linenr <= ln and object.linenr2 > ln: selectedItem[0] = thisItem # Any children that we should display? if object.children: SetItems(thisItem, object.children, level) # Set visibility thisItem.setExpanded(bool(level < showLevel))
def __init__(self, parent, widget): # Do not pass parent, because is a sublayout QtWidgets.QVBoxLayout.__init__(self) # Layout self.setSpacing(1) self.addWidget(widget) # Create checkbox widget if not self.DISABLE_SYSTEM_DEFAULT: t = translate("shell", "Use system default") self._check = QtWidgets.QCheckBox(t, parent) self._check.stateChanged.connect(self.onCheckChanged) self.addWidget(self._check) # The actual value of this shell config attribute self._value = "" # A buffered version, so that clicking the text box does not # remove the value at once self._bufferedValue = ""
def testWhetherFileWasChanged(self): """testWhetherFileWasChanged() Test to see whether the file was changed outside our backs, and let the user decide what to do. Returns True if it was changed. """ # get the path path = self._filename if not os.path.isfile(path): # file is deleted from the outside return # test the modification time... mtime = os.path.getmtime(path) if mtime != self._modifyTime: # ask user dlg = QtWidgets.QMessageBox(self) dlg.setWindowTitle("File was changed") dlg.setText("File has been modified outside of the editor:\n" + self._filename) dlg.setInformativeText("Do you want to reload?") t = dlg.addButton("Reload", QtWidgets.QMessageBox.AcceptRole) # 0 dlg.addButton("Keep this version", QtWidgets.QMessageBox.RejectRole) # 1 dlg.setDefaultButton(t) # whatever the result, we will reset the modified time self._modifyTime = os.path.getmtime(path) # get result and act result = dlg.exec_() if result == QtWidgets.QMessageBox.AcceptRole: self.reload() else: pass # when cancelled or explicitly said, do nothing # Return that indeed the file was changes return True
def __init__(self, parent, **kwargs): QtWidgets.QWidget.__init__(self, parent) self._left = LogoWidget(self) self._right = LabelWidget(self, **kwargs) # Layout layout = QtWidgets.QHBoxLayout(self) self.setLayout(layout) # layout.setContentsMargins(0,0,0,0) layout.setSpacing(25) layout.addStretch(1) layout.addWidget(self._left, 0) layout.addWidget(self._right, 0) layout.addStretch(1) # Change background of main window to create a splash-screen-efefct iconImage = "pyzologo256.png" iconImage = os.path.join(pyzo.pyzoDir, "resources", "appicons", iconImage) iconImage = iconImage.replace(os.path.sep, "/") # Fix for Windows self.setStyleSheet(STYLESHEET % iconImage)
def createPopupMenu(self): # Init menu menu = QtWidgets.QMenu() # Insert two items for item in ["Editors", "Shells"]: action = menu.addAction(item) action.setCheckable(True) action.setChecked(True) action.setEnabled(False) # Insert tools for tool in pyzo.toolManager.loadToolInfo(): action = menu.addAction(tool.name) action.setCheckable(True) action.setChecked(bool(tool.instance)) action.menuLauncher = tool.menuLauncher # Show menu and process result a = menu.popup(QtGui.QCursor.pos()) if a: a.menuLauncher(not a.menuLauncher(None))