def test_execute_in_millis(qtapi): called_at = [] def later(): called_at.append(time.time()) initial = time.time() execute_after_millis(100, later) execute_after_millis(100, later) execute_after_millis(100, later) execute_after_millis(100, later) execute_after_millis(100, later) from pyvmmonitor_qt.qt_event_loop import process_events processed = 0 while len(called_at) == 0: processed += 1 process_events() time.sleep(0.01) assert processed >= 2, 'It takes at least one loop to enable the timer and another to call it!' assert len(called_at) == 1 # When using 0.1 we had fails such as 1393329951.561 >= (1393329951.462 + 0.1) # When using 0.098 we had fails such as 1460803824.435426 >= (1460803824.338036 + 0.098) # When using 0.096 we had fails such as 1472124879.664037 >= (1472124879.568162 + 0.096) assert called_at[0] >= initial + 0.094
def qpixmap_widget(): from pyvmmonitor_qt.qt_event_loop import process_events from pyvmmonitor_qt.qt_pixmap_widget import QPixmapWidget widget = QPixmapWidget() yield widget widget.deleteLater() process_events(collect=True)
def test_mouse_shortcuts_in_app(qtapi, _shortcuts_main_window): from pyvmmonitor_qt.commands.qt_commands_manager import create_default_qt_commands_manager from pyvmmonitor_qt.commands.qt_commands_manager import CTRL_MOUSE_WHEEL_DOWN from pyvmmonitor_qt.qt.QtCore import Qt from pyvmmonitor_qt.qt_event_loop import process_events try: main_window = _shortcuts_main_window() main_window.show() process_events() activated = [] def on_zoom_out(): activated.append('on_zoom_out') qt_commands_manager = create_default_qt_commands_manager(main_window) # : :type qt_commands_manager: _DefaultQtShortcutsManager qt_commands_manager.register_command('zoom_out', 'Zoom Out') qt_commands_manager.set_command_handler('zoom_out', on_zoom_out) qt_commands_manager.set_shortcut('zoom_out', CTRL_MOUSE_WHEEL_DOWN) qt_commands_manager.mouse_shortcut_activated(CTRL_MOUSE_WHEEL_DOWN) assert activated == ['on_zoom_out'] del activated[:] qt_commands_manager.set_shortcut('zoom_out', 'Ctrl+D') qtapi.keyPress(main_window, 'd', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_zoom_out'] del activated[:] qt_commands_manager.mouse_shortcut_activated(CTRL_MOUSE_WHEEL_DOWN) assert activated == ['on_zoom_out'] del activated[:] finally: main_window = None
def test_multi_line_edit_linked_edition(qtapi): from pyvmmonitor_qt.qt_event_loop import process_events edition = qt_linked_edition.MultiLineText(None, 'text') try: edition.qwidget.show() process_events() with pytest.raises(AttributeError): edition.invalid_attribute = 20 data = _Data() edition.set_data([data]) assert edition.qwidget.toPlainText() == 'Text' data.text = 'foo' assert edition.qwidget.toPlainText() == 'Text' process_queue() # Only update when queue is processed assert edition.qwidget.toPlainText() == 'foo' changed = [0] def on_text_changed(): changed[0] += 1 edition.qwidget.textChanged.connect(on_text_changed) edition.qwidget.setPlainText('bar') process_events() assert changed[0] == 1 assert data.text == 'bar' finally: edition.dispose()
def virtual_tree(): from pyvmmonitor_qt.qt.QtWidgets import QTreeView from pyvmmonitor_qt.tree.pythonic_tree_view import PythonicQTreeView tree = QTreeView() def has_children(pythonic_tree, node): if node is None or node.data[0] == '1': return True return False def create_children(pythonic_tree, node): if node is None: pythonic_tree['1'] = '1' pythonic_tree['3'] = '2' else: if node.data[0] == '1': pythonic_tree.add_node(node, 'foo', '5') tree = PythonicQTreeView(tree, has_children=has_children, create_children=create_children) yield tree from pyvmmonitor_qt import qt_utils if qt_utils.is_qobject_alive(tree.tree): tree.tree.deleteLater() tree = None from pyvmmonitor_qt.qt_event_loop import process_events process_events(collect=True)
def qgradient_slider(): from pyvmmonitor_qt.qt_event_loop import process_events from pyvmmonitor_qt.qt_gradient_slider import QGradientSlider slider = QGradientSlider() yield slider slider.deleteLater() process_events(collect=True)
def test_choose_color_widget(qtapi, choose_color_widget): from pyvmmonitor_qt.qt_event_loop import process_events from pyvmmonitor_qt.qt.QtGui import QColor process_events() color_wheel_widget = choose_color_widget.color_wheel_widget choose_color_widget.color_wheel_widget.repaint() pixmap_size = choose_color_widget.color_wheel_widget._pixmap.size() # Just checking that the color wheel was built on paint assert pixmap_size.width() > 30 assert pixmap_size.height() > 30 assert color_wheel_widget.width() > pixmap_size.width() assert color_wheel_widget.height() > pixmap_size.height() center = color_wheel_widget._center assert color_wheel_widget.saturation_from_point(center[0], center[1]) == 0.0 assert color_wheel_widget.saturation_from_point(pixmap_size.width(), 0.0) == 1.0 choose_color_widget.model.color = QColor.fromCmykF(0.000000, 0.000000, 0.000000, 0.000000, 1.000000)
def opacity_widget(): from pyvmmonitor_qt.qt_choose_color_widget import ChooseColorModel from pyvmmonitor_qt.qt_choose_color_widget import _OpacityWidget widget = _OpacityWidget(parent=None, model=ChooseColorModel()) widget.show() yield widget widget.deleteLater() widget = None from pyvmmonitor_qt.qt_event_loop import process_events process_events(collect=True)
def rgb_widget(): from pyvmmonitor_qt.qt_choose_color_widget import RGBWidget from pyvmmonitor_qt.qt_choose_color_widget import ChooseColorModel rgbwidget = RGBWidget(parent=None, model=ChooseColorModel()) rgbwidget.show() yield rgbwidget rgbwidget.deleteLater() rgbwidget = None from pyvmmonitor_qt.qt_event_loop import process_events process_events(collect=True)
def hsv_widget(): from pyvmmonitor_qt.qt_choose_color_widget import HSVWidget from pyvmmonitor_qt.qt_choose_color_widget import ChooseColorModel hsvwidget = HSVWidget(parent=None, model=ChooseColorModel()) hsvwidget.show() yield hsvwidget hsvwidget.deleteLater() hsvwidget = None from pyvmmonitor_qt.qt_event_loop import process_events process_events(collect=True)
def choose_color_widget(): from pyvmmonitor_qt.qt_choose_color_widget import ChooseColorModel from pyvmmonitor_qt.qt_choose_color_widget import ChooseColorWidget from pyvmmonitor_qt.qt_event_loop import process_events choose_color_widget = ChooseColorWidget(parent=None, model=ChooseColorModel()) choose_color_widget.show() yield choose_color_widget choose_color_widget.deleteLater() choose_color_widget = None process_events(collect=True)
def tree(): from pyvmmonitor_qt.qt.QtWidgets import QTreeView from pyvmmonitor_qt.tree.pythonic_tree_view import PythonicQTreeView tree = QTreeView() tree = PythonicQTreeView(tree) yield tree from pyvmmonitor_qt import qt_utils if qt_utils.is_qobject_alive(tree.tree): tree.tree.deleteLater() tree = None from pyvmmonitor_qt.qt_event_loop import process_events process_events(collect=True)
def test_tree_view(qtapi, tree): from pyvmmonitor_qt import qt_utils from pyvmmonitor_qt.tree.pythonic_tree_view import TreeNode tree.tree.show() tree.columns = ['col1', 'col2'] qtapi.add_widget(tree.tree) # Usual API to use tree['a'] = [10, 20] tree['a.b'] = [20, 30] tree['a.c'] = ['30'] tree['a.b.c'] = ['30', 40] assert qt_utils.list_wiget_item_captions(tree.tree, cols=(0, 1)) == [['10', '20'], ['+20', '+30'], ['++30', '++40'], ['+30', '+']] tree['a'].expand() tree['a'].check(True) node = TreeNode([1, 2]) assert not node.is_expanded() with pytest.raises(RuntimeError): node.expand(True) assert not node.is_expanded( ) # We can only expand after it's added to the tree with pytest.raises(RuntimeError): node.check(True) assert not node.is_checked() tree['a.d'] = node node.expand() node.check() assert node.is_expanded() assert node.is_checked() tree['a.d.c'] = [2, 4] tree['a.d.c'].expand() assert tree['a.d.c'].is_expanded() assert node.is_expanded() assert node.is_checked() assert not node.is_checked(1) from pyvmmonitor_qt.qt_event_loop import process_events process_events() assert node.is_expanded() assert node.is_checked() assert not node.is_checked(1)
def test_shortcuts_in_app(qtapi, _shortcuts_main_window): from pyvmmonitor_qt.commands.qt_commands_manager import create_default_qt_commands_manager from pyvmmonitor_qt.qt.QtCore import Qt from pyvmmonitor_qt.qt.QtGui import QKeySequence from pyvmmonitor_qt.qt_event_loop import process_events try: main_window = _shortcuts_main_window() main_window.show() process_events() activated = [] def on_copy(): activated.append('on_copy') qt_commands_manager = create_default_qt_commands_manager(main_window) # : :type qt_commands_manager: _DefaultQtShortcutsManager qt_commands_manager.register_command('copy', 'Copy') qt_commands_manager.set_command_handler('copy', on_copy) qt_commands_manager.set_shortcut('copy', QKeySequence('Ctrl+C')) qtapi.keyPress(main_window, 'c', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_copy'] del activated[:] qt_commands_manager.remove_shortcut('copy', 'Ctrl+C') qtapi.keyPress(main_window, 'c', Qt.KeyboardModifier.ControlModifier) assert activated == [] qt_commands_manager.set_shortcut('copy', 'Ctrl+D') qtapi.keyPress(main_window, 'd', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_copy'] del activated[:] # Both active (Ctrl+C, Ctrl+D) qt_commands_manager.set_shortcut('copy', 'Ctrl+C') qtapi.keyPress(main_window, 'd', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_copy'] del activated[:] qtapi.keyPress(main_window, 'c', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_copy'] del activated[:] qt_commands_manager.remove_shortcut('copy', 'Ctrl+C') qtapi.keyPress(main_window, 'c', Qt.KeyboardModifier.ControlModifier) assert activated == [] finally: main_window = None
def test_tree_view(qtapi, tree): from pyvmmonitor_qt import qt_utils from pyvmmonitor_qt.tree.pythonic_tree_view import TreeNode tree.tree.show() tree.columns = ['col1', 'col2'] qtapi.add_widget(tree.tree) # Usual API to use tree['a'] = [10, 20] tree['a.b'] = [20, 30] tree['a.c'] = ['30'] tree['a.b.c'] = ['30', 40] assert qt_utils.list_wiget_item_captions(tree.tree, cols=(0, 1)) == [ ['10', '20'], ['+20', '+30'], ['++30', '++40'], ['+30', '+']] tree['a'].expand() tree['a'].check(True) node = TreeNode([1, 2]) assert not node.is_expanded() with pytest.raises(RuntimeError): node.expand(True) assert not node.is_expanded() # We can only expand after it's added to the tree with pytest.raises(RuntimeError): node.check(True) assert not node.is_checked() tree['a.d'] = node node.expand() node.check() assert node.is_expanded() assert node.is_checked() tree['a.d.c'] = [2, 4] tree['a.d.c'].expand() assert tree['a.d.c'].is_expanded() assert node.is_expanded() assert node.is_checked() assert not node.is_checked(1) from pyvmmonitor_qt.qt_event_loop import process_events process_events() assert node.is_expanded() assert node.is_checked() assert not node.is_checked(1)
def test_marching_ants(qtapi): from pyvmmonitor_qt.qt.QtWidgets import QGraphicsView view = QGraphicsView() view.show() from pyvmmonitor_qt.qt.QtWidgets import QGraphicsScene scene = QGraphicsScene(view) view.setScene(scene) from pyvmmonitor_qt import qt_graphics_items_animation animation = qt_graphics_items_animation.GraphicsItemsAnimation(timeout=0) from pyvmmonitor_qt.qt.QtGui import QPolygonF from pyvmmonitor_qt.qt.QtCore import QPointF polygon = ((0, 0), (40, 0), (40, 20)) from pyvmmonitor_qt.qt.QtWidgets import QGraphicsPolygonItem item1 = QGraphicsPolygonItem(QPolygonF([QPointF(*tup) for tup in polygon])) item2 = QGraphicsPolygonItem(QPolygonF([QPointF(*tup) for tup in polygon])) scene.addItem(item1) scene.addItem(item2) assert not animation._timer.isActive() handle = animation.marching_ants(item1, item2) assert animation._timer.isActive() assert item1.pen().dashOffset() == 0.0 assert item2.pen().dashOffset() == 0.0 qt_event_loop.process_events() assert item1.pen().dashOffset() == 18.0 assert item2.pen().dashOffset() == 13.0 ants_handle = handle.handle assert ants_handle in animation._marching_ants._marching_ants_handlers handle.stop() assert ants_handle not in animation._marching_ants._marching_ants_handlers assert handle.handle is None assert not animation._timer.isActive() animation.dispose() scene.deleteLater() scene = None view.deleteLater() view = None
def assert_focus_within_timeout(widget): from pyvmmonitor_qt.qt_event_loop import process_events if widget.hasFocus(): return widget.setFocus() process_events() if widget.hasFocus(): return def check_focus(): widget.setFocus() process_events() if widget.hasFocus(): return True return 'Widget: %s still has no focus.' % (widget,) assert_condition_within_timeout(check_focus)
def test_choose_color_widget(qtapi, choose_color_widget): from pyvmmonitor_qt.qt_event_loop import process_events from pyvmmonitor_qt.qt.QtGui import QColor process_events() color_wheel_widget = choose_color_widget.color_wheel_widget choose_color_widget.color_wheel_widget.repaint() pixmap_size = choose_color_widget.color_wheel_widget._pixmap.size() # Just checking that the color wheel was built on paint assert pixmap_size.width() > 30 assert pixmap_size.height() > 30 assert color_wheel_widget.width() > pixmap_size.width() assert color_wheel_widget.height() > pixmap_size.height() center = color_wheel_widget._center assert color_wheel_widget.saturation_from_point(center[0], center[1]) == 0.0 assert color_wheel_widget.saturation_from_point(pixmap_size.width(), 0.0) == 1.0 choose_color_widget.model.color = QColor.fromCmykF( 0.000000, 0.000000, 0.000000, 0.000000, 1.000000)
def qtapi(qtbot): from pyvmmonitor_qt.qt_app import obtain_qapp from pyvmmonitor_qt.qt_collect import start_collect_only_in_ui_thread obtain_qapp() # Will make sure that the default stylesheet is also applied start_collect_only_in_ui_thread( ) # Make sure we'll only collect items in the main thread def d(self, make_visible=True): widget_and_visibility = [] for weak_widget in _list_widgets(self): widget = weak_widget() if widget is not None: widget_and_visibility.append((widget, widget.isVisible())) if make_visible: for w in widget_and_visibility: w[0].setVisible(True) from pyvmmonitor_qt.qt.QtWidgets import QApplication QApplication.instance().exec_() for widget, visible in widget_and_visibility: widget.setVisible(visible) qtbot.d = types.MethodType(d, qtbot) yield qtbot for w in _list_widgets(qtbot): w = w() if hasattr(w, 'set_data'): w.set_data(None) if hasattr(w, 'clear_cycles'): w.clear_cycles() from pyvmmonitor_qt.qt_event_loop import process_events process_events(collect=True)
def test_int_edit_linked_edition(qtapi): from pyvmmonitor_qt.qt_event_loop import process_events int_edition = qt_linked_edition.IntEdition(None, 'val') try: int_edition.qwidget.show() process_events() with pytest.raises(AttributeError): int_edition.invalid_attribute = 20 data = _Data() int_edition.set_data([data]) assert int_edition.qwidget.text() == '10' data.val = 30 assert int_edition.qwidget.text() == '10' process_queue() # Only update when queue is processed assert int_edition.qwidget.text() == '30' int_edition.qwidget.setText('40') assert data.val == 40 finally: int_edition.dispose()
def qtapi(qtbot): from pyvmmonitor_qt.qt_app import obtain_qapp from pyvmmonitor_qt.qt_collect import start_collect_only_in_ui_thread obtain_qapp() # Will make sure that the default stylesheet is also applied start_collect_only_in_ui_thread() # Make sure we'll only collect items in the main thread def d(self, make_visible=True): widget_and_visibility = [] for weak_widget in _list_widgets(self): widget = weak_widget() if widget is not None: widget_and_visibility.append((widget, widget.isVisible())) if make_visible: for w in widget_and_visibility: w[0].setVisible(True) from pyvmmonitor_qt.qt.QtWidgets import QApplication QApplication.instance().exec_() for widget, visible in widget_and_visibility: widget.setVisible(visible) qtbot.d = types.MethodType(d, qtbot) yield qtbot for w in _list_widgets(qtbot): w = w() if hasattr(w, 'set_data'): w.set_data(None) if hasattr(w, 'clear_cycles'): w.clear_cycles() from pyvmmonitor_qt.qt_event_loop import process_events process_events(collect=True)
def test_font_family_qt_linked_edition(qtapi): from pyvmmonitor_qt.qt_event_loop import process_events font_family = qt_linked_edition.FontFamily(None, 'font') try: font_family.qwidget.show() process_events() with pytest.raises(AttributeError): font_family.invalid_attribute = 20 data = _Data() font_family.set_data([data]) assert font_family.qwidget.currentFont().family() == 'Arial' data.font = 'Times New Roman' assert font_family.qwidget.currentFont().family() == 'Arial' process_queue() # Only update when queue is processed assert font_family.qwidget.currentFont().family() == 'Times New Roman' font_family.set_current_font_family('Verdana') assert font_family.qwidget.currentFont().family() == 'Verdana' finally: font_family.dispose()
def check_focus(): widget.setFocus() process_events() if widget.hasFocus(): return True return 'Widget: %s still has no focus.' % (widget,)
def test_widget_scopes(qtapi, _shortcuts_main_window): ''' ''' from pyvmmonitor_qt.commands.qt_commands_manager import create_default_qt_commands_manager from pyvmmonitor_qt.qt.QtCore import Qt from pyvmmonitor_qt.qt.QtGui import QKeySequence from pyvmmonitor_qt.qt_event_loop import process_events from pyvmmonitor_qt.qt_utils import assert_focus_within_timeout try: main_window = _shortcuts_main_window() main_window.show() process_events() activated = [] def on_g(): activated.append('on_g') def on_d(): activated.append('on_d') def on_b(): activated.append('on_b') qt_commands_manager = create_default_qt_commands_manager(main_window) qt_commands_manager.register_scope('line_edit1') qt_commands_manager.register_scope('line_edit2') # : :type qt_commands_manager: _DefaultQtShortcutsManager qt_commands_manager.register_command('cmd_g', 'CMD_G') qt_commands_manager.set_command_handler('cmd_g', on_g) qt_commands_manager.set_shortcut('cmd_g', QKeySequence('Ctrl+G')) qt_commands_manager.register_command('cmd_d', 'CMD_D') qt_commands_manager.set_command_handler('cmd_d', on_d, 'line_edit1') qt_commands_manager.set_shortcut('cmd_d', QKeySequence('Ctrl+D'), scope='line_edit1') qt_commands_manager.register_command('cmd_b', 'CMD_B') qt_commands_manager.set_command_handler('cmd_b', on_b, 'line_edit2') qt_commands_manager.set_shortcut('cmd_b', QKeySequence('Ctrl+B'), scope='line_edit2') qt_commands_manager.set_scope_widget('line_edit2', main_window.line_edit2) qt_commands_manager.set_scope_widget('line_edit1', main_window.line_edit1) qtapi.keyPress(main_window, 'G', Qt.KeyboardModifier.ControlModifier) qtapi.keyPress(main_window.line_edit1, 'G', Qt.KeyboardModifier.ControlModifier) qtapi.keyPress(main_window.line_edit2, 'G', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_g', 'on_g', 'on_g'] del activated[:] qtapi.keyPress(main_window, 'B', Qt.KeyboardModifier.ControlModifier) assert activated == [] assert_focus_within_timeout(main_window.line_edit1) qtapi.keyPress(main_window.line_edit1, 'B', Qt.KeyboardModifier.ControlModifier) assert activated == [] assert_focus_within_timeout(main_window.line_edit2) qtapi.keyPress(main_window.line_edit2, 'B', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_b'] del activated[:] qtapi.keyPress(main_window, 'D', Qt.KeyboardModifier.ControlModifier) assert activated == [] assert_focus_within_timeout(main_window.line_edit1) qtapi.keyPress(main_window.line_edit1, 'D', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_d'] assert_focus_within_timeout(main_window.line_edit2) qtapi.keyPress(main_window.line_edit2, 'D', Qt.KeyboardModifier.ControlModifier) assert activated == ['on_d'] del activated[:] finally: main_window = None