def __init__(self, parent, cli_iface, iface_name):
        super(ControlPanelWindow, self).__init__(parent)
        self.setWindowTitle('SLCAN Adapter Control Panel')
        self.setAttribute(Qt.WA_DeleteOnClose)              # This is required to stop background timers!

        self._cli_iface = cli_iface
        self._iface_name = iface_name

        self._state_widget = StateWidget(self, self._cli_iface)
        self._config_widget = ConfigWidget(self, self._cli_iface)
        self._cli_widget = CLIWidget(self, self._cli_iface)

        self._tab_widget = QTabWidget(self)
        self._tab_widget.addTab(self._state_widget, get_icon('dashboard'), 'Adapter State')
        self._tab_widget.addTab(self._config_widget, get_icon('wrench'), 'Configuration')
        self._tab_widget.addTab(self._cli_widget, get_icon('terminal'), 'Command Line')

        self._status_bar = QStatusBar(self)
        self._status_bar.setSizeGripEnabled(False)

        iface_name_label = QLabel(iface_name.split('/')[-1], self)
        iface_name_label.setFont(get_monospace_font())

        layout = QVBoxLayout(self)
        layout.addWidget(iface_name_label)
        layout.addWidget(self._tab_widget)
        layout.addWidget(self._status_bar)

        left, top, right, bottom = layout.getContentsMargins()
        bottom = 0
        layout.setContentsMargins(left, top, right, bottom)

        self.setLayout(layout)
        self.resize(400, 400)
Exemple #2
0
    def __init__(
        self, parent, node, target_node_id, file_server_widget, node_monitor, dynamic_node_id_allocator_widget
    ):
        super(NodePropertiesWindow, self).__init__(parent)
        self.setAttribute(Qt.WA_DeleteOnClose)  # This is required to stop background timers!
        self.setWindowTitle("Node Properties [%d]" % target_node_id)
        self.setMinimumWidth(640)

        self._target_node_id = target_node_id
        self._node = node
        self._file_server_widget = file_server_widget

        self._info_box = InfoBox(self, target_node_id, node_monitor)
        self._controls = Controls(self, node, target_node_id, file_server_widget, dynamic_node_id_allocator_widget)
        self._config_params = ConfigParams(self, node, target_node_id)

        self._status_bar = QStatusBar(self)
        self._status_bar.setSizeGripEnabled(False)

        layout = QVBoxLayout(self)
        layout.addWidget(self._info_box)
        layout.addWidget(self._controls)
        layout.addWidget(self._config_params)
        layout.addWidget(self._status_bar)

        left, top, right, bottom = layout.getContentsMargins()
        bottom = 0
        layout.setContentsMargins(left, top, right, bottom)

        self.setLayout(layout)
    def __init__(self, parent, node, target_node_id, file_server_widget,
                 node_monitor, dynamic_node_id_allocator_widget):
        super(NodePropertiesWindow, self).__init__(parent)
        self.setAttribute(
            Qt.WA_DeleteOnClose)  # This is required to stop background timers!
        self.setWindowTitle('Node Properties [%d]' % target_node_id)
        self.setMinimumWidth(640)

        self._target_node_id = target_node_id
        self._node = node
        self._file_server_widget = file_server_widget

        self._info_box = InfoBox(self, target_node_id, node_monitor)
        self._controls = Controls(self, node, target_node_id,
                                  file_server_widget,
                                  dynamic_node_id_allocator_widget)
        self._config_params = ConfigParams(self, node, target_node_id)

        self._status_bar = QStatusBar(self)
        self._status_bar.setSizeGripEnabled(False)

        layout = QVBoxLayout(self)
        layout.addWidget(self._info_box)
        layout.addWidget(self._controls)
        layout.addWidget(self._config_params)
        layout.addWidget(self._status_bar)

        left, top, right, bottom = layout.getContentsMargins()
        bottom = 0
        layout.setContentsMargins(left, top, right, bottom)

        self.setLayout(layout)
Exemple #4
0
    def refresh(self):
        addons = sorted(self._addons, key=lambda item: item.name)
        
        prev_checked = set(addon.identifier for addon in self.__checked_addons)
        prev_unchecked = set(addon.identifier for addon in self.__addons if addon not in self.__checked_addons)
        
        self.__addons = list(addons)
        
        self.__checked_addons = set()
        
        button_factory = self._addon_button_factory()
        
        self.setRowCount(len(self.__addons))
        
        for no, addon in enumerate(self.__addons):
            check_widget = QWidget()
            check_layout = QHBoxLayout()
            check_layout.setAlignment(Qt.AlignCenter)
            check_check = QCheckBox()
            if addon.identifier not in prev_unchecked:
                check_check.setChecked(True)
                self.__checked_addons.add(addon)
            check_check.toggled.connect(partial(self.__check_checked, addon))
            check_check.setFocusPolicy(Qt.NoFocus)
            check_layout.addWidget(check_check)
            check_widget.setLayout(check_layout)
            self.setCellWidget(no, 0, check_widget)
            
            if addon.icon:
                icon_widget = QWidget()
                icon_layout = QVBoxLayout()
                icon_layout.setSpacing(0)
                icon_widget.setLayout(icon_layout)
                icon_label = QLabel()
                icon_label.setAutoFillBackground(False)
                icon_label.setPixmap(image_loader.load(addon.icon))
                icon_label.setAlignment(Qt.AlignTop)
                icon_layout.addWidget(icon_label)
                
                lp, tp, rp, bp = icon_layout.getContentsMargins()
                icon_layout.setContentsMargins(lp, tp, 0, bp)
                
                self.setCellWidget(no, 1, icon_widget)
            
            layout = QVBoxLayout()
            layout.setSpacing(0)
            layout.setAlignment(Qt.AlignTop)
            
            name_layout = QHBoxLayout()
            name_layout.setSpacing(20)
            name_layout.setAlignment(Qt.AlignLeft)
            
            name_label = QLabel(addon.name)
            name_label.setAutoFillBackground(False)
            name_label.setTextFormat(Qt.PlainText)
            font = name_label.font()
            font.setWeight(QFont.Bold)
            name_label.setFont(font)
            name_layout.addWidget(name_label)
            
            if isinstance(addon, OnlineAddOn):
                if self.__show_prev_version:
                    version = "{0} ⟶ {1}".format(addon.local_addon.version, addon.latest_version.version)
                else:
                    version = addon.latest_version.version
            else:
                version = addon.version
            
            version_label = QLabel(str(version))
            version_label.setAutoFillBackground(False)
            version_label.setTextFormat(Qt.PlainText)
            name_layout.addWidget(version_label)
            
            layout.addLayout(name_layout)
            
            if addon.description:
                description_label = QLabel(addon.description)
                description_label.setAutoFillBackground(False)
                description_label.setTextFormat(Qt.PlainText)
                description_label.setWordWrap(True)
                layout.addWidget(description_label)
            
            addon_button_box = QHBoxLayout()
            addon_button_box.setAlignment(Qt.AlignRight)
            
            addon_button_box_widget = QWidget()
            addon_button_box_widget.setLayout(addon_button_box)
            if self.EXPANDING_BUTTON_BOX:
                addon_button_box_widget.setVisible(False)
            addon_button_box_widget.setObjectName("button_box")
            
            if button_factory is not None:
                button_factory.add_buttons(addon, addon_button_box, addon_button_box_widget)
            
            if addon_button_box.count() > 0:
                layout.addWidget(addon_button_box_widget)
            
            widget = QWidget()
            widget.setLayout(layout)
            self.setCellWidget(no, 2, widget)

            self.__refresh_selection_colors(widget, False)
        
        self.resizeColumnsToContents()
        self.resizeRowsToContents()
        
        cur_checked = set(addon.identifier for addon in self.__checked_addons)
        
        if prev_checked != cur_checked:
            self.check_changed.emit()
Exemple #5
0
class AppCard(QFrame):
	"""A Card widget derived from QFrame contains app icon, 
	app name, app developer, app description, app rating, etc"""

	STYLES = STYLES
	Q_ENUM(STYLES)

	def __init__(self, parent=None):
		QFrame.__init__(self, parent)

		self.setFixedSize(200, 300)

		self.setObjectName("Card")
		
		self.setAutoFillBackground(True)

		self.appId = -1
		self.appIcon = "./img/card/bird.png"
		self.appBack = "./img/card/card_back.png"
		self.appName = "PROS Smart CPQ for Manufacturing"
		self.appDev = "By PROS\nWeb apps"
		self.appRating = 0
		self.appFeedback = 0
		self.appState = 0
		self.style_str = "border: 1px solid #ddd; background: qlineargradient(spread:pad, x1:0 y1:0, x2:1 y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(225, 225, 225, 225));"
		self.appDesc = "Deliver Sales Automation and Profits Through Personalized Selling"
		self.setBackgroundImage(self.appBack)

		self.iconSize = 48, 48
		self.iconMargins = 10, 10, 10, 10
		self.iconFrameStyle = STYLES.STYLE_DEFAULT

		self.iconFrame = QLabel(self)
		self.iconFrame.setAutoFillBackground(True)
		self.iconFrame.setObjectName("IconFrame")
		self.iconFrame.setStyleSheet(self.iconFrameStyle)

		self.imgIcon = QLabel(self.iconFrame)
		self.imgIcon.setPixmap(QPixmap(self.appIcon))
		self.imgIcon.setFixedSize(48, 48)
		self.imgIcon.setScaledContents(True)

		self.iconLayout = QHBoxLayout(self.iconFrame)
		self.iconLayout.setContentsMargins(10, 10, 10, 10)
		self.iconLayout.setAlignment(Qt.AlignLeft)
		self.iconLayout.addWidget(self.imgIcon, Qt.AlignLeft)
		self.iconFrame.setLayout(self.iconLayout)

		self.txtName = ElideLabel("", self)
		self.txtName.setText(self.appName)
		self.txtName.setFont(QFont("Roboto", 15))
		self.txtName.setElideMode(1)
		self.txtName.setWordWrap(True)

		self.txtDev = ElideLabel("", self)
		self.txtDev.setWordWrap(True)
		self.txtDev.setText(self.appDev)
		self.txtDev.setFont(QFont("Roboto", 8))

		self.txtDesc = ElideLabel("", self)
		self.txtDesc.setText(self.appDesc)
		self.txtDesc.setAlignment(Qt.AlignTop)
		self.txtDesc.setFont(QFont("Roboto", 10))
		self.txtDesc.setElideMode(1)
		self.txtDesc.setWordWrap(True)	

		self.starRating = StarRating(self)

		self.feedbackGiven = QLabel(self)
		self.feedbackGiven.setObjectName("Feedback")
		self.feedbackGiven.setStyleSheet("#Feedback{color: #ababab}")
		self.feedbackGiven.setFont(QFont("Roboto", 12))
		self.feedbackGiven.setAlignment(Qt.AlignVCenter)
		self.feedbackGiven.setText("(" + str(self.appFeedback) + ")")

		self.btnInstall = Button('Install', self)
		self.btnInstall.clicked.connect(self.onInstallClicked)

		self.btnLaunch = Button('Launch', self)
		self.btnLaunch.setButtonType(Button.BUTTON_TYPE.LAUNCH)
		self.btnLaunch.clicked.connect(self.onLaunchClicked)
		self.btnLaunch.hide()

		self.btnUninstall = Button('Uninstall', self)
		self.btnUninstall.setButtonType(Button.BUTTON_TYPE.DELETE)
		self.btnUninstall.clicked.connect(self.onUninstallClicked)
		self.btnUninstall.hide()

		self.shadowEffect = QGraphicsDropShadowEffect(self)
		self.shadowEffect.setBlurRadius(9)
		self.shadowEffect.setColor(QColor(225, 225, 225))
		self.shadowEffect.setOffset(5, 5)
		self.setGraphicsEffect(self.shadowEffect)

		self.frameLayout = QVBoxLayout(self)
		self.frameLayout.setContentsMargins(0, 0, 0, 0)

		self.mainLayout = QVBoxLayout()
		self.mainLayout.setSpacing(5)
		self.mainLayout.setContentsMargins(10, 0, 10, 15)

		self.ratingLayout = QHBoxLayout()
		self.ratingLayout.setSpacing(5)
		self.ratingLayout.addWidget(self.starRating, 1, Qt.AlignLeft)
		self.ratingLayout.addWidget(self.feedbackGiven, 1, Qt.AlignLeft)

		self.separator = QFrame(self)
		self.separator.setObjectName("line")
		self.separator.setFixedHeight(2)
		self.separator.setFixedWidth(self.width())
		self.separator.setFrameShape(QFrame.HLine)
		self.separator.setFrameShadow(QFrame.Sunken)

		self.btnLayout = QHBoxLayout()
		self.btnLayout.setContentsMargins(5, 5, 5, 10)
		self.btnLayout.setSpacing(20)
		self.btnLayout.setAlignment(Qt.AlignHCenter)
		self.btnLayout.addWidget(self.btnInstall)
		self.btnLayout.addWidget(self.btnUninstall)
		self.btnLayout.addWidget(self.btnLaunch)

		self.mainLayout.addWidget(self.txtName, 1, Qt.AlignLeft)
		self.mainLayout.addWidget(self.txtDev, 1, Qt.AlignLeft)
		self.mainLayout.addWidget(self.txtDesc, 3, Qt.AlignLeft)
		self.mainLayout.addLayout(self.ratingLayout, Qt.AlignLeft)

		self.frameLayout.addWidget(self.iconFrame, 1)
		self.frameLayout.addLayout(self.mainLayout)
		self.frameLayout.addWidget(self.separator)
		self.frameLayout.addLayout(self.btnLayout)

		self.setLayout(self.frameLayout)
		self.setAppState(self.appState)
		self.show()

	#automatically adjust child widgets' sizes based on the frame's geometry
	#this might affect widgets' sizes
	def autoAdjust(self):
		self.starRating.adjustWidthByHeight(self.height()/15)
		self.feedbackGiven.setFixedHeight(self.height()/16)
		self.iconFrame.setFixedHeight(self.height()/5)
		self.setIconSize(self.iconFrame.height() * 4 / 5, self.iconFrame.height() *4 / 5)
		mm = self.iconFrame.height() / (5 * 2)
		self.setIconMargins(mm, mm, mm, mm)

	#set fixed size for the icon, maybe called logo or brand
	def setIconSize(self, aw, ah):
		self.iconSize = aw, ah
		self.imgIcon.setFixedSize(self.iconSize[0], self.iconSize[1])

	#set icon margins within the icon frame
	def setIconMargins(self, ml, mt = 0, mr = 0, mb = 0):
		self.iconMargins = ml, mt, mr, mb
		mml, mmt, mmr, mmb = self.mainLayout.getContentsMargins()
		self.iconLayout.setContentsMargins(mml, mt, mmr, mb)
	#set icon frame's style, you can stylize background(single color, gradient or image), border, etc
	def setIconFrameStyle(self, style):
		self.iconFrameStyle = style
		self.iconFrame.setStyleSheet(self.iconFrameStyle)

	@pyqtSlot()
	def onInstallClicked(self):
		QMessageBox.information(None, "ID: " + str(self.appId), "Install button clicked")

	@pyqtSlot()
	def onUninstallClicked(self):
		QMessageBox.information(None, "ID: " + str(self.appId), "Gonna uninstall the app?")

	@pyqtSlot()
	def onLaunchClicked(self):
		QMessageBox.information(None, "ID: " + str(self.appId), "Launch is not ready yet!")

	#set whether the app is already installed or not, accordingly show or hide appropriate buttons
	def setAppState(self, state):
		if state == 0:
			self.btnInstall.show()
			self.btnUninstall.hide()
			self.btnLaunch.hide()
		elif state == 1:
			self.btnInstall.hide()
			self.btnUninstall.show()
			self.btnLaunch.show()
		self.autoAdjust()

	#return current app state
	def getAppState(self):
		return self.appState

	#set applicaton name
	def setAppName(self, name):
		if name != self.appName:
			self.appName = name
			self.txtName.setText(self.appName)
	#return application name
	def getAppName(self):
		return self.appName

	#set developer name, or could be company name
	def setAppDevName(self, name):
		if name != self.appDev:
			self.appDev = name
			self.txtDev.setText(self.appDev)

	#return developer name
	def getAppDevName(self):
		return self.appDev

	#set description about application
	def setAppDesc(self, desc):
		if desc != self.appDesc:
			self.appDesc = desc
			self.txtDesc.setText(self.appDesc)

	#return description of application
	def getAppDesc(self):
		return self.appDesc

	#set application icon with appropriate file path
	def setAppIcon(self, imgPath):
		if imgPath != self.appIcon:
			self.appIcon = imgPath
			self.imgIcon.setPixmap(QPixmap(self.appIcon))

	#return QPixmap of icon
	def getAppIconPixmap(self):
		return QPixmap(self.appIcon)

	#return path to icon
	def getAppIconPath(self):
		return self.appIcon

	#set applicaiton star rating and count of given feedbacks
	def setAppRating(self, rating, feedback):
		if rating != self.appRating or feedback != self.appFeedback:
			self.appRating, self.appFeedback = rating, feedback
			self.starRating.setRating(rating)
			self.feedbackGiven.setText("(" + str(feedback) + ")")

	#return star rating value and the count of given feedbacks
	def getAppRating(self):
		return (self.appRating, self.appFeedback)

	#set path to background would be embedded into stylesheet string
	def setBackgroundImage(self, img):
		self.appBack = img
		self.setStyleSheet("#Card{" + self.style_str + " background-image: url(" + self.appBack + ")}")

	#set application ID
	def setAppId(self, id):
		self.appId = id

	#return app ID
	def getAppId(self):
		return self.appId

	#set blur radius of frame's shadow effect
	def setShadowBlurRadius(self, radius):
		self.shadowEffect.setBlurRadius(radius)

	#set shadow offset of frame's shadow effect
	def setShadowOffset(self, offX, offY):
		self.shadowEffect.setOffset(offX, offY)

	#set shadow color of frame's shadow effect
	def setShadowColor(self, color):
		self.shadowEffect.setColor(color)

	#set font of application name
	def setAppNameFont(self, font):
		self.txtName.setFont(font)

	#set font of developer name
	def setAppDevFont(self, font):
		self.txtDev.setFont(font)

	#set font of description to the app
	def setAppDescFont(self, font):
		self.txtDesc.setFont(font);
Exemple #6
0
class BaseActivity(QDialog, BaseView):
    '''
    自定义标题栏
    '''
    bar: TitleBar = None
    '''
    窗口拖动位置
    '''
    _right_rect = []
    _bottom_rect = []
    _corner_rect = []
    _drag_ignore_fixed = False  # 拖动无视尺寸固定
    '''
    扳机默认值
    '''
    _move_drag = False
    _corner_drag = False
    _bottom_drag = False
    _right_drag = False
    '''
    拖拽位置记录
    '''
    _move_drag_position = None

    def __init__(self, flags=None, *args, **kwargs):
        super().__init__(flags, *args, **kwargs)

        self._configure()

    def _configure(self):
        # 边距
        self.margin = 0
        # 日志对象
        self.logger = logger
        self.logger_err = logger_err
        # 顶级窗口无边框
        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint
                            | Qt.WindowSystemMenuHint
                            | Qt.WindowMinimizeButtonHint
                            | Qt.WindowMaximizeButtonHint)
        # 窗口尺寸控制
        self.minHeight = 768
        self.minWidth = 1024
        self.resize(self.minWidth, self.minHeight)
        # 背景透明
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        # 框架布局
        self._main_layout = QVBoxLayout()
        self._main_layout.setSpacing(0)
        # 如果设置零边距,在窗口状态变更时(如最大化),边角会出现空白区域
        self._main_layout.setContentsMargins(self.margin, self.margin,
                                             self.margin, self.margin)
        self.setLayout(self._main_layout)

    def addLayout(self, layout):
        '''
        往主布局中添加子布局
        '''
        self._main_layout.addLayout(layout)

    def alert(info):
        '''
        提示弹出框
        '''
        pass

    def isResizable(self):
        """是否可调整
        """
        return self.minimumSize() != self.maximumSize()

    def resizeEvent(self, _event):
        '''
        自定义窗口调整大小事件
        采用三个列表生成式生成三个列表, 用以保存一个鼠标可以拖动的范围
        '''
        if not self.bar:
            return
        # 右侧边界
        self._right_rect = [
            QPoint(x, y)
            for x in range(self.width() - self.config.window_zoom_critical,
                           self.width() + 1)
            for y in range(self.bar.height(),
                           self.height() + self.config.window_zoom_critical)
        ]
        # 下边界
        self._bottom_rect = [
            QPoint(x, y)
            for x in range(1,
                           self.width() + self.config.window_zoom_critical)
            for y in range(self.height() - self.config.window_zoom_critical,
                           self.height() + 1)
        ]
        # 右下边界
        self._corner_rect = [
            QPoint(x, y)
            for x in range(self.width() - self.config.window_zoom_critical,
                           self.width() + 1)
            for y in range(self.height() - self.config.window_zoom_critical,
                           self.height() + 1)
        ]
        '''
        重新调整边界范围以备实现鼠标拖拽缩放窗口大小, 采用三个列表生成式生成三个列表
        '''
        # self._right_rect = [QPoint(x, y) for x in range(self.width() - self.config.window_zoom_critical, self.width() + 1)
        #                     for y in range(5, self.height() - self.config.window_zoom_critical)]
        # self._bottom_rect = [QPoint(x, y) for x in range(5, self.width() - self.config.window_zoom_critical)
        #                      for y in range(self.height() - self.config.window_zoom_critical, self.height() + 1)]
        # self._corner_rect = [QPoint(x, y) for x in range(self.width() - self.config.window_zoom_critical, self.width() + 1)
        #                      for y in range(self.height() - self.config.window_zoom_critical, self.height() + 1)]

    def mousePressEvent(self, event):
        '''
        重构鼠标点击事件
        '''
        if not self.bar:
            return
        if (event.button() == Qt.LeftButton) and (event.pos()
                                                  in self._corner_rect):
            self._corner_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._right_rect):
            self._right_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._bottom_rect):
            self._bottom_drag = True
            event.accept()
        elif (event.button()
              == Qt.LeftButton) and (event.y() <= self.bar.height()):
            self._move_drag = True
            self._move_drag_position = event.globalPos() - self.pos()
            event.accept()
        '''
        重写鼠标点击的事件
        '''
        # if (event.button() == Qt.LeftButton) and (event.pos() in self._corner_rect):
        #     self._corner_drag = True
        #     event.accept()
        # elif (event.button() == Qt.LeftButton) and (event.pos() in self._right_rect):
        #     self._right_drag = True
        #     event.accept()
        # elif (event.button() == Qt.LeftButton) and (event.pos() in self._bottom_rect):
        #     self._bottom_drag = True
        #     event.accept()
        # elif (event.button() == Qt.LeftButton) and (event.y() < 40):
        #     self._move_drag = True
        #     self._move_drag_position = event.globalPos() - self.pos()
        #     event.accept()

    def mouseMoveEvent(self, _):
        '''
        判断鼠标位置是否移动到了边界以便更换鼠标样式
        '''
        if self._drag_ignore_fixed:
            if self.isFullScreen():
                # 非全屏均可移动
                return
        elif self.isMaximized() or self.isFullScreen(
        ) or not self.isResizable():
            # 最大化时不可移动
            return
        if _.pos() in self._corner_rect:
            self.setCursor(Qt.SizeFDiagCursor)
        elif _.pos() in self._bottom_rect:
            self.setCursor(Qt.SizeVerCursor)
        elif _.pos() in self._right_rect:
            self.setCursor(Qt.SizeHorCursor)
        else:
            self.setCursor(Qt.ArrowCursor)

        if Qt.LeftButton and self._right_drag:
            self.resize(_.pos().x(), self.height())
            _.accept()
        elif Qt.LeftButton and self._bottom_drag:
            self.resize(self.width(), _.pos().y())
            _.accept()
        elif Qt.LeftButton and self._corner_drag:
            self.resize(_.pos().x(), _.pos().y())
            _.accept()
        elif Qt.LeftButton and self._move_drag:
            self.move(_.globalPos() - self._move_drag_position)
            _.accept()

    def mouseReleaseEvent(self, _):
        '''
        鼠标释放后,各扳机复位
        '''
        self._move_drag = False
        self._corner_drag = False
        self._bottom_drag = False
        self._right_drag = False

    def dragEnterEvent(self, event):
        '''
        判断拖拽物体是否有路径,如果有则拖拽生效
        '''
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        '''
        拖拽移动
        '''
        if event.mimeData().hasUrls:
            try:
                event.setDropAction(Qt.CopyAction)
            except Exception as e:
                pass
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        '''
        如果需要监听文件拖拽则重构此方法
        获取拖拽文件
        '''
        try:
            if event.mimeData().hasUrls:
                event.setDropAction(Qt.CopyAction)
                event.accept()
                links = []
                for url in event.mimeData().urls():
                    links.append(str(url.toLocalFile()))
                print(links)
            else:
                event.ignore()
        except Exception as e:
            raise e

    def mouseDoubleClickEvent(self, e: QMouseEvent):
        '''
        双击的坐标小于头部坐标时才最大化, 如果不需要这个功能,在继承子类时重构此方法即可
        '''
        if not self.bar:
            return
        if e.pos().y() < self.bar.y() + self.bar.height():
            self.bar.on_window_change()

    def keyPressEvent(self, a0: QKeyEvent):
        '''
        键盘监听事件
        '''
        if a0.key() == Qt.Key_Escape:
            a0.ignore()
        else:
            a0.accept()

    def eventFilter(self, target, event):
        if self.bar and isinstance(event, QWindowStateChangeEvent):
            if self.isVisible() and not self.isMinimized() and bool(
                    self.windowFlags() & Qt.WindowMinMaxButtonsHint):
                # 如果当前是最大化则隐藏最大化按钮
                maximized = self.isMaximized()
                self.bar.showMaximizeButton(not maximized)
                self.bar.showNormalButton(maximized)
                # 修复最大化边距空白问题
                if maximized:
                    self._oldMargins = self._main_layout.getContentsMargins()
                    self._main_layout.setContentsMargins(0, 0, 0, 0)
                else:
                    if hasattr(self, '_oldMargins'):
                        self._main_layout.setContentsMargins(*self._oldMargins)
        return super(BaseActivity, self).eventFilter(target, event)

    def paintEvent(self, event):
        '''
        由于是全透明背景窗口,重绘事件中绘制透明度为1的难以发现的边框,用于调整窗口大小
        '''
        painter = QPainter(self)
        painter.setPen(QPen(QColor(255, 255, 255, 1), 2 * self.margin))
        painter.drawRect(self.rect())