def __init__(self, alignment=Qt.AlignCenter, parent=None): super(MLineTabWidget, self).__init__(parent=parent) self.tool_button_group = MUnderlineButtonGroup() self.bar_layout = QHBoxLayout() self.bar_layout.setContentsMargins(0, 0, 0, 0) if alignment == Qt.AlignCenter: self.bar_layout.addStretch() self.bar_layout.addWidget(self.tool_button_group) self.bar_layout.addStretch() elif alignment == Qt.AlignLeft: self.bar_layout.addWidget(self.tool_button_group) self.bar_layout.addStretch() elif alignment == Qt.AlignRight: self.bar_layout.addStretch() self.bar_layout.addWidget(self.tool_button_group) self.stack_widget = MStackedWidget() self.tool_button_group.sig_checked_changed.connect( self.stack_widget.setCurrentIndex) main_lay = QVBoxLayout() main_lay.setContentsMargins(0, 0, 0, 0) main_lay.setSpacing(0) main_lay.addLayout(self.bar_layout) main_lay.addWidget(MDivider()) main_lay.addSpacing(5) main_lay.addWidget(self.stack_widget) self.setLayout(main_lay)
class MCard(QWidget): def __init__(self, title=None, image=None, size=None, extra=None, type=None, parent=None): super(MCard, self).__init__(parent=parent) self.setAttribute(Qt.WA_StyledBackground) self.setProperty('border', False) size = size or dayu_theme.default_size map_label = { dayu_theme.large: (MLabel.H2Level, 20), dayu_theme.medium: (MLabel.H3Level, 15), dayu_theme.small: (MLabel.H4Level, 10), } self._title_label = MLabel(text=title) self._title_label.set_dayu_level(map_label.get(size)[0]) padding = map_label.get(size)[-1] self._title_layout = QHBoxLayout() self._title_layout.setContentsMargins(padding, padding, padding, padding) if image: self._title_icon = MAvatar() self._title_icon.set_dayu_image(image) self._title_icon.set_dayu_size(size) self._title_layout.addWidget(self._title_icon) self._title_layout.addWidget(self._title_label) self._title_layout.addStretch() if extra: self._extra_button = MToolButton().icon_only().svg('more.svg') self._title_layout.addWidget(self._extra_button) self._content_layout = QVBoxLayout() self._main_lay = QVBoxLayout() self._main_lay.setSpacing(0) self._main_lay.setContentsMargins(1, 1, 1, 1) if title: self._main_lay.addLayout(self._title_layout) self._main_lay.addWidget(MDivider()) self._main_lay.addLayout(self._content_layout) self.setLayout(self._main_lay) def get_more_button(self): return self._extra_button def set_widget(self, widget): self._content_layout.addWidget(widget) def border(self): self.setProperty('border', True) self.style().polish(self) return self
def __init__(self, parent=None): super(MMenuTabWidget, self).__init__(parent=parent) self.tool_button_group = MBlockButtonGroup() self._bar_layout = QHBoxLayout() self._bar_layout.setContentsMargins(10, 0, 10, 0) self._bar_layout.addWidget(self.tool_button_group) self._bar_layout.addStretch() bar_widget = QWidget() bar_widget.setObjectName('bar_widget') bar_widget.setLayout(self._bar_layout) bar_widget.setAttribute(Qt.WA_StyledBackground) main_lay = QVBoxLayout() main_lay.setContentsMargins(0, 0, 0, 0) main_lay.setSpacing(0) main_lay.addWidget(bar_widget) main_lay.addWidget(MDivider()) main_lay.addSpacing(5) self.setLayout(main_lay) self.setFixedHeight(dayu_theme.large + 10)
def _init_ui(self): item_list = [ { 'text': 'Overview', 'svg': 'home_line.svg', 'clicked': functools.partial(MMessage.info, u'首页', parent=self) }, { 'text': u'我的', 'svg': 'user_line.svg', 'clicked': functools.partial(MMessage.info, u'编辑账户', parent=self) }, { 'text': u'Notice', 'svg': 'alert_line.svg', 'clicked': functools.partial(MMessage.info, u'查看通知', parent=self) }, ] tool_bar = MMenuTabWidget() tool_bar.tool_bar_insert_widget( MLabel('DaYu').h4().secondary().strong()) tool_bar.tool_bar_append_widget( MBadge.dot( show=True, widget=MToolButton().icon_only().svg('user_fill.svg').large())) self.content_widget = MLabel() for index, data_dict in enumerate(item_list): tool_bar.add_menu(data_dict, index) tool_bar.tool_button_group.set_dayu_checked(0) main_lay = QVBoxLayout() main_lay.setContentsMargins(0, 0, 0, 0) main_lay.addWidget(tool_bar) main_lay.addWidget(self.content_widget) self.setLayout(main_lay)
def __init__(self, cover=None, avatar=None, title=None, description=None, extra=False, parent=None): super(MMeta, self).__init__(parent) self.setAttribute(Qt.WA_StyledBackground) self._cover_label = QLabel() self._avatar = MAvatar() self._title_label = MLabel().h4() self._description_label = MLabel().secondary() self._description_label.setWordWrap(True) self._description_label.set_elide_mode(Qt.ElideRight) self._title_layout = QHBoxLayout() self._title_layout.addWidget(self._title_label) self._title_layout.addStretch() self._extra_button = MToolButton( parent=self).icon_only().svg('more.svg') self._title_layout.addWidget(self._extra_button) self._extra_button.setVisible(extra) content_lay = QFormLayout() content_lay.setContentsMargins(5, 5, 5, 5) content_lay.addRow(self._avatar, self._title_layout) content_lay.addRow(self._description_label) self._button_layout = QHBoxLayout() main_lay = QVBoxLayout() main_lay.setSpacing(0) main_lay.setContentsMargins(1, 1, 1, 1) main_lay.addWidget(self._cover_label) main_lay.addLayout(content_lay) main_lay.addLayout(self._button_layout) main_lay.addStretch() self.setLayout(main_lay) self._cover_label.setFixedSize(QSize(200, 200))
def _init_ui(self): main_lay = QVBoxLayout() self.setLayout(main_lay) main_lay.addWidget(MDivider('circle')) lay1 = QHBoxLayout() circle_1 = MProgressCircle(parent=self) circle_1.setFormat(u'%p Days') circle_1.setValue(80) circle_2 = MProgressCircle(parent=self) circle_2.set_dayu_color(dayu_theme.success_color) circle_2.setValue(100) circle_3 = MProgressCircle(parent=self) circle_3.set_dayu_color(dayu_theme.error_color) circle_3.setValue(40) dashboard_1 = MProgressCircle.dashboard(parent=self) dashboard_1.setFormat(u'%p Days') dashboard_1.setValue(80) dashboard_2 = MProgressCircle.dashboard(parent=self) dashboard_2.set_dayu_color(dayu_theme.success_color) dashboard_2.setValue(100) dashboard_3 = MProgressCircle.dashboard(parent=self) dashboard_3.set_dayu_color(dayu_theme.error_color) dashboard_3.setValue(40) lay1.addWidget(circle_1) lay1.addWidget(circle_2) lay1.addWidget(circle_3) dashboard_lay = QHBoxLayout() dashboard_lay.addWidget(dashboard_1) dashboard_lay.addWidget(dashboard_2) dashboard_lay.addWidget(dashboard_3) main_lay.addLayout(lay1) main_lay.addWidget(MDivider('dashboard')) main_lay.addLayout(dashboard_lay) main_lay.addWidget(MDivider('different radius')) circle_4 = MProgressCircle(parent=self) circle_4.set_dayu_width(100) circle_4.setValue(40) circle_5 = MProgressCircle(parent=self) circle_5.setValue(40) circle_6 = MProgressCircle(parent=self) circle_6.set_dayu_width(160) circle_6.setValue(40) lay2 = QHBoxLayout() lay2.addWidget(circle_4) lay2.addWidget(circle_5) lay2.addWidget(circle_6) main_lay.addLayout(lay2) main_lay.addWidget(MDivider('data bind')) self.register_field('percent', 0) self.register_field('color', self.get_color) self.register_field('format', self.get_format) circle = MProgressCircle(parent=self) self.bind('percent', circle, 'value') self.bind('color', circle, 'dayu_color') self.bind('format', circle, 'format') lay3 = QHBoxLayout() button_grp = MPushButtonGroup() button_grp.set_dayu_type(MPushButton.DefaultType) button_grp.set_button_list([ {'text': '+', 'clicked': functools.partial(self.slot_change_percent, 10)}, {'text': '-', 'clicked': functools.partial(self.slot_change_percent, -10)}, ]) lay3.addWidget(circle) lay3.addWidget(button_grp) lay3.addStretch() main_lay.addLayout(lay3) custom_widget = QWidget() custom_layout = QVBoxLayout() custom_layout.setContentsMargins(20, 20, 20, 20) custom_layout.addStretch() custom_widget.setLayout(custom_layout) lab1 = MLabel(text='42,001,776').h3() lab2 = MLabel(text=u'消费人群规模').secondary() lab3 = MLabel(text=u'总占人数 75%').secondary() lab1.setAlignment(Qt.AlignCenter) lab2.setAlignment(Qt.AlignCenter) lab3.setAlignment(Qt.AlignCenter) custom_layout.addWidget(lab1) custom_layout.addWidget(lab2) custom_layout.addWidget(MDivider()) custom_layout.addWidget(lab3) custom_layout.addStretch() custom_circle = MProgressCircle() custom_circle.set_dayu_width(180) custom_circle.setValue(75) custom_circle.set_widget(custom_widget) main_lay.addWidget(MDivider('custom circle')) main_lay.addWidget(custom_circle) main_lay.addStretch()
def _init_ui(self): basic_card_lay = MFlowLayout() basic_card_lay.setSpacing(20) for setting in [{ 'title': '', }, { 'title': 'Card Title', 'size': dayu_theme.small }, { 'title': 'Card Title', 'image': MPixmap('app-houdini.png') }, { 'title': 'Card Title', 'extra': 'More', 'image': MPixmap('app-houdini.png') }, { 'title': 'Card Title', 'extra': 'More', }]: card_0 = MCard(**setting) content_widget_0 = QWidget() content_lay_0 = QVBoxLayout() content_lay_0.setContentsMargins(15, 15, 15, 15) content_widget_0.setLayout(content_lay_0) for i in range(4): content_lay_0.addWidget(MLabel('Card Content {}'.format(i + 1))) card_0.set_widget(content_widget_0) basic_card_lay.addWidget(card_0) meta_card_lay = MFlowLayout() meta_card_lay.setSpacing(20) for setting in [ { 'title': u'Houdini', 'description': u'Side Effects Software的旗舰级产品,是创建高级视觉效果的有效工具', 'avatar': MPixmap('user_line.svg'), 'cover': MPixmap('app-houdini.png') }, { 'title': u'Autodesk Maya', 'description': u'3D 数字动画和视觉效果的世界领先软件应用程序', 'cover': MPixmap('app-maya.png') }, ]: meta_card = MMeta() meta_card.setup_data(setting) meta_card_lay.addWidget(meta_card) task_card_lay = QVBoxLayout() # task_card_lay.setSpacing(10) for setting in [ { 'title': u'Task A', 'description': u'demo pl_0010 Animation \n2019/04/01 - 2019/04/09', 'avatar': MPixmap('success_line.svg', dayu_theme.success_color), }, { 'title': u'Task B', 'description': u'#2 closed by xiao hua.', 'avatar': MPixmap('error_line.svg', dayu_theme.error_color) }, { 'title': u'Task C', 'description': u'#3 closed by xiao hua.', 'avatar': MPixmap('warning_line.svg', dayu_theme.warning_color) } ] * 5: meta_card = MMeta(extra=True) meta_card.setup_data(setting) task_card_lay.addWidget(meta_card) left_lay = QVBoxLayout() left_lay.addWidget(MDivider('Basic')) left_lay.addLayout(basic_card_lay) left_lay.addWidget(MDivider('Meta E-Commerce Example')) left_lay.addLayout(meta_card_lay) left_lay.addStretch() left_widget = QWidget() left_widget.setLayout(left_lay) right_lay = QVBoxLayout() right_lay.addWidget(MDivider('Meta Task Item Example')) scroll = QScrollArea() scroll.setWidgetResizable(True) task_widget = QWidget() task_widget.setLayout(task_card_lay) scroll.setWidget(task_widget) right_lay.addWidget(scroll) right_widget = QWidget() right_widget.setLayout(right_lay) splitter = QSplitter() splitter.addWidget(left_widget) splitter.addWidget(right_widget) splitter.setStretchFactor(0, 80) splitter.setStretchFactor(1, 20) main_lay = QVBoxLayout() main_lay.addWidget(splitter) self.setLayout(main_lay)
def __init__(self, text, duration=None, dayu_type=None, parent=None): super(MToast, self).__init__(parent) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog | Qt.WA_TranslucentBackground | Qt.WA_DeleteOnClose) self.setAttribute(Qt.WA_StyledBackground) _icon_lay = QHBoxLayout() _icon_lay.addStretch() if dayu_type == MToast.LoadingType: _icon_lay.addWidget( MLoading(size=dayu_theme.huge, color=dayu_theme.text_color_inverse)) else: _icon_label = MAvatar() _icon_label.set_dayu_size(60) _icon_label.set_dayu_image( MPixmap('{}_line.svg'.format(dayu_type or MToast.InfoType), dayu_theme.text_color_inverse)) _icon_lay.addWidget(_icon_label) _icon_lay.addStretch() _content_label = MLabel() _content_label.setText(text) _content_label.setAlignment(Qt.AlignCenter) _main_lay = QVBoxLayout() _main_lay.setContentsMargins(0, 0, 0, 0) _main_lay.addStretch() _main_lay.addLayout(_icon_lay) _main_lay.addSpacing(10) _main_lay.addWidget(_content_label) _main_lay.addStretch() self.setLayout(_main_lay) self.setFixedSize(QSize(120, 120)) _close_timer = QTimer(self) _close_timer.setSingleShot(True) _close_timer.timeout.connect(self.close) _close_timer.timeout.connect(self.sig_closed) _close_timer.setInterval( (duration or self.default_config.get('duration')) * 1000) _ani_timer = QTimer(self) _ani_timer.timeout.connect(self._fade_out) _ani_timer.setInterval( (duration or self.default_config.get('duration')) * 1000 - 300) _close_timer.start() _ani_timer.start() self._opacity_ani = QPropertyAnimation() self._opacity_ani.setTargetObject(self) self._opacity_ani.setDuration(300) self._opacity_ani.setEasingCurve(QEasingCurve.OutCubic) self._opacity_ani.setPropertyName(b'windowOpacity') self._opacity_ani.setStartValue(0.0) self._opacity_ani.setEndValue(0.9) self._get_center_position(parent) self._fade_int()
class MItemViewSet(QWidget): sig_double_clicked = Signal(QModelIndex) sig_left_clicked = Signal(QModelIndex) TableViewType = MTableView BigViewType = MBigView TreeViewType = MTreeView ListViewType = MListView def __init__(self, view_type=None, parent=None): super(MItemViewSet, self).__init__(parent) self._main_lay = QVBoxLayout() self._main_lay.setSpacing(5) self._main_lay.setContentsMargins(0, 0, 0, 0) self.sort_filter_model = MSortFilterModel() self.source_model = MTableModel() self.sort_filter_model.setSourceModel(self.source_model) view_class = view_type or MItemViewSet.TableViewType self.item_view = view_class() self.item_view.doubleClicked.connect(self.sig_double_clicked) self.item_view.pressed.connect(self.slot_left_clicked) self.item_view.setModel(self.sort_filter_model) self._search_line_edit = MLineEdit().search().small() self._search_attr_button = MToolButton().icon_only().svg( 'down_fill.svg').small() self._search_line_edit.set_prefix_widget(self._search_attr_button) self._search_line_edit.textChanged.connect( self.sort_filter_model.set_search_pattern) self._search_line_edit.setVisible(False) _search_lay = QHBoxLayout() _search_lay.setContentsMargins(0, 0, 0, 0) _search_lay.addStretch() _search_lay.addWidget(self._search_line_edit) self._main_lay.addLayout(_search_lay) self._main_lay.addWidget(self.item_view) self.setLayout(self._main_lay) @Slot(QModelIndex) def slot_left_clicked(self, start_index): button = QApplication.mouseButtons() if button == Qt.LeftButton: real_index = self.sort_filter_model.mapToSource(start_index) self.sig_left_clicked.emit(real_index) def set_header_list(self, header_list): self.source_model.set_header_list(header_list) self.sort_filter_model.set_header_list(header_list) self.sort_filter_model.setSourceModel(self.source_model) self.item_view.set_header_list(header_list) @Slot() def setup_data(self, data_list): self.source_model.clear() if data_list: self.source_model.set_data_list(data_list) def get_data(self): return self.source_model.get_data_list() def searchable(self): """Enable search line edit visible.""" self._search_line_edit.setVisible(True) return self
class MItemViewFullSet(QWidget): sig_double_clicked = Signal(QModelIndex) sig_left_clicked = Signal(QModelIndex) sig_current_changed = Signal(QModelIndex, QModelIndex) sig_current_row_changed = Signal(QModelIndex, QModelIndex) sig_current_column_changed = Signal(QModelIndex, QModelIndex) sig_selection_changed = Signal(QItemSelection, QItemSelection) sig_context_menu = Signal(object) def __init__(self, table_view=True, big_view=False, parent=None): super(MItemViewFullSet, self).__init__(parent) self.sort_filter_model = MSortFilterModel() self.source_model = MTableModel() self.sort_filter_model.setSourceModel(self.source_model) self.stack_widget = QStackedWidget() self.view_button_grp = MToolButtonGroup(exclusive=True) data_group = [] if table_view: self.table_view = MTableView(show_row_count=True) self.table_view.doubleClicked.connect(self.sig_double_clicked) self.table_view.pressed.connect(self.slot_left_clicked) self.table_view.setModel(self.sort_filter_model) self.stack_widget.addWidget(self.table_view) data_group.append({ 'svg': 'table_view.svg', 'checkable': True, 'tooltip': u'Table View' }) if big_view: self.big_view = MBigView() self.big_view.doubleClicked.connect(self.sig_double_clicked) self.big_view.pressed.connect(self.slot_left_clicked) self.big_view.setModel(self.sort_filter_model) self.stack_widget.addWidget(self.big_view) data_group.append({ 'svg': 'big_view.svg', 'checkable': True, 'tooltip': u'Big View' }) # 设置多个view 共享 MItemSelectionModel leader_view = self.stack_widget.widget(0) self.selection_model = leader_view.selectionModel() for index in range(self.stack_widget.count()): if index == 0: continue other_view = self.stack_widget.widget(index) other_view.setSelectionModel(self.selection_model) self.selection_model.currentChanged.connect(self.sig_current_changed) self.selection_model.currentRowChanged.connect( self.sig_current_row_changed) self.selection_model.currentColumnChanged.connect( self.sig_current_column_changed) self.selection_model.selectionChanged.connect( self.sig_selection_changed) self.tool_bar = QWidget() self.top_lay = QHBoxLayout() self.top_lay.setContentsMargins(0, 0, 0, 0) if data_group and len(data_group) > 1: self.view_button_grp.sig_checked_changed.connect( self.stack_widget.setCurrentIndex) self.view_button_grp.set_button_list(data_group) self.view_button_grp.set_dayu_checked(0) self.top_lay.addWidget(self.view_button_grp) self.search_line_edit = MLineEdit().search().small() self.search_attr_button = MToolButton().icon_only().svg( 'down_fill.svg').small() self.search_line_edit.set_prefix_widget(self.search_attr_button) self.search_line_edit.textChanged.connect( self.sort_filter_model.set_search_pattern) self.search_line_edit.setVisible(False) self.top_lay.addStretch() self.top_lay.addWidget(self.search_line_edit) self.tool_bar.setLayout(self.top_lay) self.page_set = MPage() self.main_lay = QVBoxLayout() self.main_lay.setSpacing(5) self.main_lay.setContentsMargins(0, 0, 0, 0) self.main_lay.addWidget(self.tool_bar) self.main_lay.addWidget(self.stack_widget) self.main_lay.addWidget(self.page_set) self.setLayout(self.main_lay) def enable_context_menu(self): for index in range(self.stack_widget.count()): view = self.stack_widget.widget(index) view.enable_context_menu(True) view.sig_context_menu.connect(self.sig_context_menu) def set_no_data_text(self, text): for index in range(self.stack_widget.count()): view = self.stack_widget.widget(index) view.set_no_data_text(text) def set_selection_mode(self, mode): for index in range(self.stack_widget.count()): view = self.stack_widget.widget(index) view.setSelectionMode(mode) def tool_bar_visible(self, flag): self.tool_bar.setVisible(flag) @Slot(QModelIndex) def slot_left_clicked(self, start_index): button = QApplication.mouseButtons() if button == Qt.LeftButton: real_index = self.sort_filter_model.mapToSource(start_index) self.sig_left_clicked.emit(real_index) def set_header_list(self, header_list): self.source_model.set_header_list(header_list) self.sort_filter_model.set_header_list(header_list) self.sort_filter_model.setSourceModel(self.source_model) for index in range(self.stack_widget.count()): view = self.stack_widget.widget(index) view.set_header_list(header_list) def tool_bar_append_widget(self, widget): self.top_lay.addWidget(widget) def tool_bar_insert_widget(self, widget): self.top_lay.insertWidget(0, widget) @Slot() def setup_data(self, data_list): self.source_model.clear() if data_list: self.source_model.set_data_list(data_list) self.set_record_count(len(data_list)) @Slot(int) def set_record_count(self, total): self.page_set.set_total(total) def get_data(self): return self.source_model.get_data_list() def searchable(self): """Enable search line edit visible.""" self.search_line_edit.setVisible(True) return self