Ejemplo n.º 1
0
def execute_after_millis(millis, func):

    def register_timer():
        assert is_in_main_thread(), \
            'We can only create QTimers in the main thread '\
            '(or at least delete them in the same thread).'

        with _timers_lock:
            existing_timer = _timers_alive.get(func)
            if existing_timer is not None:
                timer = existing_timer.timer
                if timer is not None:
                    try:
                        timer.stop()
                        timer.start(millis)
                    except Exception:
                        pass
                    return  # Restart it!

            timer = QTimer()
            timer_alive = _TimerAlive(func, timer)
            _timers_alive[func] = timer_alive

            timer.setSingleShot(True)
            timer.timeout.connect(timer_alive)
            timer.start(millis)

    if not is_in_main_thread():
        from pyvmmonitor_qt.qt_event_loop import execute_on_next_event_loop
        execute_on_next_event_loop(register_timer)
    else:
        register_timer()
Ejemplo n.º 2
0
def assert_condition_within_timeout(condition, timeout=2.):

    '''
    :param callable condition:
        A callable which may return a bool or a string (if True or an empty
        string, the condition is considered matched).

    :param float timeout:
        Timeout in seconds
    '''
    assert is_in_main_thread()
    initial = time.time()
    while True:
        c = condition()
        if isinstance(c, bool):
            if c:
                return
        elif isinstance(c, (compat.bytes, compat.unicode)):
            if not c:
                return
        else:
            raise AssertionError('Expecting bool or string as the return.')

        if time.time() - initial > timeout:
            raise AssertionError(
                u'Could not reach condition before timeout: %s (condition return: %s)' %
                (timeout, c))

        # from pyvmmonitor_qt.qt_event_loop import process_events
        # process_events()

        from pyvmmonitor_qt.qt_event_loop import process_queue
        process_queue()
        time.sleep(1 / 50.)
Ejemplo n.º 3
0
    def set_selection(self, obj_ids, clear_selection=True):
        from pyvmmonitor_qt.qt.QtCore import QModelIndex
        from pyvmmonitor_qt.qt.QtCore import QItemSelection
        from pyvmmonitor_qt.qt.QtCore import QItemSelectionModel

        assert thread_utils.is_in_main_thread()
        selection_model = self.tree.selectionModel()

        selection = None
        for obj_id in obj_ids:

            item = self._fast.get(obj_id)
            if item is not None:
                index = item._items[0].index()
                if index is not None:
                    index = self._sort_model.mapFromSource(index)
                    if selection is None:
                        selection = QItemSelection(index, index)
                    else:
                        selection.select(index, index)

        if selection:
            if not clear_selection:
                selection_model.select(
                    selection,
                    QItemSelectionModel.Select | QItemSelectionModel.Rows)
            else:
                selection_model.select(
                    selection, QItemSelectionModel.ClearAndSelect
                    | QItemSelectionModel.Current | QItemSelectionModel.Rows)
        else:
            if clear_selection:
                selection_model.select(QModelIndex(),
                                       QItemSelectionModel.Clear)
Ejemplo n.º 4
0
def execute_after_millis(millis, func):

    def register_timer():
        assert is_in_main_thread(), \
            'We can only create QTimers in the main thread '\
            '(or at least delete them in the same thread).'

        with _timers_lock:
            existing_timer = _timers_alive.get(func)
            if existing_timer is not None:
                timer = existing_timer.timer
                if timer is not None:
                    try:
                        timer.stop()
                        timer.start(millis)
                    except Exception:
                        pass
                    return  # Restart it!

            timer = QTimer()
            timer_alive = _TimerAlive(func, timer)
            _timers_alive[func] = timer_alive

            timer.setSingleShot(True)
            timer.timeout.connect(timer_alive)
            timer.start(millis)

    if not is_in_main_thread():
        from pyvmmonitor_qt.qt_event_loop import execute_on_next_event_loop
        execute_on_next_event_loop(register_timer)
    else:
        register_timer()
Ejemplo n.º 5
0
    def set_selection(self, obj_ids, clear_selection=True):
        from pyvmmonitor_qt.qt.QtCore import QModelIndex
        from pyvmmonitor_qt.qt.QtCore import QItemSelection
        from pyvmmonitor_qt.qt.QtCore import QItemSelectionModel

        assert thread_utils.is_in_main_thread()
        selection_model = self.tree.selectionModel()

        selection = None
        for obj_id in obj_ids:

            item = self._fast.get(obj_id)
            if item is not None:
                index = item._items[0].index()
                if index is not None:
                    index = self._sort_model.mapFromSource(index)
                    if selection is None:
                        selection = QItemSelection(index, index)
                    else:
                        selection.select(index, index)

        if selection:
            if not clear_selection:
                selection_model.select(
                    selection,
                    QItemSelectionModel.Select | QItemSelectionModel.Rows)
            else:
                selection_model.select(
                    selection,
                    QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Current |
                    QItemSelectionModel.Rows)
        else:
            if clear_selection:
                selection_model.select(QModelIndex(), QItemSelectionModel.Clear)
Ejemplo n.º 6
0
def assert_condition_within_timeout(condition, timeout=2.):

    '''
    :param callable condition:
        A callable which may return a bool or a string (if True or an empty
        string, the condition is considered matched).

    :param float timeout:
        Timeout in seconds
    '''
    assert is_in_main_thread()
    initial = time.time()
    while True:
        c = condition()
        if isinstance(c, bool):
            if c:
                return
        elif isinstance(c, (compat.bytes, compat.unicode)):
            if not c:
                return
        else:
            raise AssertionError('Expecting bool or string as the return.')

        if time.time() - initial > timeout:
            raise AssertionError(
                u'Could not reach condition before timeout: %s (condition return: %s)' %
                (timeout, c))

        # from pyvmmonitor_qt.qt_event_loop import process_events
        # process_events()

        from pyvmmonitor_qt.qt_event_loop import process_queue
        process_queue()
        time.sleep(1 / 50.)
Ejemplo n.º 7
0
    def __init__(self):
        assert is_in_main_thread()
        QObject.__init__(self)
        self._collector = GarbageCollector()

        timer = self.timer = QTimer()
        timer.timeout.connect(self.check)
        timer.start(self.INTERVAL)
Ejemplo n.º 8
0
    def __call__(self, *args, **kwargs):  # @DontTrace
        '''
        Calls every registered function with the given args and kwargs.
        '''
        callbacks = self._callbacks
        if not callbacks:
            return

        # Note: There's a copy of this code in the _calculate_to_call method below. It's a copy
        # because we don't want to had a function call overhead here.
        to_call = []

        for key, info in compat.items(callbacks):  # iterate in a copy

            func_obj = info[0]
            if func_obj is not None:
                # Ok, we have a self.
                func_obj = func_obj()
                if func_obj is None:
                    # self is dead
                    del callbacks[key]
                else:
                    func_func = info[1]
                    if func_func is None:
                        to_call.append(func_obj)
                    else:
                        if compat.PY2:
                            to_call.append(
                                new.instancemethod(func_func, func_obj,
                                                   info[2]))
                        else:
                            to_call.append(new.MethodType(func_func, func_obj))

            else:
                func_func = info[1]

                # No self: either classmethod or just callable
                to_call.append(func_func)

        # let's keep the 'if' outside of the iteration...
        if not is_in_main_thread():
            for func in to_call:
                if not getattr(func, '__call_out_of_main_thread__', False):
                    raise AssertionError(
                        'Call: %s out of the main thread (and it is not marked as @not_main_thread_callback)!'
                        % (func, ))

        for func in to_call:
            try:
                func(*args, **kwargs)
            except Exception:  # Show it but don't propagate.
                sys.excepthook(*sys.exc_info())
    def __setitem__(self, obj_id, obj):
        assert thread_utils.is_in_main_thread()
        assert obj_id not in self._fast

        try:
            i = obj_id.rindex('.')
        except ValueError:
            parent_node = self._root
        else:
            parent_node = self._fast[obj_id[:i]]

        self._add_child_node(parent_node, obj_id, obj)
        return obj
    def add_child(self, root_id, prefix, obj):
        assert thread_utils.is_in_main_thread()

        if root_id:
            parent_node = self._fast[root_id]
            prefix = '%s.%s' % (root_id, prefix)
        else:
            parent_node = self._root

        obj_id = '%s%03d' % (prefix, parent_node.next_id(prefix))
        while obj_id in self._fast:
            obj_id = '%s%03d' % (prefix, parent_node.next_id(prefix))

        self._add_child_node(parent_node, obj_id, obj)
        return obj
Ejemplo n.º 11
0
    def get_selection(self):
        '''
        :return list(unicode):
            Returns a list with the selected items.
        '''
        assert thread_utils.is_in_main_thread()
        new_selection = []
        selected_indexes = self.tree.selectedIndexes()

        if selected_indexes:
            nodes = set()
            for i in selected_indexes:
                node = i.data(_NODE_ROLE)
                if node not in nodes:
                    nodes.add(node)
                    if node is not None:
                        obj_id = node.obj_id
                        new_selection.append(obj_id)
        return new_selection
Ejemplo n.º 12
0
    def get_selection(self):
        '''
        :return list(unicode):
            Returns a list with the selected items.
        '''
        assert thread_utils.is_in_main_thread()
        new_selection = []
        selected_indexes = self.tree.selectedIndexes()

        if selected_indexes:
            nodes = set()
            for i in selected_indexes:
                node = i.data(_NODE_ROLE)
                if node not in nodes:
                    nodes.add(node)
                    if node is not None:
                        obj_id = node.obj_id
                        new_selection.append(obj_id)
        return new_selection
    def set_selection(self, source, selection):
        if isinstance(selection, basestring):
            selection = (selection,)

        # Note: besides removing the duplicates, will also convert the type to a tuple.
        selection = remove_duplicates(selection, ret_type=tuple)

        assert isinstance(selection, tuple)

        assert is_in_main_thread(), 'Can only change selection in main thread.'

        if selection == self._selection:
            if not self.reselect_on_same_selection:
                return False

        self._selection = selection
        self._source = source

        self._do_selection(source, selection)
        return True
Ejemplo n.º 14
0
def process_events(collect=False, handle_future_events=False):
    from pyvmmonitor_core.thread_utils import is_in_main_thread
    from pyvmmonitor_qt.qt.QtCore import QTimer
    from .qt_app import obtain_qapp

    assert is_in_main_thread()

    if not collect:
        obtain_qapp().processEvents()

    else:
        app = obtain_qapp()
        timer = QTimer()
        timer.setSingleShot(True)
        timer.timeout.connect(app.exit)
        timer.start(0)
        app.exec_()

    if handle_future_events:
        process_queue(handle_future_events=True)
Ejemplo n.º 15
0
def process_events(collect=False, handle_future_events=False):
    from pyvmmonitor_core.thread_utils import is_in_main_thread
    from pyvmmonitor_qt.qt.QtCore import QTimer
    from .qt_app import obtain_qapp

    assert is_in_main_thread()

    if not collect:
        obtain_qapp().processEvents()

    else:
        app = obtain_qapp()
        timer = QTimer()
        timer.setSingleShot(True)
        timer.timeout.connect(app.exit)
        timer.start(0)
        app.exec_()

    if handle_future_events:
        process_queue(handle_future_events=True)
Ejemplo n.º 16
0
    def add_node(self, parent_node, obj_id, node, index=-1):
        '''
        Adds a node to the tree below the passed parent.

        :param TreeNode|unicode|NoneType parent_node:
            If None is passed, it'll be added to the root, otherwise, it'll be added to
            the passed node (which can be passed directly or through its id).

        :param unicode obj_id:
            The id for this node.

        :param object|TreeNode node:
            Either the instanced TreeNode to be added or the data for which a TreeNode
            should be created.

        :param int index:
            The index at which the child node should be added.
        '''
        if isinstance(parent_node, compat.unicode):
            parent_node = self._fast[parent_node]

        if not isinstance(node, TreeNode):
            node = TreeNode(node)

        assert thread_utils.is_in_main_thread()
        assert obj_id not in self._fast
        if parent_node is None:
            items = node._attach_to_tree(self, obj_id)
            if index == -1:
                self._model.appendRow(items)
            else:
                assert index >= 0
                self._model.insertRow(index, items)
            self._root_items.add(node)
        else:
            items = node._attach_to_tree(self, obj_id)
            parent_node._append_row(node, index=index)

        node._parent = parent_node
        self._fast[obj_id] = node
        return node
Ejemplo n.º 17
0
    def add_node(self, parent_node, obj_id, node, index=-1):
        '''
        Adds a node to the tree below the passed parent.

        :param TreeNode|unicode|NoneType parent_node:
            If None is passed, it'll be added to the root, otherwise, it'll be added to
            the passed node (which can be passed directly or through its id).

        :param unicode obj_id:
            The id for this node.

        :param object|TreeNode node:
            Either the instanced TreeNode to be added or the data for which a TreeNode
            should be created.

        :param int index:
            The index at which the child node should be added.
        '''
        if isinstance(parent_node, compat.unicode):
            parent_node = self._fast[parent_node]

        if not isinstance(node, TreeNode):
            node = TreeNode(node)

        assert thread_utils.is_in_main_thread()
        assert obj_id not in self._fast, '%s already in %s' % (obj_id, self)
        if parent_node is None:
            items = node._attach_to_tree(self, obj_id)
            if index == -1:
                self._model.appendRow(items)
            else:
                assert index >= 0
                self._model.insertRow(index, items)
            self._root_items.add(node)
        else:
            items = node._attach_to_tree(self, obj_id)
            parent_node._append_row(node, index=index)

        node._parent = parent_node
        self._fast[obj_id] = node
        return node
Ejemplo n.º 18
0
def _assert_condition_within_timeout(condition, timeout=2.):
    assert is_in_main_thread()
    initial = time.time()
    while True:
        c = condition()
        if isinstance(c, bool):
            if c:
                return
        elif isinstance(c, (compat.bytes, compat.unicode)):
            if not c:
                return
        else:
            raise AssertionError('Expecting bool or string as the return.')

        if time.time() - initial > timeout:
            raise AssertionError(
                u'Could not reach condition before timeout: %s (condition return: %s)'
                % (timeout, c))

        # process_events()
        time.sleep(1 / 60.)
Ejemplo n.º 19
0
    def register_timer():
        assert is_in_main_thread(), \
            'We can only create QTimers in the main thread '\
            '(or at least delete them in the same thread).'

        with _timers_lock:
            existing_timer = _timers_alive.get(func)
            if existing_timer is not None:
                timer = existing_timer.timer
                if timer is not None:
                    try:
                        timer.stop()
                        timer.start(millis)
                    except Exception:
                        pass
                    return  # Restart it!

            timer = QTimer()
            timer_alive = _TimerAlive(func, timer)
            _timers_alive[func] = timer_alive

            timer.setSingleShot(True)
            timer.timeout.connect(timer_alive)
            timer.start(millis)
Ejemplo n.º 20
0
    def register_timer():
        assert is_in_main_thread(), \
            'We can only create QTimers in the main thread '\
            '(or at least delete them in the same thread).'

        with _timers_lock:
            existing_timer = _timers_alive.get(func)
            if existing_timer is not None:
                timer = existing_timer.timer
                if timer is not None:
                    try:
                        timer.stop()
                        timer.start(millis)
                    except Exception:
                        pass
                    return  # Restart it!

            timer = QTimer()
            timer_alive = _TimerAlive(func, timer)
            _timers_alive[func] = timer_alive

            timer.setSingleShot(True)
            timer.timeout.connect(timer_alive)
            timer.start(millis)
    def itertree(self, node=None, recursive=True, class_=None):
        '''
        Iters children of the node sorted in tree order.

        :note: Usually to get all classes it'd be better to use iter_instances and
        to iterate all iteritems() (if the order is not important).

        Yields obj_id and the obj
        '''
        assert thread_utils.is_in_main_thread()
        if node is None:
            node = self._root

        if recursive:
            if not class_:
                return self._iter_recursive_no_class(node)
            else:
                return self._iter_recursive_class(node, class_)

        else:
            if class_:
                return self._iter_no_recursive_class(node, class_)
            else:
                return self._iter_no_recursive_no_class(node)
Ejemplo n.º 22
0
    def check(self):
        assert is_in_main_thread()
        DEBUG = False
        # Uncomment for debug
        if DEBUG:
            flags = (
                gc.DEBUG_COLLECTABLE |
                gc.DEBUG_UNCOLLECTABLE |
                gc.DEBUG_SAVEALL  # i.e.: put in gc.garbage!
            )

            try:
                flags |= gc.DEBUG_INSTANCES  # @UndefinedVariable
            except AttributeError:
                pass

            try:
                flags |= gc.DEBUG_OBJECTS  # @UndefinedVariable
            except AttributeError:
                pass

            try:
                flags |= gc.DEBUG_LEAK
            except AttributeError:
                pass

            try:
                flags |= gc.DEBUG_STATS
            except AttributeError:
                pass

        else:
            flags = 0

        gc.set_debug(flags)
        l0, l1, l2 = gc.get_count()

        if l0 > self.threshold[0]:
            num = gc.collect(0)
            if DEBUG:
                print('collecting gen 0, found:', num, 'unreachable')

            if l1 > self.threshold[1]:
                num = gc.collect(1)
                if DEBUG:
                    print('collecting gen 1, found:', num, 'unreachable')

                if l2 > self.threshold[2]:
                    num = gc.collect(2)
                    if DEBUG:
                        print('collecting gen 2, found:', num, 'unreachable')

        # uncomment for debug
        if DEBUG:
            garbage = gc.garbage
            if garbage:
                for obj in garbage:
                    print('Error: cycle in: %s (%r) %s' % (obj, repr(obj), type(obj)))

            del gc.garbage[:]

        gc.set_debug(0)
Ejemplo n.º 23
0
def show_message(
        message,
        detailed_message='',
        title='Error',
        parent=None,
        icon=None):
    '''
    :param icon:
        QMessageBox.NoIcon
        QMessageBox.Question
        QMessageBox.Information
        QMessageBox.Warning
        QMessageBox.Critical
    '''
    from pyvmmonitor_qt.qt.QtWidgets import QMessageBox
    if icon is None:
        icon = QMessageBox.Critical
    if isinstance(icon, compat.bytes):
        icon = icon.decode('utf-8', 'replace')

    if isinstance(icon, compat.unicode):
        icon = icon.lower()
        if icon == 'error':
            icon = QMessageBox.Critical
        elif icon in ('warning', 'warn'):
            icon = QMessageBox.Warning
        elif icon in ('information', 'info'):
            icon = QMessageBox.Information
        elif icon == 'question':
            icon = QMessageBox.Question
        else:
            logger.warn('Invalid icon: %s' % (icon,))
            icon = QMessageBox.NoIcon

    if not is_in_main_thread():

        # Important: if we're not in the main thread, we have to schedule to run it later
        # (in the UI thread).
        def func():
            show_message(message, detailed_message, title, parent, icon)

        from pyvmmonitor_qt.qt_event_loop import execute_on_next_event_loop
        execute_on_next_event_loop(func)
        return

    if parent is None:
        parent = get_main_window()

    from pyvmmonitor_qt.qt_app import obtain_qapp
    get_icon = obtain_qapp().style().standardIcon

    from pyvmmonitor_qt.qt.QtWidgets import QStyle
    if icon == QMessageBox.Information:
        icon = get_icon(QStyle.SP_MessageBoxInformation)
    elif icon == QMessageBox.Critical:
        icon = get_icon(QStyle.SP_MessageBoxCritical)
    elif icon == QMessageBox.Warning:
        icon = get_icon(QStyle.SP_MessageBoxWarning)
    elif icon == QMessageBox.Question:
        icon = get_icon(QStyle.SP_MessageBoxQuestion)
    else:
        from pyvmmonitor_qt.qt.QtGui import QIcon
        icon = QIcon()

    return __show_dialog_and_exec(parent, title, message, detailed_message, icon)
Ejemplo n.º 24
0
def show_message(
        message,
        detailed_message='',
        title='Error',
        parent=None,
        icon=None):
    '''
    :param icon:
        QMessageBox.NoIcon
        QMessageBox.Question
        QMessageBox.Information
        QMessageBox.Warning
        QMessageBox.Critical
    '''
    from pyvmmonitor_qt.qt.QtWidgets import QMessageBox
    if icon is None:
        icon = QMessageBox.Critical
    if isinstance(icon, compat.bytes):
        icon = icon.decode('utf-8', 'replace')

    if isinstance(icon, compat.unicode):
        icon = icon.lower()
        if icon == 'error':
            icon = QMessageBox.Critical
        elif icon in ('warning', 'warn'):
            icon = QMessageBox.Warning
        elif icon in ('information', 'info'):
            icon = QMessageBox.Information
        elif icon == 'question':
            icon = QMessageBox.Question
        else:
            logger.warn('Invalid icon: %s' % (icon,))
            icon = QMessageBox.NoIcon

    if not is_in_main_thread():

        # Important: if we're not in the main thread, we have to schedule to run it later
        # (in the UI thread).
        def func():
            show_message(message, detailed_message, title, parent, icon)

        from pyvmmonitor_qt.qt_event_loop import execute_on_next_event_loop
        execute_on_next_event_loop(func)
        return

    if parent is None:
        parent = get_main_window()

    from pyvmmonitor_qt.qt_app import obtain_qapp
    get_icon = obtain_qapp().style().standardIcon

    from pyvmmonitor_qt.qt.QtWidgets import QStyle
    if icon == QMessageBox.Information:
        icon = get_icon(QStyle.SP_MessageBoxInformation)
    elif icon == QMessageBox.Critical:
        icon = get_icon(QStyle.SP_MessageBoxCritical)
    elif icon == QMessageBox.Warning:
        icon = get_icon(QStyle.SP_MessageBoxWarning)
    elif icon == QMessageBox.Question:
        icon = get_icon(QStyle.SP_MessageBoxQuestion)
    else:
        from pyvmmonitor_qt.qt.QtGui import QIcon
        icon = QIcon()

    return __show_dialog_and_exec(parent, title, message, detailed_message, icon)