def _onTvFilesCustomContextMenuRequested(self, pos ): """Connected automatically by uic """ menu = QMenu() menu.addAction( core.actionManager().action( "mFile/mClose/aCurrent" ) ) menu.addAction( core.actionManager().action( "mFile/mSave/aCurrent" ) ) menu.addAction( core.actionManager().action( "mFile/mReload/aCurrent" ) ) menu.addSeparator() # sort menu sortMenu = QMenu( self ) group = QActionGroup( sortMenu ) group.addAction( self.tr( "Opening order" ) ) group.addAction( self.tr( "File name" ) ) group.addAction( self.tr( "URL" ) ) group.addAction( self.tr( "Suffixes" ) ) group.triggered.connect(self._onSortTriggered) sortMenu.addActions( group.actions() ) for i, sortMode in enumerate(["OpeningOrder", "FileName", "URL", "Suffixes"]): action = group.actions()[i] action.setData( sortMode ) action.setCheckable( True ) if sortMode == self.model.sortMode(): action.setChecked( True ) aSortMenu = QAction( self.tr( "Sorting" ), self ) aSortMenu.setMenu( sortMenu ) aSortMenu.setIcon( QIcon( ":/enkiicons/sort.png" )) aSortMenu.setToolTip( aSortMenu.text() ) menu.addAction( sortMenu.menuAction() ) menu.exec_( self.tvFiles.mapToGlobal( pos ) )
def _update(self, action: QAction, initialize: bool): """updates the internal values from the given action.""" if not self._action: return self._disconnectAction() self.changed.disconnect(self._updateToolTipWithKeySequence) if initialize: self.setSeparator(action.isSeparator()) self.setMenuRole(action.menuRole()) if self.hasAttribute(ProxyActionAttribute.UpdateIcon) or initialize: self.setIcon(action.icon()) self.setIconText(action.iconText()) self.setIconVisibleInMenu(action.isIconVisibleInMenu()) if self.hasAttribute(ProxyActionAttribute.UpdateText) or initialize: self.setText(action.text()) self._toolTip = action.toolTip() self._updateToolTipWithKeySequence() self.setStatusTip(action.statusTip()) self.setWhatsThis(action.whatsThis()) self.setCheckable(action.isCheckable()) if not initialize: self.setChecked(action.isChecked()) self.setEnabled(action.isEnabled()) self.setVisible(action.isVisible()) self._connectAction() self.changed.connect(self._updateToolTipWithKeySequence)
def __msgActionWarning(self, newAction: QAction, actionId: ItemId, oldAction: QAction or None): """ :returns: a Warning text with the given Action's and ItemId's properties :param newAction: Action to take strings from :param actionId: ItemId to take strings from """ oldActionMsg = " {}/{}".format(oldAction.objectName(), oldAction.text()) if oldAction else "" msg = "addOverrideAction {}/{}: Action{} is already registered for context {} {}.".format( newAction.objectName(), newAction.text(), oldActionMsg, actionId.uniqueIdentifier, actionId.toSetting()) return msg
def _onTvFilesCustomContextMenuRequested(self, pos): """Connected automatically by uic """ menu = QMenu() menu.addAction(core.actionManager().action("mFile/mClose/aCurrent")) menu.addAction(core.actionManager().action("mFile/mSave/aCurrent")) menu.addAction(core.actionManager().action("mFile/mReload/aCurrent")) menu.addSeparator() # sort menu sortMenu = QMenu(self) group = QActionGroup(sortMenu) group.addAction(self.tr("Opening order")) group.addAction(self.tr("File name")) group.addAction(self.tr("URL")) group.addAction(self.tr("Suffixes")) group.triggered.connect(self._onSortTriggered) sortMenu.addActions(group.actions()) for i, sortMode in enumerate( ["OpeningOrder", "FileName", "URL", "Suffixes"]): action = group.actions()[i] action.setData(sortMode) action.setCheckable(True) if sortMode == self.model.sortMode(): action.setChecked(True) aSortMenu = QAction(self.tr("Sorting"), self) aSortMenu.setMenu(sortMenu) aSortMenu.setIcon(QIcon(":/enkiicons/sort.png")) aSortMenu.setToolTip(aSortMenu.text()) menu.addAction(sortMenu.menuAction()) menu.exec_(self.tvFiles.mapToGlobal(pos))
class InputSinkUI(SinkUI): def __init__(self, parent): self.mouse_pressed = False SinkUI.__init__(self, parent) self.setAcceptDrops(False) self.setContentsMargins(0,0,0,0) self.layout.setContentsMargins(6,2,6,0) def createMute(self): self.mute = InputMuteButton(self) self.mute.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed,True)) self.connect(self.mute, SIGNAL("clicked()"), self.on_mute_cb) def context_menu_create_custom(self): self.create_menu_switch_sink() self.create_menu_ladspa_effects() def create_menu_kill_sink(self): self.action_kill = QAction(i18n("Disconnect/kill"), self.popup_menu) self.popup_menu.addAction(self.action_kill) self.action_kill.triggered.connect(self.on_contextmenu_clicked) def context_menu_create_settings(self): pass def create_menu_switch_sink(self): sink_menu = QMenu(i18n("Move To"), self.popup_menu) sinks = self.veromix.get_sink_widgets() for sink in sinks: action = QAction(sink.name(), self.popup_menu) sink_menu.addAction(action) self.popup_menu.addMenu(sink_menu) def create_menu_ladspa_effects(self): if not self.veromix.is_ladspa_enabled(): return def context_menu_create_effects(self): pass def on_contextmenu_clicked(self, action): if type(action) == bool: return if action.text() == self.action_kill.text(): self.sink_input_kill() return 0 # search ouputs for text, and move sink_input for sink in self.veromix.get_sink_widgets(): if action.text() == sink.name(): self.pa.move_sink_input(self.index, int(sink.index)) return 0 def getOutputIndex(self): return self.pa_sink.props["sink"] def update_label(self): text = self.pa_sink.name bold = self.pa_sink.props["app"] iconname = None if self.pa_sink.props["app_icon"] != "None": iconname = self.pa_sink.props["app_icon"] if iconname == None and self.pa_sink.props["app"] != "None": iconname = self.veromix.query_application(self.pa_sink.props["app"]) if bold == "knotify": bold = i18n("Event Sounds") text = "" iconname = 'dialog-information' if bold == "npviewer.bin" or bold == "plugin-container": bold = i18n("Flash Player") text = "" iconname = 'flash' if bold == "chromium-browser": bold = i18n("Chromium Browser") text = "" if bold == "Skype": if text == "Event Sound": text = i18n("Event Sound") if text == "Output": text = i18n("Voice Output") if text == "LADSPA Stream" or (self.pa_sink.props["media.name"] == "LADSPA Stream"): for sink in self.veromix.get_sink_widgets(): if sink.pa_sink.props["owner_module"] == self.pa_sink.props["owner_module"]: bold = sink.pa_sink.props["device.ladspa.name"] text = "" iconname = sink.pa_sink.props["device.icon_name"] # FIXME if bold in ["", "None", None]: bold = text text = "" if text in ["None", None]: text = "" if iconname in ["", "None", None]: iconname = "mixer-pcm" if iconname : self.mute.setBigIconName(iconname) self.updateIcon() if self.slider: self.set_name(bold) self.slider.setText(text) self.slider.setBoldText(bold) ### Drag and Drop def mousePressEvent(self, event): self.mouse_pressed = True def mouseReleaseEvent(self, event): self.mouse_pressed = False def mouseMoveEvent(self,e): if self.mouse_pressed : self.startDrag(e) def startDrag(self,event): drag = QDrag(event.widget()) drag.setPixmap(self.mute.icon().pixmap(self.size().height(),self.size().height())) mimedata = QMimeData() liste = [] liste.append(QUrl( "veromix://sink_input_index:" + str(int(self.index)))) mimedata.setUrls(liste) drag.setMimeData(mimedata) #drag.setHotSpot(event.pos() - self.rect().topLeft()) dropAction = drag.start(Qt.MoveAction)
def createuiaction(self): action = QAction(QIcon(self.icon), self.icontext, None) if not self.valid[0]: action.setEnabled(False) action.setText(action.text() + " (invalid)") return action
class FeatureFormBase(QWidget): requiredfieldsupdated = pyqtSignal(bool) formvalidation = pyqtSignal(bool) helprequest = pyqtSignal(str) showwidget = pyqtSignal(QWidget) loadform = pyqtSignal() rejected = pyqtSignal(str, int) accepted = pyqtSignal() enablesave = pyqtSignal(bool) showlargewidget = pyqtSignal(object, object, object, dict) def __init__(self, form, formconfig, feature, defaults, parent, *args, **kwargs): super(FeatureFormBase, self).__init__(parent) self.form = form self.formconfig = formconfig self.boundwidgets = CaseInsensitiveDict() self.requiredfields = CaseInsensitiveDict() self.feature = feature self.geomwidget = None self.defaults = defaults self.bindingvalues = CaseInsensitiveDict() self.editingmode = kwargs.get("editmode", False) self.widgetidlookup = {} self._has_save_buttons = False self.star_all_button = QAction(QIcon(":/icons/save_default_all"), "Star All", self, triggered=self.star_all) def open_large_widget(self, widgettype, lastvalue, callback, config=None): self.showlargewidget.emit(widgettype, lastvalue, callback, config) def form_actions(self): builtin = [] if self._has_save_buttons: builtin.append(self.star_all_button) useractions = self.user_form_actions() if not useractions: useractions = [] return builtin + useractions def star_all(self): """ Star or unstar all buttons on the form. :param star_all: True to star all buttons on the form. """ checked = self.star_all_button.text() == "Star All" buttons = self._field_save_buttons() for button in buttons: button.setChecked(checked) if checked: self.star_all_button.setText("Star None") else: self.star_all_button.setText("Star All") @property def is_capturing(self): return self.editingmode == False @is_capturing.setter def is_capturing(self, value): self.editingmode = not value def updaterequired(self, value): passed = self.allpassing self.formvalidation.emit(passed) def validateall(self): widgetwrappers = self.boundwidgets.itervalues() for wrapper in widgetwrappers: wrapper.validate() def setupui(self): """ Setup the widget in the form """ self.geomwidget = self.findcontrol("__geomwidget") widgetsconfig = copy.deepcopy(self.formconfig['widgets']) try: widgetsconfig = self.get_widgets(widgetsconfig) except AttributeError: pass layer = self.form.QGISLayer # Crash in QGIS if you lookup a field that isn't found. # We just make a dict with all fields lower because QgsFields is case sensitive. fields = {field.name().lower(): field for field in layer.pendingFields().toList()} # Build a lookup for events self.events = collections.defaultdict(list) for event in self.form.events: self.events[event['source']].append(event) widgetsconfig = copy.deepcopy(widgetsconfig) self.sectionwidgets = {} currentsection = None for config in widgetsconfig: widgettype = config['widget'] if widgettype == "Section": name = config['name'] currentsection = name self.sectionwidgets[name] = [] continue field = config['field'] if not field: utils.info("Skipping widget. No field defined") continue field = field.lower() if field in self.boundwidgets: utils.warning("Can't bind the same field ({}) twice.".format(field)) continue widget = self.findcontrol(field) if widget is None: widget = roam.editorwidgets.core.createwidget(widgettype) config['hidden'] = True utils.info("No widget named {} found so we have made one.".format(field)) label = self.findcontrol("{}_label".format(field)) if label is None: utils.debug("No label found for {}".format(field)) widgetconfig = config.get('config', {}) widgetconfig['formwidget'] = self try: qgsfield = fields[field] except KeyError: utils.log("No field for ({}) found".format(field)) context = dict(project=self.form.project, form=self.form, featureform=self) try: widgetwrapper = roam.editorwidgets.core.widgetwrapper(widgettype=widgettype, layer=self.form.QGISLayer, field=qgsfield, widget=widget, label=label, config=widgetconfig, context=context) except EditorWidgetException as ex: utils.exception(ex) continue widgetwrapper.default_events = config.get('default_events', ['capture']) readonlyrules = config.get('read-only-rules', []) if self.editingmode and 'editing' in readonlyrules: widgetwrapper.readonly = True elif 'insert' in readonlyrules or 'always' in readonlyrules: widgetwrapper.readonly = True widgetwrapper.hidden = config.get('hidden', False) widgetwrapper.newstyleform = self.formconfig.get("newstyle", False) widgetwrapper.required = config.get('required', False) widgetwrapper.id = config.get('_id', '') # Only connect widgets that have events if widgetwrapper.id in self.events: widgetwrapper.valuechanged.connect(partial(self.check_for_update_events, widgetwrapper)) widgetwrapper.valuechanged.connect(self.updaterequired) try: changedslot = getattr(self, "widget_{}_changed".format(field)) widgetwrapper.valuechanged.connect(changedslot) except AttributeError: pass widgetwrapper.largewidgetrequest.connect(RoamEvents.show_widget.emit) self._bindsavebutton(field) self.boundwidgets[field] = widgetwrapper try: self.widgetidlookup[config['_id']] = widgetwrapper except KeyError: pass if currentsection: self.sectionwidgets[currentsection].append(widgetwrapper) def widgets_for_section(self, name): try: return self.sectionwidgets[name] except KeyError: return [] def get_widget_from_id(self, id): try: return self.widgetidlookup[id] except KeyError: return None def check_for_update_events(self, widget, value): if not self.feature: return from qgis.core import QgsExpression, QgsExpressionContext, QgsExpressionContextScope # If we don't have any events for this widgets just get out now if not widget.id in self.events: return events = self.events[widget.id] events = [event for event in events if event['event'].lower() == 'update'] if not events: return feature = self.to_feature(no_defaults=True) for event in events: action = event['action'].lower() targetid = event['target'] if targetid == widget.id: utils.log("Can't connect events to the same widget. ID {}".format(targetid)) continue widget = self.get_widget_from_id(targetid) if not widget: utils.log("Can't find widget for id {} in form".format(targetid)) continue condition = event['condition'] expression = event['value'] context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable("value", value) scope.setVariable("field", widget.field) context.setFeature(feature) context.appendScope(scope) conditionexp = QgsExpression(condition) exp = QgsExpression(expression) if action.lower() == "show": widget.hidden = not conditionexp.evaluate(context) if action.lower() == "hide": widget.hidden = conditionexp.evaluate(context) if action == 'widget expression': if conditionexp.evaluate(context): newvalue = self.widget_default(field, feature=feature) widget.setvalue(newvalue) if action == 'set value': if conditionexp.evaluate(context): newvalue = exp.evaluate(context) widget.setvalue(newvalue) def bindvalues(self, values, update=False): """ Bind the values to the form. """ if not update: self.bindingvalues = CaseInsensitiveDict(values) else: for key, value in values.iteritems(): try: self.bindingvalues[key] = value except KeyError: continue for field, value in values.iteritems(): value = nullcheck(value) try: wrapper = self.boundwidgets[field] if hasattr(wrapper, 'savetofile') and wrapper.savetofile: if value and not os.path.exists(value): value = os.path.join(self.form.project.image_folder, value) self.boundwidgets[field].setvalue(value) except KeyError: utils.debug("Can't find control for field {}. Ignoring".format(field)) self.validateall() if self.geomwidget and self.feature: self.geomwidget.set_geometry(self.feature.geometry()) def bind_feature(self, feature): self.feature = feature values = self.form.values_from_feature(feature) self.bindvalues(values) def getvalues(self, no_defaults=False): def shouldsave(field): name = "{}_save".format(field) button = self.findcontrol(name) if not button is None: return button.isChecked() savedvalues = {} values = CaseInsensitiveDict(self.bindingvalues) for field, wrapper in self.boundwidgets.iteritems(): if not no_defaults and wrapper.get_default_value_on_save: value = self.widget_default(field) else: value = wrapper.value() extradata = wrapper.extraData() values.update(extradata) # TODO this should put pulled out and unit tested. MOVE ME! # NOTE: This is photo widget stuff and really really doesn't belong here. if hasattr(wrapper, 'savetofile') and wrapper.savetofile and wrapper.saveable: if wrapper.filename and self.editingmode: name = os.path.basename(wrapper.filename) name, extension = os.path.splitext(name) if wrapper.modified: if not name.endswith("_edited"): newend = "_edited{}".format(extension) value = name + newend else: value = os.path.basename(wrapper.filename) else: value = os.path.basename(wrapper.filename) else: if wrapper.modified: value = wrapper.get_filename() else: value = '' if shouldsave(field): savedvalues[field] = value values[field] = value return values, savedvalues def findcontrol(self, name, all=False): regex = QRegExp("^{}$".format(QRegExp.escape(name))) regex.setCaseSensitivity(Qt.CaseInsensitive) try: if all: return self.findChildren(QWidget, regex) else: widget = self.findChildren(QWidget, regex)[0] except IndexError: widget = None return widget def _field_save_buttons(self): """ Return all the save buttons for the form. :return: """ for field in self.boundwidgets.keys(): name = "{}_save".format(field) savebutton = self.findcontrol(name) if savebutton: yield savebutton def _bindsavebutton(self, field): name = "{}_save".format(field) button = self.findcontrol(name) if button is None: return button.setCheckable(not self.editingmode) button.setIcon(QIcon(":/icons/save_default")) button.setIconSize(QSize(24, 24)) button.setChecked(field in self.defaults) button.setVisible(not self.editingmode) self._has_save_buttons = True def createhelplinks(self): def createhelplink(label, folder): def getHelpFile(): # TODO We could just use the tooltip from the control to show help # rather then having to save out a html file. name = label.objectName() if name.endswith("_label"): name = name[:-6] filename = "{}.html".format(name) filepath = os.path.join(folder, "help", filename) if os.path.exists(filepath): return filepath else: return None if label is None: return helpfile = getHelpFile() if helpfile: text = '<a href="{}">{}<a>'.format(helpfile, label.text()) label.setText(text) label.linkActivated.connect(self.helprequest.emit) for label in self.findChildren(QLabel): createhelplink(label, self.form.folder) def widget_default(self, name, feature=None): """ Return the default value for the given widget """ try: widgetconfig = self.form.widget_by_field(name) except IndexError: raise KeyError("Widget with name {} not found on form".format(name)) if not 'default' in widgetconfig: raise KeyError('Default value not defined for this field {}'.format(name)) if not feature: feature = self.feature return defaults.widget_default(widgetconfig, feature, self.form.QGISLayer) def close_form(self, reason=None, level=1): self.rejected.emit(reason, level) def to_feature(self, no_defaults=False): """ Create a QgsFeature from the current form values """ if not self.feature: return feature = QgsFeature(self.feature.fields()) feature.setGeometry(QgsGeometry(self.feature.geometry())) try: values, _ = self.getvalues(no_defaults=no_defaults) except TypeError: values, _ = self.getvalues() self.updatefeautrefields(feature, values) self.update_geometry(feature) return feature
class QMPCApp(QObject): __images__ = { 'background': "images/background.png", } __icons__ = { 'homeButton': "general_backspace", 'volumeButton': "general_speaker", 'settingsButton': "keyboard_menu", 'prevButton': "/etc/hildon/theme/mediaplayer/Back.png", 'prevButtonPressed': "/etc/hildon/theme/mediaplayer/BackPressed.png", 'playButton': "/etc/hildon/theme/mediaplayer/Play.png", 'pauseButton': "/etc/hildon/theme/mediaplayer/Pause.png", 'stopButton': "/etc/hildon/theme/mediaplayer/Stop.png", 'stopButtonPressed': "/etc/hildon/theme/mediaplayer/StopPressed.png", 'nextButton': "/etc/hildon/theme/mediaplayer/Forward.png", 'nextButtonPressed': "/etc/hildon/theme/mediaplayer/ForwardPressed.png", 'repeatButton': "/etc/hildon/theme/mediaplayer/Repeat.png", 'repeatButtonPressed': "/etc/hildon/theme/mediaplayer/RepeatPressed.png", 'shuffleButton': "/etc/hildon/theme/mediaplayer/Shuffle.png", 'shuffleButtonPressed': "/etc/hildon/theme/mediaplayer/ShufflePressed.png", } def __init__(self): super(QMPCApp,self).__init__() self.mw = None self.initData() self.initMPD() self.initActions() self.initGUI() QTimer.singleShot(100,self.deferredStart) def deferredStart(self): if self.data.autoconnect: self.connectMPD() def initData(self): self.selectedServerName = None self.data = DataModel() self.data.loadSettings() self.imagehelper = ImageHelper(images=self.__images__, icons=self.__icons__) QApplication.instance().aboutToQuit.connect(self.data.saveSettings) def initActions(self): self.actionPlayer = QAction("Player", self) self.actionPlayer.triggered.connect( lambda: self.showWidget(self.player)) self.actionPlaylist = QAction("Playlist",self) self.actionPlaylist.triggered.connect( lambda: self.showWidget(self.playlist)) self.actionBrowser = QAction("Browser",self) self.actionBrowser.triggered.connect( lambda: self.showWidget(self.browser)) self.actionOutputs = QAction("Outputs",self) self.actionOutputs.triggered.connect(self.showOutputs) self.actionStats = QAction("Statistics",self) self.actionStats.triggered.connect(self.showStats) self.actionPrefs = QAction("Preferences",self) self.actionPrefs.triggered.connect(self.showPrefs) self.actionConnect = QAction("Connect",self) self.actionConnect.triggered.connect(self.connectActivated) def initGUI(self): self.initStartScreen() self.initWidgets() if not have_maemo: self.mw = QMainWindow() menu = self.mw.menuBar() menufile = menu.addMenu("&File") menuwindows = menu.addMenu("&Windows") self.mw.statusBar() menuwindows.addAction(self.actionPlayer) menuwindows.addAction(self.actionPlaylist) menuwindows.addAction(self.actionBrowser) menuwindows.addAction(self.actionOutputs) menuwindows.addAction(self.actionStats) menufile.addAction(self.actionConnect) menufile.addAction(self.actionPrefs) menufile.addSeparator() menufile.addAction("&Quit", QApplication.quit) self.setConnectionState(False) def initStartScreen(self): self.startscreen = StartScreen(self) self.startscreen.clicked.connect(self.connectActivated) if have_maemo: menu = QMenuBar(self.startscreen) menu.addAction(self.actionConnect) menu.addAction(self.actionPrefs) def initWidgets(self): # create subwidgets self.player = Player(self) self.playlist = Playlist(self) self.browser = Browser(self) if have_maemo: # build Maemo stack hierarchy self.playlist.setParent(self.player) self.browser.setParent(self.player) for w in [ self.player, self.playlist, self.browser ]: w.setAttribute( Qt.WA_Maemo5StackedWindow) w.setWindowFlags( w.windowFlags() | Qt.Window) # add menu bar menu = QMenuBar(self.player) menu.addAction(self.actionPlaylist) menu.addAction(self.actionBrowser) menu.addAction(self.actionStats) menu.addAction(self.actionOutputs) menu.addAction(self.actionPrefs) menu.addAction(self.actionConnect) else: self.stack = QStackedWidget() for w in [ self.player, self.playlist, self.browser ]: w.setParent(self.stack) self.stack.addWidget(w) def switchView(self, connected): if have_maemo: if connected: self.player.show() self.startscreen.hide() else: self.startscreen.show() else: cw = self.mw.centralWidget() if cw: cw.setParent(None) cw.hide() if connected: self.mw.setCentralWidget(self.stack) self.stack.show() self.showWidget(self.player) else: self.mw.setCentralWidget(self.startscreen) self.startscreen.show() self.mw.show() def showWidget(self,widget): if not have_maemo: self.stack.setCurrentWidget(widget) widget.show() def connectActivated(self): if self.actionConnect.text() == "Connect": self.connectMPD() else: self.disconnectMPD() def initMPD(self): self.mpd = MPDWrapper() self.mpdtimer = None def connectMPD(self,reconnect=False): selected = self.data.selectedServer() if not len(selected): InformationBox.information( self.mw, "Select server to connect") self.showPrefs() selected = self.data.selectedServer() if len(selected): name, address, port = selected try: if not reconnect: InformationBox.information( self.mw, "Connecting to <b>%s</b>" % name) QApplication.processEvents() self.mpd.timeout = 10 self.mpd.connect( str(address), int(port)) if not reconnect: InformationBox.information( self.mw, "Connected to <b>%s</b>" % name) QApplication.processEvents() self.setConnectionState(True) self.selectedServerName = name self.mpdtimer = self.startTimer(5000) except socket.timeout, e: self.setConnectionState(False) InformationBox.information( self.mw, "%s: %s" %(name,e)) QApplication.processEvents() except socket.gaierror, e: self.setConnectionState(False) InformationBox.information( self.mw, "%s: %s" %(name,e[1])) QApplication.processEvents() except socket.error, e: self.setConnectionState(False) InformationBox.information( self.mw, "%s: %s" %(name,e[1])) QApplication.processEvents()