def __init__(self, data, parent=None): QWidget.__init__(self, parent) self.data = data vbox = QVBoxLayout() self.setLayout(vbox) title = QLabel('Indexed Strings') vbox.addWidget(title) self.frame = QFrame() vbox.addWidget(self.frame) self.vbox = QVBoxLayout() self.frame.setLayout(self.vbox) self.frame.setFrameShape(QFrame.Panel) self.frame.setFrameShadow(QFrame.Sunken) self.table = QTableWidget() self.table.horizontalHeader().hide() self.vbox.addWidget(self.table) self.table.hide() self.noStringsLabel = QLabel('<i>No indexed strings</i>') self.vbox.addWidget(self.noStringsLabel) self.widgets = [] self.populate() self.data.attributeAdded.connect(self.attributeAddedSlot) self.data.dataReset.connect(self.dataResetSlot) self.data.dirtied.connect(self.dataDirtiedSlot)
def __init__(self, *args, **kwargs): super(ButtonGroupFieldWidget, self).__init__(*args, **kwargs) self._value = '' self._buttons = dict() items = self.data().get('items') widget = QFrame(self) layout = layouts.HorizontalLayout(spacing=0, margins=(0, 0, 0, 0)) widget.setLayout(layout) index = 0 for item in items: index += 1 button = buttons.BaseButton(item, parent=self) button.setCheckable(True) button_callback = partial(self.set_value, item) button.clicked.connect(button_callback) self._buttons[item] = button if index == 1: button.setProperty('first', True) if index == len(items): button.setProperty('last', True) self.set_widget(widget)
def ui(self): super(SidebarWidget, self).ui() self._title_widget = QFrame(self) title_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) self._title_widget.setLayout(title_layout) buttons_layout = layouts.HorizontalLayout(spacing=0, margins=(0, 0, 0, 0)) self._title_button = buttons.BaseButton(parent=self) self._title_button.setIcon(resources.icon('reset')) self._menu_button = buttons.BaseButton(parent=self) self._menu_button.setIcon(resources.icon('menu_dots')) buttons_layout.addWidget(self._title_button) buttons_layout.addStretch() buttons_layout.addWidget(self._menu_button) self._filter_search = search.SearchFindWidget(parent=self) self._filter_search.setVisible(False) title_layout.addLayout(buttons_layout) title_layout.addWidget(self._filter_search) self._tree_widget = SidebarTree(self) self._tree_widget.installEventFilter(self) self._tree_widget.itemDropped = self.itemDropped self._tree_widget.itemRenamed = self.itemRenamed self.itemSelectionChanged = self._tree_widget.itemSelectionChanged self._filter_search.set_text(self._tree_widget.filter_text()) self.main_layout.addWidget(self._title_widget) self.main_layout.addWidget(self._tree_widget)
def ui(self): # theme = tpDcc.ToolsMgr().get_tool_theme('tpDcc-tools-hub') # border_width = qtutils.dpi_scale_divide(theme.STACK_BORDER_WIDTH) margin = qtutils.dpi_scale_divide(1) self.main_layout = layouts.VerticalLayout(margins=(margin, margin, margin, margin), spacing=0) # self.main_layout = layouts.VerticalLayout(margins=(0, 0, 0, 0), spacing=0) self.setLayout(self.main_layout) if not self._title_frame: self._title_frame = StackTitleFrame( title=self._title, icon=self._icon, title_editable=self._title_editable, item_icon_size=self._icon_size) if not self._show_item_icon: self._title_frame.item_icon_button.hide() self._contents_widget = QFrame(parent=self) self._contents_layout = layouts.VerticalLayout( spacing=self._contents_spacing, margins=self._contents_margins) self._contents_widget.setLayout(self._contents_layout) self.main_layout.addWidget(self._title_frame) self.main_layout.addWidget(self._contents_widget)
def ui(self): super(BaseSaveWidget, self).ui() title_layout = layouts.HorizontalLayout() title_layout.setContentsMargins(2, 2, 0, 0) title_layout.setSpacing(2) self._icon_lbl = QLabel() self._icon_lbl.setMaximumSize(QSize(14, 14)) self._icon_lbl.setMinimumSize(QSize(14, 14)) self._icon_lbl.setScaledContents(True) self._title_lbl = QLabel() title_layout.addWidget(self._icon_lbl) title_layout.addWidget(self._title_lbl) self._folder_widget = directory.SelectFolder('Folder', use_app_browser=True) buttons_layout = layouts.HorizontalLayout() buttons_layout.setContentsMargins(4, 4, 4, 4) buttons_layout.setSpacing(4) buttons_frame = QFrame() buttons_frame.setFrameShape(QFrame.NoFrame) buttons_frame.setFrameShadow(QFrame.Plain) buttons_frame.setLayout(buttons_layout) buttons_layout.addStretch() self.save_btn = buttons.BaseButton('Save') self.cancel_btn = buttons.BaseButton('Cancel') buttons_layout.addWidget(self.save_btn, parent=self) buttons_layout.addWidget(self.cancel_btn, parent=self) buttons_layout.addStretch() self._options_layout = layouts.VerticalLayout() self._options_layout.setContentsMargins(0, 0, 0, 0) self._options_layout.setSpacing(2) self._options_frame = QFrame() self._options_frame.setFrameShape(QFrame.NoFrame) self._options_frame.setFrameShadow(QFrame.Plain) self._options_frame.setLineWidth(0) self._options_frame.setLayout(self._options_layout) self._extra_layout = layouts.VerticalLayout() self._extra_layout.setContentsMargins(0, 0, 0, 0) self._extra_layout.setSpacing(2) self.main_layout.addLayout(title_layout) self.main_layout.addWidget(self._folder_widget) self._extra_layout.addWidget(self._options_frame) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addLayout(self._extra_layout) self.main_layout.addWidget(dividers.Divider()) self.main_layout.addWidget(buttons_frame)
def __init__(self, *args, **kwargs): super(RadioFieldWidget ,self).__init__(*args, **kwargs) self._radio_buttons = list() layout = layouts.VerticalLayout(margins=(0, 0, 0, 0)) self._radio_frame = QFrame(self) self._radio_frame.setLayout(layout) self.set_widget(self._radio_frame) self.label().setStyleSheet('margin-top: 2px;') self.label().setAlignment(Qt.AlignRight | Qt.AlignTop) self.widget().setStyleSheet('margin-top: 2px;')
def __init__(self, auto_resize=False, single_row_select=True, context_menu_callback=None, last_column_stretch=True, has_counters=False, parent=None ): QFrame.__init__(self, parent) self._has_counters = has_counters self.model = None self.table_view = RowTableView(auto_resize, single_row_select, context_menu_callback, last_column_stretch) self.table_view.doubleClicked.connect(self._double_clicked) if has_counters: self.counters = Counters() self.counters.button_clicked.connect(self._counter_clicked) self.search_bar = QLineEdit() self.search_bar.setFixedHeight(SEARCHBAR_HEIGHT) self.search_bar.textChanged.connect(self.set_search_text) self.search_bar.setToolTip("Search bar") self.auto_size_button = QPushButton('<>') self.auto_size_button.setFixedSize(SEARCHBAR_HEIGHT, SEARCHBAR_HEIGHT) self.auto_size_button.clicked.connect(self._auto_size_clicked) self.auto_size_button.setToolTip("Auto size") self.status_label = QLabel(STATUS_LABEL_MESSAGE.format(0, 0)) self.status_label.setFixedWidth(STATUS_LABEL_WIDTH) self.progress_bar = QProgressBar() self.progress_bar.setFormat('') layout = QGridLayout() layout.addWidget(self.search_bar, 0, 0, 1, 3) layout.addWidget(self.auto_size_button, 0, 3) if has_counters: layout.addWidget(self.counters, 1, 0, 1, 2) layout.addWidget(self.table_view, 1, 2, 1, 2) else: layout.addWidget(self.table_view, 1, 0, 1, 4) layout.addWidget(self.status_label, 2, 0) layout.addWidget(self.progress_bar, 2, 1, 1, 3) layout.setColumnStretch(2, 100) self.setLayout(layout)
def __init__(self, *args, **kwargs): super(StringDoubleFieldWidget, self).__init__(*args, **kwargs) widget = QFrame(self) layout = layouts.HorizontalLayout(spacing=4, margins=(0, 0, 0, 0)) widget.setLayout(layout) self._widget1 = lineedit.BaseLineEdit(parent=self) self._widget2 = lineedit.BaseLineEdit(parent=self) self._widget1.textChanged.connect(self._on_emit_value_changed) self._widget2.textChanged.connect(self._on_emit_value_changed) layout.addWidget(self._widget1) layout.addWidget(self._widget2) self.set_widget(widget)
def ui(self): super(GroupBoxWidget, self).ui() self._title_widget = buttons.BaseButton(self._title, parent=self) self._title_widget.setCheckable(True) self._on_icon = resources.icon('down_button') self._off_icon = resources.icon('right_button') self._title_widget.setIcon(self._off_icon) self._widget_frame = QFrame(self) self._widget_frame.setObjectName('contentsWidget') widget_frame_layout = layouts.VerticalLayout(spacing=2, margins=(0, 0, 0, 0)) self._widget_frame.setLayout(widget_frame_layout) self.main_layout.addWidget(self._title_widget) self.main_layout.addWidget(self._widget_frame)
def initWindows(self): self.mainLayout = QHBoxLayout() self.setLayout(self.mainLayout) self.mainLayout.setSpacing(0) self.mainLayout.setContentsMargins(5, 2, 5, 2) self.initPenSizeButtons() self.initFontWidget() self.initPenColorButtons() self.separator = QFrame(self) self.separator.setFrameShape(QFrame.VLine) self.separator.setFrameShadow(QFrame.Sunken) self.mainLayout.addWidget(self.penSize) self.mainLayout.addWidget(self.changeFontButton) self.mainLayout.addWidget(self.separator) self.mainLayout.addWidget(self.colorSet)
def get_vertical_separator_widget(max_height=30, parent=None): """ Returns horizontal separator widget :param max_height: int, maximum height for the separator :param parent: QWidget or None, parent widget :return: QWidget """ h_div_w = QWidget(parent=parent) h_div_l = layouts.VerticalLayout(spacing=0, margins=(5, 5, 5, 5)) h_div_l.setAlignment(Qt.AlignLeft) h_div_w.setLayout(h_div_l) h_div = QFrame(parent=h_div_w) h_div.setObjectName('dividerSeparator') # ID selector used by style h_div.setMaximumHeight(qtutils.dpi_scale(max_height)) h_div.setFrameShape(QFrame.VLine) h_div.setFrameShadow(QFrame.Sunken) h_div_l.addWidget(h_div) return h_div_w
def get_horizontal_separator(): v_div_w = QWidget() v_div_l = QVBoxLayout() v_div_l.setAlignment(Qt.AlignLeft) v_div_l.setContentsMargins(0, 0, 0, 0) v_div_l.setSpacing(0) v_div_w.setLayout(v_div_l) v_div = QFrame() v_div.setMinimumHeight(30) v_div.setFrameShape(QFrame.VLine) v_div.setFrameShadow(QFrame.Sunken) v_div_l.addWidget(v_div) return v_div_w
def createWidget(self, menu): """ Overrides base QWidgetAction createWidget function :param menu: QMenu :return: QWidget """ widget = QFrame(self.parent()) widget.setObjectName('filterByAction') facet = self._facet name = facet.get('name', '') count = str(facet.get('count', 0)) title = name.replace('.', '').title() cbx = checkbox.BaseCheckBox(parent=widget) cbx.setAttribute(Qt.WA_TransparentForMouseEvents) cbx.setText(title) cbx.installEventFilter(self) cbx.setChecked(self._checked) label2 = label.BaseLabel(parent=widget) label2.setObjectName('actionCounter') label2.setText(count) layout = layouts.HorizontalLayout(spacing=0, margins=(0, 0, 0, 0)) layout.addWidget(cbx, stretch=1) layout.addWidget(label2) widget.setLayout(layout) cbx.toggled.connect(self._on_triggered) return widget
def createWidget(self, menu): """ Overrides base QWidgetAction createWidget function :param menu: QMenu """ widget = QFrame(self.parent()) widget.setObjectName('filterByAction') title = self._name label = checkbox.BaseCheckBox(parent=widget) label.setText(title) label.setAttribute(Qt.WA_TransparentForMouseEvents) label.toggled.connect(self._on_triggered) label.setStyleSheet(""" #QCheckBox::indicator:checked { image: url(none.png) } QCheckBox::indicator:unchecked { image: url(none.png) } """) action_layout = layouts.HorizontalLayout(margins=(0, 0, 0, 0)) action_layout.addWidget(label, stretch=1) widget.setLayout(action_layout) return widget
def __init__(self, title='', animation_duration=300, parent=None): super(ExpandableLine, self).__init__(parent=parent) self._animation_duration = animation_duration base_layout = layouts.GridLayout(margins=(0, 0, 0, 0)) base_layout.setVerticalSpacing(0) self.setLayout(base_layout) self.expand_btn = QToolButton() self.expand_btn.setText(str(title)) self.expand_btn.setStyleSheet('QToolButton { border : none; }') self.expand_btn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.expand_btn.setArrowType(Qt.ArrowType.RightArrow) self.expand_btn.setCheckable(True) self.expand_btn.setChecked(True) header_line = QFrame() header_line.setFrameShape(QFrame.HLine) header_line.setFrameShadow(QFrame.Sunken) header_line.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) self.content_area = QScrollArea() self.content_area.setStyleSheet('QScrollArea { border: none;}') self.content_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.content_area.setMaximumHeight(0) self.content_area.setMinimumHeight(0) self.toggle_anim = QParallelAnimationGroup() self.toggle_anim.addAnimation(QPropertyAnimation(self, 'minimumHeight')) self.toggle_anim.addAnimation(QPropertyAnimation(self, 'maximumHeight')) self.toggle_anim.addAnimation(QPropertyAnimation(self.content_area, 'maximumHeight')) row = 0 base_layout.addWidget(self.expand_btn, row, 0, 1, 1, Qt.AlignLeft) base_layout.addWidget(header_line, row, 2, 1, 1) row += 1 base_layout.addWidget(self.content_area, row, 0, 1, 3) def expand_view(checked): arrow_type = Qt.DownArrow if checked else Qt.RightArrow direction = QAbstractAnimation.Forward if checked else QAbstractAnimation.Backward self.expand_btn.setArrowType(arrow_type) self.toggle_anim.setDirection(direction) self.toggle_anim.start() # === SIGNALS === # self.expand_btn.toggled.connect(expand_view) expand_view(True)
def ui(self): super(PopupMessage, self).ui() current_theme = self.theme() self.setObjectName('message') self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog | Qt.WA_TranslucentBackground | Qt.WA_DeleteOnClose) # self.setAttribute(Qt.WA_TranslucentBackground) if self._theme_type == MessageTypes.LOADING: icon_label = loading.CircleLoading.tiny(parent=self) else: icon_label = avatar.Avatar.tiny() current_type = self._theme_type or MessageTypes.INFO if current_theme: icon_label.image = resources.pixmap( current_type, color=getattr(current_theme, '{}_color'.format(current_type))) main_frame = QFrame(self) main_frame_layout = layouts.HorizontalLayout(spacing=5, margins=(5, 5, 5, 5)) main_frame.setLayout(main_frame_layout) self.main_layout.addWidget(main_frame) self._content_label = label.BaseLabel(parent=self) self._content_label.setText(self._text) self._close_btn = buttons.BaseToolButton(parent=self).image( 'close', theme='window').icon_only().tiny() self._close_btn.setVisible(self._closable or False) main_frame_layout.addWidget(icon_label) main_frame_layout.addWidget(self._content_label) main_frame_layout.addStretch() main_frame_layout.addWidget(self._close_btn)
def initOtherButtons(self, flags): # other action buttons if len(self.button_list) != 0: self.separator1 = QFrame(self) self.separator1.setFrameShape(QFrame.VLine) self.separator1.setFrameShadow(QFrame.Sunken) self.hlayout.addWidget(self.separator1) self.undoButton = QPushButton(self) self.undoButton.setIcon(QIcon(":/resource/icon/undo.png")) self.undoButton.setFixedSize(self.iconWidth, self.iconWidth) self.undoButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.undoButton) if flags & constant.SAVE_TO_FILE: self.saveButton = QPushButton(self) self.saveButton.setIcon(QIcon(":/resource/icon/save.png")) self.saveButton.setFixedSize(self.iconWidth, self.iconHeight) self.saveButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.saveButton) self.separator2 = QFrame(self) self.separator2.setFrameShape(QFrame.VLine) self.separator2.setFrameShadow(QFrame.Sunken) self.hlayout.addWidget(self.separator2) self.cancelButton = QPushButton(self) self.cancelButton.setIcon(QIcon(":/resource/icon/close.png")) self.cancelButton.setFixedSize(self.iconWidth, self.iconHeight) self.cancelButton.clicked.connect(self.otherButtonsClicked) if flags & constant.CLIPBOARD: self.okButton = QPushButton(self) self.okButton.setIcon(QIcon(":/resource/icon/check.png")) self.okButton.setFixedSize(self.iconWidth, self.iconHeight) self.okButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.okButton) self.hlayout.addWidget(self.cancelButton)
def createWidget(self, menu): widget = QFrame(menu) widget.setObjectName('iconPickerAction') action_layout = layouts.HorizontalLayout(margins=(0, 0, 0, 0)) action_layout.addWidget(self.picker(), stretch=1) widget.setLayout(action_layout) return widget
def __init__(self, *args, **kwargs): super(FormWidget, self).__init__(*args, **kwargs) self._schema = dict() self._widgets = list() self._validator = None main_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) self.setLayout(main_layout) self._fields_frame = QFrame(self) self._fields_frame.setObjectName('fieldsFrame') options_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) self._fields_frame.setLayout(options_layout) self._title_widget = buttons.BaseButton(parent=self) self._title_widget.setCheckable(True) self._title_widget.setObjectName('titleWidget') self._title_widget.toggled.connect(self._on_title_clicked) self._title_widget.hide() main_layout.addWidget(self._title_widget) main_layout.addWidget(self._fields_frame)
def ui(self): super(SaveWidget, self).ui() model_panel_layout = layouts.HorizontalLayout() model_panel_layout.setContentsMargins(0, 0, 0, 0) model_panel_layout.setSpacing(0) thumbnail_layout = layouts.VerticalLayout() thumbnail_layout.setContentsMargins(0, 0, 0, 0) thumbnail_layout.setSpacing(0) self._thumbnail_frame = QFrame() self._thumbnail_frame.setMinimumSize(QSize(50, 50)) self._thumbnail_frame.setMaximumSize(QSize(150, 150)) self._thumbnail_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self._thumbnail_frame.setFrameShape(QFrame.NoFrame) self._thumbnail_frame.setFrameShadow(QFrame.Plain) self._thumbnail_frame.setLineWidth(0) self._thumbnail_frame.setLayout(thumbnail_layout) model_panel_layout.addWidget(self._thumbnail_frame) self._thumbnail_btn = QPushButton() self._thumbnail_btn.setMinimumSize(QSize(0, 0)) self._thumbnail_btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self._thumbnail_btn.setMaximumSize(QSize(150, 150)) self._thumbnail_btn.setToolTip('Take snapshot') self._thumbnail_btn.setStyleSheet( 'color: rgb(40, 40, 40);border: 0px solid rgb(0, 0, 0, 150);background-color: rgb(254, 255, 230, 200);' ) self._thumbnail_btn.setIcon(resources.icon('thumbnail')) self._thumbnail_btn.setToolTip(""" Click to capture a thumbnail from the current viewport.\n CTRL + Click to show the capture window for better framing """) thumbnail_layout.addWidget(self._thumbnail_btn) self._extra_layout.addLayout(model_panel_layout)
def create_horizontal_line(): """ Creates and returns a new horizontal line :return: QFrame """ line_frame = QFrame() line_frame.setFrameShape(QFrame.HLine) line_frame.setFrameShadow(QFrame.Sunken) return line_frame
def create_vertical_line(): """ Creates and returns a new vertical line :return: QFrame """ line_frame = QFrame() line_frame.setFrameShape(QFrame.VLine) line_frame.setFrameShadow(QFrame.Sunken) return line_frame
def __init__(self, *args, **kwargs): super(RangeFieldWidget, self).__init__(*args, **kwargs) widget = QFrame(self) layout = layouts.HorizontalLayout(spacing=4, margins=(0, 0, 0, 0)) widget.setLayout(layout) validator = QIntValidator(-50000000, 50000000, self) self._min_widget = lineedit.BaseLineEdit(parent=self) self._min_widget.setValidator(validator) self._min_widget.textChanged.connect(self._on_emit_value_changed) widget.layout().addWidget(self._min_widget) self._max_widget = lineedit.BaseLineEdit(parent=self) self._max_widget.setValidator(validator) self._max_widget.textChanged.connect(self._on_emit_value_changed) widget.layout().addWidget(self._max_widget) self.set_widget(widget)
def ui(self): super(Project, self).ui() self.setMaximumWidth(qtutils.dpi_scale(160)) self.setMaximumHeight(qtutils.dpi_scale(200)) widget_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) main_frame = QFrame() main_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) main_frame.setLineWidth(1) main_frame.setLayout(widget_layout) self.main_layout.addWidget(main_frame) self.project_btn = QPushButton('', self) self.project_btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.project_btn.setIconSize(QSize(120, 120)) project_lbl = label.BaseLabel(self.name, parent=self) project_lbl.setObjectName('projectLabel') project_lbl.setAlignment(Qt.AlignCenter) widget_layout.addWidget(self.project_btn) widget_layout.addWidget(project_lbl)
def ui(self): super(Template, self).ui() self.setMaximumWidth(160) self.setMaximumHeight(200) widget_layout = layouts.VerticalLayout(spacing=0, margins=(2, 2, 2, 2)) main_frame = QFrame() main_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) main_frame.setLineWidth(1) main_frame.setLayout(widget_layout) self.main_layout.addWidget(main_frame) self.template_btn = QPushButton('', self) self.template_btn.setCheckable(True) self.template_btn.setIcon(self.get_icon()) self.template_btn.setIconSize(QSize(120, 120)) template_lbl = label.BaseLabel(self.name, parent=self) template_lbl.setObjectName('templateLabel') template_lbl.setAlignment(Qt.AlignCenter) widget_layout.addWidget(self.template_btn) widget_layout.addWidget(template_lbl)
def ui(self): super(OptionsViewer, self).ui() edit_mode_icon = resources.icon('edit') move_up_icon = resources.icon('sort_up') move_down_icon = resources.icon('sort_down') remove_icon = resources.icon('delete') self._edit_widget = QWidget() top_layout = layouts.HorizontalLayout() top_layout.setContentsMargins(0, 0, 0, 0) top_layout.setSpacing(2) self._edit_widget.setLayout(top_layout) self.main_layout.addWidget(self._edit_widget) self._edit_mode_btn = buttons.BaseButton(parent=self) self._edit_mode_btn.setIcon(edit_mode_icon) self._edit_mode_btn.setCheckable(True) top_layout.addWidget(self._edit_mode_btn) horizontal_separator = QFrame() horizontal_separator.setFrameShape(QFrame.VLine) horizontal_separator.setFrameShadow(QFrame.Sunken) top_layout.addWidget(horizontal_separator) self._move_up_btn = buttons.BaseButton(parent=self) self.move_down_btn = buttons.BaseButton(parent=self) self.remove_btn = buttons.BaseButton(parent=self) self._move_up_btn.setIcon(move_up_icon) self.move_down_btn.setIcon(move_down_icon) self.remove_btn.setIcon(remove_icon) self._move_up_btn.setVisible(False) self.move_down_btn.setVisible(False) self.remove_btn.setVisible(False) top_layout.addWidget(self._move_up_btn) top_layout.addWidget(self.move_down_btn) top_layout.addWidget(self.remove_btn) top_layout.addStretch() self.main_layout.addWidget(dividers.Divider()) self._scroll = QScrollArea() self._scroll.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self._scroll.setFocusPolicy(Qt.NoFocus) self._scroll.setWidgetResizable(True) self.setFocusPolicy(Qt.NoFocus) self._options_list = self.OPTION_LIST_CLASS(parent=self) self._scroll.setWidget(self._options_list) self.main_layout.addWidget(self._scroll)
def ui(self): super(DoubleSpinBoxAxis, self).ui() axis_widget = QFrame(parent=self) axis_widget.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) axis_layout = layouts.HorizontalLayout(spacing=0, margins=(0, 0, 0, 0)) axis_widget.setLayout(axis_layout) self._axis_btn = buttons.get_axis_button(axis_type=self._axis, parent=self) self._line = BaseDoubleSpinBox(parent=self) self._line.setRange(self._min, self._max) self._line.setValue(self._start) axis_layout.addWidget(self._axis_btn) axis_layout.addWidget(self._line) self.main_layout.addWidget(axis_widget)
def ui(self): super(ExpandablePanel, self).ui() widget_palette = QPalette() widget_palette.setColor(QPalette.Background, QColor.fromRgb(60, 60, 60)) self.setAutoFillBackground(True) self.setPalette(widget_palette) frame = QFrame() frame.setFrameShape(QFrame.StyledPanel) frame.setFrameShadow(QFrame.Sunken) self.main_layout.addWidget(frame) main_layout = layouts.VerticalLayout(spacing=0, margins=(2, 2, 2, 2), parent=frame) main_layout.setAlignment(Qt.AlignTop) self._header_area = QWidget() self._header_area.setMinimumHeight(20) self._widget_area = QWidget() self._widget_area.setAutoFillBackground(True) self._widget_area.setPalette(widget_palette) self._header_text_label = dividers.Divider(self._header_text) self._widget_layout = layouts.VerticalLayout(spacing=5) self._widget_layout.setMargin(5) self._widget_area.setLayout(self._widget_layout) header_layout = layouts.HorizontalLayout(margins=(0, 0, 0, 0)) header_layout.addWidget(self._icon) header_layout.addWidget(self._header_text_label) self._header_area.setLayout(header_layout) main_layout.addWidget(self._header_area) main_layout.addWidget(self._widget_area) self._icon.clicked.connect(self.change_state)
def ui(self): super(DragDoubleSpinBoxLineAxis, self).ui() axis_widget = QFrame() axis_widget.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) axis_layout = layouts.HorizontalLayout(spacing=0, margins=(0, 0, 0, 0)) axis_widget.setLayout(axis_layout) self._axis_btn = buttons.get_axis_button(axis_type=self._axis, parent=self) self._line = DragDoubleSpinBoxLine(start=self._start, max=self._max, min=self._min, positive=self._positive, parent=self) self._reset_btn = buttons.BaseToolButton( parent=self).image('reset').icon_only() self._reset_btn.setVisible(self._reset) self._reset_btn.setEnabled(self._reset) axis_layout.addWidget(self._axis_btn) axis_layout.addWidget(self._line) axis_layout.addWidget(self._reset_btn) self.main_layout.addWidget(axis_widget)
class FormWidget(QFrame, object): accepted = Signal(object) stateChanged = Signal() validated = Signal() def __init__(self, *args, **kwargs): super(FormWidget, self).__init__(*args, **kwargs) self._schema = dict() self._widgets = list() self._validator = None main_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) self.setLayout(main_layout) self._fields_frame = QFrame(self) self._fields_frame.setObjectName('fieldsFrame') options_layout = layouts.VerticalLayout(spacing=0, margins=(0, 0, 0, 0)) self._fields_frame.setLayout(options_layout) self._title_widget = buttons.BaseButton(parent=self) self._title_widget.setCheckable(True) self._title_widget.setObjectName('titleWidget') self._title_widget.toggled.connect(self._on_title_clicked) self._title_widget.hide() main_layout.addWidget(self._title_widget) main_layout.addWidget(self._fields_frame) # ================================================================================================================= # OVERRIDES # ================================================================================================================= def closeEvent(self, event): self.save_persistent_values() super(FormWidget, self).closeEvent(event) # ================================================================================================================= # BASE # ================================================================================================================= def title_widget(self): """ Returns the title widget :return: QWidget """ return self._title_widget def set_title(self, title): """ Sets the title text :param title: str """ self.title_widget().setText(title) def is_expanded(self): """ Returns whether the item is expanded or not :return: bool """ return self._title_widget.isChecked() def set_expanded(self, flag): """ Expands the options if True, otherwise collapses the options :param flag: bool """ with qt_contexts.block_signals(self._title_widget): self._title_widget.setChecked(flag) self._fields_frame.setVisible(flag) def set_title_visible(self, flag): """ Sets whether the title widget is visible or not :param flag: bool """ self.title_widget().setVisible(flag) def widget(self, name): """ Returns the widget for the given widget name :param name: str :return: FieldWidget """ for widget in self._widgets: if widget.data().get('name') == name: return widget def value(self, name): """ Returns the value for the given widget name :param name: str :return: object """ widget = self.widget(name) if not widget: return None return widget.value() def set_value(self, name, value): """ Sets the value for the given field name :param name: str :param value: variant """ widget = self.widget(name) widget.set_value(value) def values(self): """ Returns all the field values indexed by the field name :return: dict """ values = dict() for widget in self._widgets: name = widget.data().get('name') if name: values[name] = widget.value() return values def set_values(self, values): """ Sets the field values for the current form :param values: dict """ state = list() for name in values: state.append({'name': name, 'value': values[name]}) self._set_state(state) def default_values(self): """ Returns all teh default field values indexed by the field name :return: dict """ values = dict() for widget in self._widgets: name = widget.data().get('name') if name: values[name] = widget.default() return values def set_data(self, name, data): """ Sets the data for the given field name :param name: str :param data: dict """ widget = self.widget(name) if not widget: return widget.set_data(data) def fields(self): """ Returns fields data for the form :return: list(dict) """ options = list() for widget in self._widgets: options.append(widget.data()) return options def field_widgets(self): """ Returns all field widgets :return: list(FieleWidget) """ return self._widgets def state(self): """ Returns the current state :return: dict """ fields = list() for widget in self._widgets: fields.append(widget.state()) state = { 'fields': fields, 'expanded': self.is_expanded() } return state def set_state(self, state): """ Sets the current state :param state: dict """ expanded = state.get('expanded') if expanded is not None: self.set_expanded(expanded) fields = state.get('fields') if fields is not None: self._set_state(fields) self.validate() def schema(self): """ Returns form's schema :return: dict """ return self._schema def set_schema(self, schema, layout=None, errors_visible=False): """ Sets the schema for the widget :param schema: list(dict) :param layout: str :param errors_visible: str """ self._schema = self._sort_schema(schema) if not self._schema: return for field in schema: cls = formfields.FIELD_WIDGET_REGISTRY.get(field.get('type', 'label')) if not cls: LOGGER.warning('Cannot find widget for {}'.format(field)) continue if layout and not field.get('layout'): field['layout'] = layout enabled = field.get('enabled', True) read_only = field.get('readOnly', False) error_visible = field.get('errorVisible') field['errorVisible'] = error_visible if error_visible is not None else errors_visible widget = cls(data=field, parent=self._fields_frame, form_widget=self) data = widget.default_data() data.update(field) widget.set_data(data) value = field.get('value') default = field.get('default') if value is None and default is not None: widget.set_value(default) if not enabled or read_only: widget.setEnabled(False) self._widgets.append(widget) callback = partial(self._on_field_changed, widget) widget.valueChanged.connect(callback) self._fields_frame.layout().addWidget(widget) self.load_persistent_values() def validator(self): """ Returns the validator for the form :return: fn """ return self._validator def set_validator(self, validator): """ Sets the validator for the options :param validator: fn """ self._validator = validator def reset(self): """ Reset all option widget back to the ir default values """ for widget in self._widgets: widget.reset() self.validate() def validate(self, widget=None): """ Validates the current options using the validator """ if not self._validator: return values = dict() for name, value in self.values().items(): data = self.widget(name).data() if data.get('validate', True): values[name] = value if widget: values['fieldChanged'] = widget.name() fields = self._validator(**values) if fields is not None: self._set_state(fields) self.validated.emit() def errors(self): """ Returns all form errors :return: list(str) """ errors = list() for widget in self._widgets: error = widget.data().get('error') if error: errors.append(error) return errors def has_errors(self): """ Returns whether the form contains any error :return: bool """ return bool(self.errors()) def save_persistent_values(self): """ Saves form widget values Triggered when the user changes field values """ data = dict() for widget in self._widgets: name = widget.data().get('name') if name and widget.data().get('persistent'): key = self.objectName() or 'FormWidget' key = widget.data().get('persistentKey', key) data.setdefault(key, dict()) data[key][name] = widget.value() for key in data: settings.set(key, data[key]) def load_persistent_values(self): """ Returns the options from the user settings :return: dict """ values = dict() default_values = self.default_values() for field in self.schema(): name = field.get('name') persistent = field.get('persistent') if persistent: key = self.objectName() or 'FormWidget' key = field.get('persistentKey', key) value = settings.get(key, dict()).get(name) else: value = default_values.get(name) if value is not None: values[name] = value self.set_values(values) # ============================================================================================================ # INTERNAL # ============================================================================================================ def _sort_schema(self, schema): """ Internal function that sorts the schema depending on the group order :param schema: list(dict) :return: list(dict) """ def _key(field): return field['order'] order = 0 if not schema: return for i, field in enumerate(schema): if field.get('type') == 'group': order = field.get('order', order) field['order'] = order return sorted(schema, key=_key) def _set_state(self, fields): """ Internal function that sets fields state :param fields: list(dict) """ for widget in self._widgets: widget.blockSignals(True) try: for widget in self._widgets: widget.set_error('') for field in fields: if field.get('name') == widget.data().get('name'): widget.set_data(field) finally: for widget in self._widgets: widget.blockSignals(False) self.stateChanged.emit() # ============================================================================================================ # CALLBACKS # ============================================================================================================ def _on_title_clicked(self, toggle): """ Internal callback function that is triggered when the user clicks in the title widget """ self.set_expanded(toggle) self.stateChanged.emit() def _on_field_changed(self, widget): """ Internal callback function triggered when the given option widget changes its value :param widget: FieldWidget """ self.validate(widget=widget)
class FixedAttributesWidget(QWidget): """ A widget for viewing/editing fixed attributes (non-varying) """ def __init__(self, data, parent=None): QWidget.__init__(self, parent) self.data = data vbox = QVBoxLayout() self.setLayout(vbox) title = QLabel('Fixed Attributes') vbox.addWidget(title) self.frame = QFrame() vbox.addWidget(self.frame) self.vbox = QVBoxLayout() self.frame.setLayout(self.vbox) self.frame.setFrameShape(QFrame.Panel) self.frame.setFrameShadow(QFrame.Sunken) self.table = QTableWidget() self.table.horizontalHeader().hide() self.vbox.addWidget(self.table) self.table.hide() self.noAttrLabel = QLabel('<i>No fixed attributes</i>') self.vbox.addWidget(self.noAttrLabel) self.widgets = [] self.populate() self.data.fixedAttributeAdded.connect(self.fixedAttributeAddedSlot) self.data.dataReset.connect(self.dataResetSlot) self.data.dirtied.connect(self.dataDirtiedSlot) def dataDirtiedSlot(self, dirty): """ SLOT when the particle data is dirtied or cleaned.""" if not dirty: for widget in self.widgets: widget.drawBorder(False) def dataResetSlot(self): """ SLOT when particle data is reconstructed """ self.populate() def fixedAttributeAddedSlot(self, name): #pylint:disable=W0613 """ SLOT when a fixed attribute is added to the particle set """ self.populate() def populate(self): """ Populates the table of fixed attributes """ self.widgets = [] # If no widgets, just drop that in numAttrs = self.data.numFixedAttributes() if not numAttrs: self.table.hide() self.noAttrLabel.show() return self.table.show() self.noAttrLabel.hide() self.table.setColumnCount(1) self.table.setRowCount(numAttrs) self.attrs = getAttrs(self.data.numFixedAttributes, self.data.fixedAttributeInfo, True) for row, (_, attr) in enumerate(self.attrs): item = QTableWidgetItem(attr.name) tooltip = '<p><tt> Name: {}<br> Type: {}<br>Count: {}</tt></p>'.\ format(attr.name, partio.TypeName(attr.type), attr.count) item.setToolTip(tooltip) self.table.setVerticalHeaderItem(row, item) value = self.data.getFixed(attr) widget = getWidget(value, self.data, attr) self.table.setCellWidget(row, 0, widget) self.widgets.append(widget) self.table.horizontalHeader().setStretchLastSection(False) self.table.setTabKeyNavigation(True) self.table.horizontalHeader().setSectionsMovable(False) self.table.horizontalHeader().resizeSections(QHeaderView.ResizeToContents) self.table.verticalHeader().resizeSections(QHeaderView.ResizeToContents)
class IndexedStringsWidget(QWidget): """ Holds the list of indexed string attributes """ def __init__(self, data, parent=None): QWidget.__init__(self, parent) self.data = data vbox = QVBoxLayout() self.setLayout(vbox) title = QLabel('Indexed Strings') vbox.addWidget(title) self.frame = QFrame() vbox.addWidget(self.frame) self.vbox = QVBoxLayout() self.frame.setLayout(self.vbox) self.frame.setFrameShape(QFrame.Panel) self.frame.setFrameShadow(QFrame.Sunken) self.table = QTableWidget() self.table.horizontalHeader().hide() self.vbox.addWidget(self.table) self.table.hide() self.noStringsLabel = QLabel('<i>No indexed strings</i>') self.vbox.addWidget(self.noStringsLabel) self.widgets = [] self.populate() self.data.attributeAdded.connect(self.attributeAddedSlot) self.data.dataReset.connect(self.dataResetSlot) self.data.dirtied.connect(self.dataDirtiedSlot) def dataDirtiedSlot(self, dirty): """ SLOT when the particle data is dirtied or cleaned.""" if not dirty: for widget in self.widgets: widget.drawBorder(False) def dataResetSlot(self): """ SLOT when particle data is reconstructed """ self.populate() def attributeAddedSlot(self, name): #pylint:disable=W0613 """ SLOT when an attribute is added to the particle set """ attr = self.data.attributeInfo(name) if attr.type == partio.INDEXEDSTR: self.populate() def populate(self): """ Populates the table of indexed strings """ self.widgets = [] # If no widgets, just drop that in attrs = [] for anum in range(self.data.numAttributes()): attr = self.data.attributeInfo(anum) if attr.type == partio.INDEXEDSTR: attrs.append(attr) if not attrs: self.table.hide() self.noStringsLabel.show() return self.table.show() self.noStringsLabel.hide() self.table.setColumnCount(1) self.table.setRowCount(len(attrs)) for row, attr in enumerate(attrs): item = QTableWidgetItem(attr.name) self.table.setVerticalHeaderItem(row, item) strings = self.data.indexedStrs(attr) table = QTableWidget() table.setColumnCount(1) table.setRowCount(len(strings)) table.horizontalHeader().hide() table.setVerticalHeaderLabels([str(i) for i in range(len(strings))]) for i, string in enumerate(strings): widget = QLabel(string) table.setCellWidget(i, 0, widget) self.widgets.append(widget) self.table.setCellWidget(row, 0, table) self.table.horizontalHeader().setStretchLastSection(False) self.table.setTabKeyNavigation(True) self.table.horizontalHeader().setSectionsMovable(False) self.table.horizontalHeader().resizeSections(QHeaderView.ResizeToContents) self.table.verticalHeader().resizeSections(QHeaderView.ResizeToContents)