def draw_layout( self, layout_name: str, reset_view: bool = True, ): print(f"drawing {layout_name}") self._current_layout = layout_name self.view.begin_loading() new_scene = qw.QGraphicsScene() self._backend.set_scene(new_scene) layout = self.doc.layout(layout_name) self._update_render_context(layout) try: start = time.perf_counter() self.create_frontend().draw_layout(layout) duration = time.perf_counter() - start print(f"took {duration:.4f} seconds") except DXFStructureError as e: qw.QMessageBox.critical( self, "DXF Structure Error", f'Abort rendering of layout "{layout_name}": {str(e)}', ) finally: self._backend.finalize() self.view.end_loading(new_scene) self.view.buffer_scene_rect() if reset_view: self.view.fit_to_scene()
def run(args): # Import on demand for a quicker startup: try: from ezdxf.addons.xqt import QtWidgets except ImportError as e: print(str(e)) sys.exit(1) from ezdxf.addons.drawing.qtviewer import CadViewer from ezdxf.addons.drawing.config import Configuration, LinePolicy config = Configuration.defaults() config = config.with_changes( line_policy=LinePolicy.ACCURATE if args.ltype == "accurate" else config.line_policy, lineweight_scaling=args.lwscale, ) signal.signal(signal.SIGINT, signal.SIG_DFL) # handle Ctrl+C properly app = QtWidgets.QApplication(sys.argv) set_app_icon(app) viewer = CadViewer(config=config) filename = args.file if filename: doc, auditor = load_document(filename) viewer.set_document( doc, auditor, layout=args.layout, ) sys.exit(app.exec())
def _populate_layer_list(self): self.layers.blockSignals(True) self.layers.clear() for layer in self._render_context.layers.values(): name = layer.layer item = qw.QListWidgetItem() self.layers.addItem(item) checkbox = qw.QCheckBox(name) checkbox.setCheckState( qc.Qt.Checked if layer.is_visible else qc.Qt.Unchecked) checkbox.stateChanged.connect(self._layers_updated) text_color = ("#FFFFFF" if is_dark_color(layer.color, 0.4) else "#000000") checkbox.setStyleSheet( f"color: {text_color}; background-color: {layer.color}") self.layers.setItemWidget(item, checkbox) self.layers.blockSignals(False)
def __init__(self, config: Configuration = Configuration.defaults()): super().__init__() self._config = config self.doc = None self._render_context = None self._visible_layers = None self._current_layout = None self._reset_backend() self.view = CADGraphicsViewWithOverlay() self.view.setScene(qw.QGraphicsScene()) self.view.scale(1, -1) # so that +y is up self.view.element_selected.connect(self._on_element_selected) self.view.mouse_moved.connect(self._on_mouse_moved) menu = self.menuBar() select_doc_action = QAction("Select Document", self) select_doc_action.triggered.connect(self._select_doc) menu.addAction(select_doc_action) self.select_layout_menu = menu.addMenu("Select Layout") toggle_sidebar_action = QAction("Toggle Sidebar", self) toggle_sidebar_action.triggered.connect(self._toggle_sidebar) menu.addAction(toggle_sidebar_action) self.sidebar = qw.QSplitter(qc.Qt.Vertical) self.layers = qw.QListWidget() self.layers.setStyleSheet( "QListWidget {font-size: 12pt;} " "QCheckBox {font-size: 12pt; padding-left: 5px;}") self.sidebar.addWidget(self.layers) info_container = qw.QWidget() info_layout = qw.QVBoxLayout() info_layout.setContentsMargins(0, 0, 0, 0) self.selected_info = qw.QPlainTextEdit() self.selected_info.setReadOnly(True) info_layout.addWidget(self.selected_info) self.mouse_pos = qw.QLabel() info_layout.addWidget(self.mouse_pos) info_container.setLayout(info_layout) self.sidebar.addWidget(info_container) container = qw.QSplitter() self.setCentralWidget(container) container.addWidget(self.view) container.addWidget(self.sidebar) container.setCollapsible(0, False) container.setCollapsible(1, True) w = container.width() container.setSizes([int(3 * w / 4), int(w / 4)]) self.setWindowTitle("CAD Viewer") self.resize(1600, 900) self.show()
def build_central_widget(self): container = QtWidgets.QSplitter(Qt.Horizontal) container.addWidget(self._structure_tree) container.addWidget(self._dxf_tags_table) tree_width = int(BROWSER_WIDTH * TREE_WIDTH_FACTOR) table_width = BROWSER_WIDTH - tree_width container.setSizes([tree_width, table_width]) container.setCollapsible(0, False) container.setCollapsible(1, False) return container
def setup_toolbar(self) -> None: toolbar = QtWidgets.QToolBar("MainToolbar") toolbar.setIconSize(QSize(ICON_SIZE, ICON_SIZE)) toolbar.addAction(self._entity_history_back_action) toolbar.addAction(self._entity_history_forward_action) toolbar.addAction(self._goto_predecessor_entity_action) toolbar.addAction(self._goto_next_entity_action) toolbar.addAction(self._show_entity_in_tree_view_action) toolbar.addAction(self._find_text_action) toolbar.addAction(self._goto_line_action) toolbar.addAction(self._goto_handle_action) toolbar.addAction(self._store_bookmark) toolbar.addAction(self._go_to_bookmark) toolbar.addAction(self._copy_entity_action) self.addToolBar(toolbar)
def run(args): try: from ezdxf.addons.xqt import QtWidgets except ImportError as e: print(str(e)) sys.exit(1) from ezdxf.addons import browser signal.signal(signal.SIGINT, signal.SIG_DFL) # handle Ctrl+C properly app = QtWidgets.QApplication(sys.argv) set_app_icon(app) main_window = browser.DXFStructureBrowser( args.file, line=args.line, handle=args.handle, resource_path=resources_path(), ) main_window.show() sys.exit(app.exec())
def _main(): parser = argparse.ArgumentParser() parser.add_argument("--cad_file") parser.add_argument("--layout", default="Model") parser.add_argument("--ltype", default="internal", choices=["internal", "ezdxf"]) # disable lineweight at all by default: parser.add_argument("--lineweight_scaling", type=float, default=0) args = parser.parse_args() # setup drawing add-on configuration config = Configuration.defaults() config = config.with_changes( line_policy=LinePolicy.ACCURATE if args.ltype == "ezdxf" else config.line_policy, lineweight_scaling=args.lineweight_scaling, ) signal.signal(signal.SIGINT, signal.SIG_DFL) # handle Ctrl+C properly app = qw.QApplication(sys.argv) v = CadViewer(config=config) if args.cad_file is not None: try: doc, auditor = recover.readfile(args.cad_file) except IOError: print(f"Not a DXF file or a generic I/O error: {args.cad_file}") sys.exit(1) except ezdxf.DXFStructureError: print(f"Invalid or corrupted DXF file: {args.cad_file}") sys.exit(2) v.set_document(doc, auditor) try: v.draw_layout(args.layout) except KeyError: print( f'could not find layout "{args.layout}". Valid layouts: {[l.name for l in v.doc.layouts]}' ) sys.exit(3) sys.exit(app.exec())
def __init__( self, scene: Optional[qw.QGraphicsScene] = None, *, use_text_cache: bool = True, debug_draw_rect: bool = False, extra_lineweight_scaling: float = 2.0, ): """ Args: extra_lineweight_scaling: compared to other backends, PyQt draws lines which appear thinner """ super().__init__() self._scene = scene or qw.QGraphicsScene() # avoids many type errors self._color_cache: Dict[Color, qg.QColor] = {} self._pattern_cache: Dict[PatternKey, int] = {} self._no_line = qg.QPen(qc.Qt.NoPen) self._no_fill = qg.QBrush(qc.Qt.NoBrush) self._text_renderer = TextRenderer(qg.QFont(), use_text_cache) self._line_renderer: PyQtLineRenderer self._extra_lineweight_scaling = extra_lineweight_scaling self._debug_draw_rect = debug_draw_rect
def setupUi(self, FindDialog): FindDialog.setObjectName("FindDialog") FindDialog.resize(320, 376) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( FindDialog.sizePolicy().hasHeightForWidth()) FindDialog.setSizePolicy(sizePolicy) FindDialog.setMinimumSize(QtCore.QSize(320, 376)) FindDialog.setMaximumSize(QtCore.QSize(320, 376)) FindDialog.setBaseSize(QtCore.QSize(320, 376)) self.verticalLayout_5 = QtWidgets.QVBoxLayout(FindDialog) self.verticalLayout_5.setObjectName("verticalLayout_5") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize) self.horizontalLayout.setObjectName("horizontalLayout") self.label = QtWidgets.QLabel(FindDialog) self.label.setObjectName("label") self.horizontalLayout.addWidget(self.label) self.find_text_edit = QtWidgets.QLineEdit(FindDialog) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.find_text_edit.sizePolicy().hasHeightForWidth()) self.find_text_edit.setSizePolicy(sizePolicy) self.find_text_edit.setMinimumSize(QtCore.QSize(0, 24)) self.find_text_edit.setMaximumSize(QtCore.QSize(16777215, 24)) self.find_text_edit.setObjectName("find_text_edit") self.horizontalLayout.addWidget(self.find_text_edit) self.verticalLayout.addLayout(self.horizontalLayout) self.groupBox = QtWidgets.QGroupBox(FindDialog) sizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.groupBox.sizePolicy().hasHeightForWidth()) self.groupBox.setSizePolicy(sizePolicy) self.groupBox.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.groupBox.setFlat(False) self.groupBox.setObjectName("groupBox") self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox) self.verticalLayout_3.setObjectName("verticalLayout_3") self.whole_words_check_box = QtWidgets.QCheckBox(self.groupBox) self.whole_words_check_box.setObjectName("whole_words_check_box") self.verticalLayout_3.addWidget(self.whole_words_check_box) self.match_case_check_box = QtWidgets.QCheckBox(self.groupBox) self.match_case_check_box.setObjectName("match_case_check_box") self.verticalLayout_3.addWidget(self.match_case_check_box) self.number_tags_check_box = QtWidgets.QCheckBox(self.groupBox) self.number_tags_check_box.setObjectName("number_tags_check_box") self.verticalLayout_3.addWidget(self.number_tags_check_box) self.verticalLayout.addWidget(self.groupBox, 0, QtCore.Qt.AlignTop) self.groupBox_2 = QtWidgets.QGroupBox(FindDialog) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.groupBox_2.sizePolicy().hasHeightForWidth()) self.groupBox_2.setSizePolicy(sizePolicy) self.groupBox_2.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.groupBox_2.setObjectName("groupBox_2") self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_2) self.verticalLayout_4.setObjectName("verticalLayout_4") self.header_check_box = QtWidgets.QCheckBox(self.groupBox_2) self.header_check_box.setChecked(True) self.header_check_box.setObjectName("header_check_box") self.verticalLayout_4.addWidget(self.header_check_box) self.classes_check_box = QtWidgets.QCheckBox(self.groupBox_2) self.classes_check_box.setObjectName("classes_check_box") self.verticalLayout_4.addWidget(self.classes_check_box) self.tables_check_box = QtWidgets.QCheckBox(self.groupBox_2) self.tables_check_box.setChecked(True) self.tables_check_box.setObjectName("tables_check_box") self.verticalLayout_4.addWidget(self.tables_check_box) self.blocks_check_box = QtWidgets.QCheckBox(self.groupBox_2) self.blocks_check_box.setChecked(True) self.blocks_check_box.setObjectName("blocks_check_box") self.verticalLayout_4.addWidget(self.blocks_check_box) self.entities_check_box = QtWidgets.QCheckBox(self.groupBox_2) self.entities_check_box.setChecked(True) self.entities_check_box.setObjectName("entities_check_box") self.verticalLayout_4.addWidget(self.entities_check_box) self.objects_check_box = QtWidgets.QCheckBox(self.groupBox_2) self.objects_check_box.setChecked(False) self.objects_check_box.setObjectName("objects_check_box") self.verticalLayout_4.addWidget(self.objects_check_box) self.verticalLayout.addWidget(self.groupBox_2, 0, QtCore.Qt.AlignTop) self.verticalLayout_5.addLayout(self.verticalLayout) self.message = QtWidgets.QLabel(FindDialog) self.message.setObjectName("message") self.verticalLayout_5.addWidget(self.message) self.buttons_layout = QtWidgets.QHBoxLayout() self.buttons_layout.setSizeConstraint( QtWidgets.QLayout.SetNoConstraint) self.buttons_layout.setObjectName("buttons_layout") self.find_forward_button = QtWidgets.QPushButton(FindDialog) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.find_forward_button.sizePolicy().hasHeightForWidth()) self.find_forward_button.setSizePolicy(sizePolicy) self.find_forward_button.setMinimumSize(QtCore.QSize(0, 0)) self.find_forward_button.setMaximumSize(QtCore.QSize(200, 100)) self.find_forward_button.setObjectName("find_forward_button") self.buttons_layout.addWidget(self.find_forward_button, 0, QtCore.Qt.AlignBottom) self.find_backwards_button = QtWidgets.QPushButton(FindDialog) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.find_backwards_button.sizePolicy().hasHeightForWidth()) self.find_backwards_button.setSizePolicy(sizePolicy) self.find_backwards_button.setMinimumSize(QtCore.QSize(0, 0)) self.find_backwards_button.setMaximumSize(QtCore.QSize(200, 100)) self.find_backwards_button.setObjectName("find_backwards_button") self.buttons_layout.addWidget(self.find_backwards_button, 0, QtCore.Qt.AlignBottom) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.buttons_layout.addItem(spacerItem) self.close_button = QtWidgets.QPushButton(FindDialog) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.close_button.sizePolicy().hasHeightForWidth()) self.close_button.setSizePolicy(sizePolicy) self.close_button.setMinimumSize(QtCore.QSize(0, 0)) self.close_button.setMaximumSize(QtCore.QSize(200, 100)) self.close_button.setToolTip("") self.close_button.setObjectName("close_button") self.buttons_layout.addWidget( self.close_button, 0, QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom) self.verticalLayout_5.addLayout(self.buttons_layout) self.retranslateUi(FindDialog) QtCore.QMetaObject.connectSlotsByName(FindDialog)
def backend(): global _app _app = qw.QApplication([]) scene = qw.QGraphicsScene() return PyQtBackend(scene)