Beispiel #1
0
class HLabels(QHBoxLayout):
    labelSheet = """QLabel {
                        font-size: 12pt;
                        font-weight: bold;
                        padding-right: 5px;
                        color: #9eeeee;}"""

    valSheet = """QLabel {
                        font-size: 12pt;
                        font-weight: bold;
                        color: #eece9e;}"""

    def __init__(self, label1=None, label2=None):
        super().__init__()
        self.label = QLabel(label1)
        self.label.setStyleSheet(self.labelSheet)
        self.value = QLabel(label2)
        self.value.setStyleSheet(self.valSheet)
        self.addWidget(self.label)
        self.addWidget(self.value)
        self.label.setAlignment(Qt.AlignmentFlag.AlignRight)
        self.value.setAlignment(Qt.AlignmentFlag.AlignLeft)

    def update_value(self, text):
        self.value.setText(str(text))

    def update_percent(self, var):
        text = str(round(var * 100, 4))
        self.value.setText(text + "%")
Beispiel #2
0
 def show_setting(self, conf: dict, layout: QGridLayout):
     groups = list()
     x = 0
     y = 0
     shape = 3
     for key in conf.keys():
         if type(conf[key]) == bool or type(conf[key]) == str:
             continue
         conf_title = conf[key]["title"]
         conf_enabled = conf[key]["enabled"]
         conf_times = conf[key]["times"]
         group = QGroupBox(conf_title)
         group.setStyleSheet("QGroupBox{border-radius:5px;}")
         group.setToolTip(conf_title + "  的设置")
         enabled = QCheckBox("启用")
         enabled.setObjectName(key)
         enabled.setToolTip("单击切换开关状态")
         enabled.setChecked(conf_enabled)
         enabled.setStyleSheet(
             "QCheckBox::indicator{width:10px;height:10px;border:none;border-radius:5px;background:#9BE3DE;}QCheckBox::indicator:unchecked{background:#BEEBE9;}QCheckBox::indicator:unchecked:hover{background:#9AD3BC;}QCheckBox::indicator:checked{background:#95E1D3;}QCheckBox::indicator:checked:hover{background:#98DED9;}"
         )
         times = QHBoxLayout()
         times_label = QLabel("次数:")
         times_label.setStyleSheet(
             "QLabel{background:transparent;border:none;border-radius:5px;}"
         )
         times_input = EnhancedEdit()
         times_input.setObjectName(key)
         times_input.setText(str(conf_times))
         times_input.setToolTip("仅限正整数")
         times_input.setValidator(
             QRegularExpressionValidator(
                 QRegularExpression("^[1-9][0-9]{1,8}$")))
         times_input.setStyleSheet(
             "QLineEdit{border:1px solid #F3EAC2;border-radius:5px;background:transparent;}QLineEdit:hover{border:1px solid #F5B461;}"
         )
         times.addWidget(times_label)
         times.addWidget(times_input)
         group_layout = QVBoxLayout()
         group_layout.addWidget(enabled)
         group_layout.addLayout(times)
         group.setLayout(group_layout)
         group.setObjectName(key)
         groups.append(group)
     for group in groups:
         if y >= shape:
             x = x + 1
             y = 0
         layout.addWidget(group, x, y)
         y = y + 1
     self.logger.debug("最后的元素位置:(%d,%d)" % (x, y))
     return (x, y)
class FileHashCheckerApp(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("File Hash Checker")
        self.setGeometry(0, 0, 600, 300)

        self.labelFileDropper = FileDropper("Datei auswählen")
        #self.selectFileButton.clicked.connect(self.get_file_to_check)
        self.labelFileDropper.setAcceptDrops(True)
        self.labelFileDropper.setStyleSheet(
            "border: 1px solid black; border-radius: 15px; text-align: center; "
            "height: 200px")
        self.labelFileDropper.move(0, 0)
        self.labelFileDropper.resize(500, 150)

        self.labelMD5Hash = QLabel(
            "Bitte zu vergleichenden MD5 Hash eingeben:")

        self.textMD5Hash = QLineEdit()

        self.buttonCompareMD5 = QPushButton('MD5 Vergleichen')
        self.buttonCompareMD5.clicked.connect(self.compare_md5)

        self.labelIsSame = QLabel()

        layout = QVBoxLayout()
        layout.addWidget(self.labelFileDropper)
        layout.addWidget(self.labelMD5Hash)
        layout.addWidget(self.textMD5Hash)
        layout.addWidget(self.buttonCompareMD5)
        layout.addWidget(self.labelIsSame)

        self.setLayout(layout)

    def get_file_to_check(self):
        file_name, _ = QFileDialog.getOpenFileName(self, 'Datei auswählen')
        self.labelFilePath.setText(file_name)

    def compare_md5(self):
        given_hash = self.textMD5Hash.text()
        generated_hash = md5(self.selectFileButton.text())

        if given_hash.upper() == generated_hash.upper():
            self.labelIsSame.setText('True')
            self.labelIsSame.setStyleSheet("background-color: green")
        else:
            self.labelIsSame.setText('False: ' + generated_hash.upper())
            self.labelIsSame.setStyleSheet("background-color: red")
Beispiel #4
0
class StatsFrame(QWidget):
    """Calculate statistics for each turn of the players."""

    label_ssheet = """QLabel {
                    font-size: 15pt;
                    font-weight: bold;
                    padding-right: 5px;
                    color: #fca018;}"""

    def __init__(self, parent=None, window=None):
        super().__init__(parent=parent)
        self.window = window
        self.hlayout = QHBoxLayout()
        self.setLayout(self.hlayout)
        self.vbox1 = QVBoxLayout()
        self.vbox2 = QVBoxLayout()
        self.cardCount = HLabels("Cards in Deck: ", "0")
        self.deckCount = HLabels("Number of Decks: ", "0")
        self.playerCount = HLabels("Number of Players: ", "0")
        self.breaking21 = HLabels("Breaking 21: ", " 0")
        self.exactly = HLabels("Exactly 21: ", " 0")
        self.under21 = HLabels("Under 21: ", " 0")
        self.probabilities = QLabel("Probabilities", parent=self)
        self.quantities = QLabel("Quantities", parent=self)
        self.vbox2.addWidget(self.quantities)
        self.vbox2.addLayout(self.cardCount)
        self.vbox2.addLayout(self.deckCount)
        self.vbox2.addLayout(self.playerCount)
        self.vbox1.addWidget(self.probabilities)
        self.vbox1.addLayout(self.breaking21)
        self.vbox1.addLayout(self.exactly)
        self.vbox1.addLayout(self.under21)
        self.hlayout.addLayout(self.vbox1)
        self.hlayout.addLayout(self.vbox2)
        self.quantities.setStyleSheet(self.label_ssheet)
        self.probabilities.setStyleSheet(self.label_ssheet)
        self.probabilities.setAlignment(Qt.AlignmentFlag(4))
        self.quantities.setAlignment(Qt.AlignmentFlag(4))
        self.labels = {
            "cards": self.cardCount,
            "decks": self.deckCount,
            "players": self.playerCount,
            "breaking": self.breaking21,
            "exactly": self.exactly,
            "under": self.under21,
        }
        self.window.driver.hook(self.labels)
    def InitWindow(self):
        self.setWindowIcon(QtGui.QIcon(self.iconName))
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        vbox = QVBoxLayout()
        label = QLabel("This is PyQt6 Label")
        vbox.addWidget(label)

        label2 = QLabel("This is PyQt6 GUI Application Development")
        label2.setFont(QtGui.QFont("Sanserif ", 20))
        label2.setStyleSheet('color:red')
        vbox.addWidget(label2)

        self.setLayout(vbox)

        self.show()
Beispiel #6
0
def makeTitle():
    titleLayout = QHBoxLayout()
    # titleLayout.setSpacing(42)
    titleFont = QtGui.QFont("Times", 32, QtGui.QFont.Weight.Bold)

    title = QLabel(opts.timeclockOpts["title"])
    title.setFixedWidth(820)
    title.setFont(titleFont)

    logo = QLabel()
    logoImage = QtGui.QPixmap("../data/assets/" + opts.timeclockOpts["logo"])
    logoImage = logoImage.scaled(QtCore.QSize(100, 100))
    logo.setPixmap(logoImage)
    if opts.timeclockOpts["darkTheme"]:
        logo.setStyleSheet("QLabel {background:white}")

    titleLayout.addWidget(title)
    titleLayout.addStretch()
    titleLayout.addWidget(logo)
    return titleLayout
Beispiel #7
0
 def show_qr(self, qr: bytes):
     title_label = QLabel("请使用微信扫描小程序码完成登陆")
     title_label.setStyleSheet(
         "QLabel{color:#ffe3ed;border:none;background-color:transparent;border-radius:5px;}"
     )
     title_label.setAlignment(Qt.Alignment.AlignCenter)
     title_label.setFixedHeight(20)
     qr_label = QLabel()
     pixmap = QPixmap()
     pixmap.loadFromData(qr)
     qr_label.setPixmap(pixmap)
     qr_label.setStyleSheet(
         "QLabel{color:#ffe3ed;border:none;background-color:transparent;border-radius:5px;}"
     )
     layout_ = QVBoxLayout()
     layout_.addWidget(title_label, 1)
     layout_.addWidget(qr_label, 9)
     self.qr_dialog = QWidget(self)
     self.qr_dialog.setLayout(layout_)
     self.main_layout.addWidget(self.qr_dialog, 1, 1,
                                Qt.Alignment.AlignCenter)
     self.qr_dialog.show()
Beispiel #8
0
    def displayTag(self, tagName):
        tagWidget = QWidget()
        tagWidget.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
        tagWidget.enterEvent = lambda e: self.setCursor(
            QCursor(Qt.CursorShape.PointingHandCursor))
        tagWidget.leaveEvent = lambda e: self.setCursor(
            QCursor(Qt.CursorShape.ArrowCursor))
        tagWidget.mouseReleaseEvent = lambda e: self.removeTag(
            self.flowLayout.indexOf(tagWidget), returnTag=False)
        self.renderStyleSheet(tagWidget)

        hBoxTag = QHBoxLayout()

        tagLabel = QLabel()
        tagLabel.setText(tagName)
        tagLabel.setStyleSheet(f'''
            QLabel {{
                background-color: transparent;
                border: none;
            }}
        ''')
        hBoxTag.addWidget(tagLabel)

        crossIcon = QPixmap('MangoUI/TagBox/img/crossresized.png')
        crossIconLabel = QLabel()
        crossIconLabel.setPixmap(crossIcon)
        crossIconLabel.setStyleSheet(f'''
            QLabel {{
                background-color: transparent;
                border: none;
            }}
        ''')
        hBoxTag.addWidget(crossIconLabel)

        hBoxTag.setContentsMargins(10, 6, 6, 6)
        tagWidget.setLayout(hBoxTag)
        self.flowLayout.addWidget(tagWidget)
Beispiel #9
0
class FixedSlider(QSlider):
    def __init__(self):
        super(FixedSlider,self).__init__()
        self.setTickInterval(1)
        self.value_label=QLabel(self)    
        self.value_label.setFixedSize(40,20) 
        self.value_label.setAutoFillBackground(True)
        self.value_label.setStyleSheet("QLabel{background:transparent;font:8px}")
        self.value_label.setAlignment(Qt.Alignment.AlignCenter)
        self.value_label.setVisible(False)
        self.value_label.move(0,-5)
    def mousePressEvent(self,event:QMouseEvent):
        super(FixedSlider,self).mousePressEvent(event)
        if self.value_label.isVisible()==False:
            self.value_label.setVisible(True)
            self.value_label.setText(str(self.value()/10))
    def mouseMoveEvent(self,event:QMouseEvent):
        super(FixedSlider,self).mouseMoveEvent(event)
        self.value_label.setText(str(self.value()/10))
        self.value_label.move(int((self.width()-self.value_label.width())*self.value()/(self.maximum()-self.minimum())),-5)
    def mouseReleaseEvent(self,event:QMouseEvent):
        super(FixedSlider,self).mouseReleaseEvent(event)
        if self.value_label.isVisible()==True:
            self.value_label.setVisible(False)
Beispiel #10
0
class UI(QWidget):
    update_signal = pyqtSignal(str)
    show_qr_signal = pyqtSignal(bytes)
    finish_signal = pyqtSignal()
    close_qr_signal = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.logger = logging.getLogger(__name__)
        formatter = logging.Formatter(
            fmt="%(asctime)s-%(levelname)s-%(message)s",
            datefmt="%Y-%m-%d %H:%M:%S")
        filehandler = logging.FileHandler(filename="logs.log",
                                          mode="w",
                                          encoding="utf-8")
        handler = QLogger(update_signal=self.update_signal)
        handler.setLevel(logging.INFO)
        filehandler.setLevel(logging.INFO)
        self.logger.setLevel(logging.INFO)
        if os.path.exists("config.json") == False:
            self.gen_conf()
        with open(file="config.json", mode="r",
                  encoding="utf-8") as conf_reader:
            conf = json.loads(conf_reader.read())
        debug = bool(conf["debug"])
        if debug == True:
            handler.setLevel(logging.DEBUG)
            filehandler.setLevel(logging.DEBUG)
            self.logger.setLevel(logging.DEBUG)
        handler.setFormatter(formatter)
        filehandler.setFormatter(formatter)
        self.logger.addHandler(handler)
        self.logger.addHandler(filehandler)
        self.logger.debug("当前调试状态:%s" % debug)
        self.resize(1024, 768)
        self.setWindowOpacity(0.9)
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
        self.setWindowFlag(Qt.WindowFlags.FramelessWindowHint)
        self.setAutoFillBackground(True)
        self.work = Work(show_qr_signal=self.show_qr_signal,
                         finish_signal=self.finish_signal,
                         close_qr_signal=self.close_qr_signal)
        self.work_thread = QThread()
        self.work.moveToThread(self.work_thread)
        self.main_layout = QGridLayout()
        self.setLayout(self.main_layout)
        self.title = QLabel("ChinaUniOnlineGUI")
        self.title.setStyleSheet(
            "QLabel{border:none;border-radius:5px;background:transparent;color:#9AD3BC;font-size:60px;}"
        )
        self.title.setAlignment(Qt.Alignment.AlignCenter)
        handler.widget.setStyleSheet(
            "QPlainTextEdit{font-family:Microsoft YaHei;background:#F3EAC2;border:none;border-radius:5px;}QScrollBar:vertical,QScrollBar::handle:vertical{background:#F3EAC2;border:none;border-radius:8px;width:16px;}QScrollBar::handle:vertical:hover{background:#F5B461;}QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical{background:#FFFDF9;border:none;border-radius:8px;width:16px;}QScrollBar::down-arrow:vertical,QScrollBar::up-arrow:vertical{background:#F5B461;border:none;border-radius:8px;width:16px;height:16px;}QScrollBar::sub-line:vertical,QScrollBar::add-line:vertical{background:transparent;border:none;}"
        )
        self.control = QVBoxLayout()
        self.control_close = QPushButton()
        self.control_close.setToolTip("关闭")
        self.control_close.setStyleSheet(
            "QPushButton{background:#FFE3ED;border-radius:5px;border:none;}QPushButton:hover{background:#EC524B;}"
        )
        self.contron_max = QPushButton()
        if self.isMaximized() == False:
            self.contron_max.setToolTip("最大化")
        else:
            self.contron_max.setToolTip("还原")
        self.contron_max.setStyleSheet(
            "QPushButton{background:#FFFDF9;border-radius:5px;border:none;}QPushButton:hover{background:#F5B461;}"
        )
        self.control_min = QPushButton()
        self.control_min.setToolTip("最小化")
        self.control_min.setStyleSheet(
            "QPushButton{background:#BEEBE9;border-radius:5px;border:none;}QPushButton:hover{background:#F3EAC2;}"
        )
        self.start_button = QPushButton("开始(&S)")
        self.start_button.setStyleSheet(
            "QPushButton{background:#9BE3DE;border:none;border-radius:5px;font-size:20px;font-family:DengXian;}QPushButton:hover{background:#9AD3BC;}"
        )
        self.start_button.setToolTip("开始")
        self.start_button.setFixedSize(120, 60)
        self.start_button.setDefault(True)
        setting_button = QPushButton("设置")
        setting_button.setToolTip("设置")
        setting_button.setFixedSize(60, 60)
        setting_button.setStyleSheet(
            "QPushButton{background:#9BE3DE;border:none;border-radius:5px;font-size:20px;font-family:DengXian;}QPushButton:hover{background:#9AD3BC;}"
        )
        setting_button.clicked.connect(self.setting_callback)
        start = QHBoxLayout()
        start.addWidget(self.start_button, 2)
        start.addWidget(setting_button, 1)
        self.control_close.clicked.connect(self.close)
        self.control_min.clicked.connect(self.min_callback)
        self.contron_max.clicked.connect(self.max_callback)
        self.start_button.clicked.connect(self.start_callback)
        self.work_thread.started.connect(self.work.start)
        self.finish_signal.connect(self.finish_callback)
        self.close_qr_signal.connect(self.close_qr)
        self.control.addWidget(self.control_min)
        self.control.addWidget(self.contron_max)
        self.control.addWidget(self.control_close)
        self.main_layout.addLayout(self.control, 0, 0)
        self.main_layout.addWidget(self.title, 0, 1)
        self.main_layout.addLayout(start, 0, 2)
        self.main_layout.addWidget(handler.widget, 1, 1)
        self.update_signal.connect(handler.widget.appendPlainText)
        handler.widget.textChanged.connect(handler.scroll_widget_to_bottom)
        self.show_qr_signal.connect(self.show_qr)
        self.logger.debug("已初始化UI")

    def min_callback(self):
        if self.isMinimized() == False:
            self.showMinimized()

    def max_callback(self):
        if self.isMaximized() == False:
            self.showMaximized()
            self.contron_max.setToolTip("还原")
        else:
            self.showNormal()
            self.contron_max.setToolTip("最大化")

    def start_callback(self):
        self.start_time = time.time()
        self.work_thread.start()
        self.start_button.setEnabled(False)
        self.start_button.setText("执行中...")

    def finish_callback(self):
        self.start_button.setEnabled(True)
        self.start_button.setText("开始")
        passed_time = time.time() - self.start_time
        mins, secs = divmod(passed_time, 60)
        hours, mins = divmod(mins, 60)
        self.logger.info("执行完成,共计用时 {:0>2d}:{:0>2d}:{:0>2d}".format(
            int(hours), int(mins), int(secs)))

    def show_qr(self, qr: bytes):
        title_label = QLabel("请使用微信扫描小程序码完成登陆")
        title_label.setStyleSheet(
            "QLabel{color:#ffe3ed;border:none;background-color:transparent;border-radius:5px;}"
        )
        title_label.setAlignment(Qt.Alignment.AlignCenter)
        title_label.setFixedHeight(20)
        qr_label = QLabel()
        pixmap = QPixmap()
        pixmap.loadFromData(qr)
        qr_label.setPixmap(pixmap)
        qr_label.setStyleSheet(
            "QLabel{color:#ffe3ed;border:none;background-color:transparent;border-radius:5px;}"
        )
        layout_ = QVBoxLayout()
        layout_.addWidget(title_label, 1)
        layout_.addWidget(qr_label, 9)
        self.qr_dialog = QWidget(self)
        self.qr_dialog.setLayout(layout_)
        self.main_layout.addWidget(self.qr_dialog, 1, 1,
                                   Qt.Alignment.AlignCenter)
        self.qr_dialog.show()

    def close_qr(self):
        self.qr_dialog.close()

    def setting_callback(self):
        setting = SettingWindow(parent=self)
        setting.setStyleSheet(
            "QDialog{border:none;border-radius:5px;background:#F3EAC2;}")
        setting.show()

    def gen_conf(self):
        default_conf = {
            "debug": False,
            "hero": {
                "title": "英雄篇",
                "enabled": True,
                "times": 1
            },
            "revival": {
                "title": "复兴篇",
                "enabled": True,
                "times": 1
            },
            "creation": {
                "title": "创新篇",
                "enabled": True,
                "times": 1
            },
            "belief": {
                "title": "信念篇",
                "enabled": True,
                "times": 1
            },
            "limit_time": {
                "title": "限时赛",
                "enabled": True,
                "times": 1
            },
            "rob": {
                "title": "抢十赛",
                "enabled": True,
                "times": 1
            }
        }
        with open(file="config.json", mode="w",
                  encoding="utf-8") as conf_writer:
            conf_writer.write(
                json.dumps(default_conf,
                           indent=4,
                           sort_keys=True,
                           ensure_ascii=False))
        self.logger.info("已生成默认配置文件")

    def mousePressEvent(self, event: QMouseEvent):
        self.logger.debug("触发鼠标按压事件")
        super().mousePressEvent(event)
        self.setFocus()
        self.m_flag = True
        if event.button() == Qt.MouseButtons.LeftButton and self.isMaximized(
        ) == False and self.hasFocus() == True:
            self.old_pos = event.globalPosition()  #获取鼠标相对窗口的位置
            self.logger.debug("已获取鼠标位置")
            self.setCursor(QtGui.QCursor(
                Qt.CursorShape.SizeAllCursor))  #更改鼠标图标

    def mouseMoveEvent(self, event: QMouseEvent):
        self.logger.debug("触发鼠标移动事件")
        super().mouseMoveEvent(event)
        if self.m_flag == True:
            delta_x = int(event.globalPosition().x() - self.old_pos.x())
            delta_y = int(event.globalPosition().y() - self.old_pos.y())
            self.move(self.x() + delta_x, self.y() + delta_y)  #更改窗口位置
            self.logger.debug("已更改窗口位置")
            self.old_pos = event.globalPosition()

    def mouseReleaseEvent(self, event: QMouseEvent):
        self.logger.debug("触发鼠标释放事件")
        super().mouseReleaseEvent(event)
        self.m_flag = False
        self.setCursor(QtGui.QCursor(Qt.CursorShape.ArrowCursor))
Beispiel #11
0
    def initUI(self):
        self.setWindowTitle("登录蓝奏云")
        self.setWindowIcon(QIcon(SRC_DIR + "login.ico"))
        logo = QLabel()
        logo.setPixmap(QPixmap(SRC_DIR + "logo3.gif"))
        logo.setStyleSheet("background-color:rgb(0,153,255);")
        logo.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.tabs = QTabWidget()
        self.auto_tab = QWidget()
        self.hand_tab = QWidget()

        # Add tabs
        self.tabs.addTab(self.auto_tab,"自动获取Cookie")
        self.tabs.addTab(self.hand_tab,"手动输入Cookie")
        self.auto_get_cookie_ok = AutoResizingTextEdit("🔶点击👇自动获取浏览器登录信息👇")
        self.auto_get_cookie_ok.setReadOnly(True)
        self.auto_get_cookie_btn = QPushButton("自动读取浏览器登录信息")
        auto_cookie_notice = '支持浏览器:Chrome, Chromium, Opera, Edge, Firefox'
        self.auto_get_cookie_btn.setToolTip(auto_cookie_notice)
        self.auto_get_cookie_btn.clicked.connect(self.call_auto_get_cookie)
        self.auto_get_cookie_btn.setStyleSheet("QPushButton {min-width: 210px;max-width: 210px;}")

        self.name_lb = QLabel("&U 用户")
        self.name_lb.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.name_ed = QLineEdit()
        self.name_lb.setBuddy(self.name_ed)

        self.pwd_lb = QLabel("&P 密码")
        self.pwd_lb.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.pwd_ed = QLineEdit()
        self.pwd_ed.setEchoMode(QLineEdit.EchoMode.Password)
        self.pwd_lb.setBuddy(self.pwd_ed)

        self.cookie_lb = QLabel("&Cookie")
        self.cookie_ed = QTextEdit()
        notice = "由于滑动验证的存在,需要输入cookie,cookie请使用浏览器获取\n" + \
            "cookie会保存在本地,下次使用。其格式如下:\n ylogin=value1; phpdisk_info=value2"
        self.cookie_ed.setPlaceholderText(notice)
        self.cookie_lb.setBuddy(self.cookie_ed)

        self.show_input_cookie_btn = QPushButton("显示Cookie输入框")
        self.show_input_cookie_btn.setToolTip(notice)
        self.show_input_cookie_btn.setStyleSheet("QPushButton {min-width: 110px;max-width: 110px;}")
        self.show_input_cookie_btn.clicked.connect(self.change_show_input_cookie)
        self.ok_btn = QPushButton("登录")
        self.ok_btn.clicked.connect(self.change_ok_btn)
        self.cancel_btn = QPushButton("取消")
        self.cancel_btn.clicked.connect(self.change_cancel_btn)
        lb_line_1 = QLabel()
        lb_line_1.setText('<html><hr />切换用户</html>')
        lb_line_2 = QLabel()
        lb_line_2.setText('<html><hr /></html>')

        self.form = QFormLayout()
        self.form.setLabelAlignment(Qt.AlignmentFlag.AlignRight)
        self.form.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)  # 覆盖MacOS的默认样式
        self.form.addRow(self.name_lb, self.name_ed)
        self.form.addRow(self.pwd_lb, self.pwd_ed)
        if is_windows:
            def set_assister_path():
                """设置辅助登录程序路径"""
                assister_path = QFileDialog.getOpenFileName(self, "选择辅助登录程序路径",
                                                            self._cwd, "EXE Files (*.exe)")
                if not assister_path[0]:
                    return None
                assister_path = os.path.normpath(assister_path[0])  # windows backslash
                if assister_path == self._cookie_assister:
                    return None
                self.assister_ed.setText(assister_path)
                self._cookie_assister = assister_path

            self.assister_lb = QLabel("登录辅助程序")
            self.assister_lb.setAlignment(Qt.AlignmentFlag.AlignCenter)
            self.assister_ed = MyLineEdit(self)
            self.assister_ed.setText(self._cookie_assister)
            self.assister_ed.clicked.connect(set_assister_path)
            self.assister_lb.setBuddy(self.assister_ed)
            self.form.addRow(self.assister_lb, self.assister_ed)

        hbox = QHBoxLayout()
        hbox.addWidget(self.show_input_cookie_btn)
        hbox.addStretch(1)
        hbox.addWidget(self.ok_btn)
        hbox.addWidget(self.cancel_btn)

        user_box = QHBoxLayout()
        self.user_num = 0
        self.user_btns = {}
        for user in self._config.users_name:
            user = str(user)  # TODO: 可能需要删掉
            self.user_btns[user] = QDoublePushButton(user)
            self.user_btns[user].setStyleSheet("QPushButton {border:none;}")
            if user == self._config.name:
                self.user_btns[user].setStyleSheet("QPushButton {background-color:rgb(0,153,2);}")
                self.tabs.setCurrentIndex(1)
            self.user_btns[user].setToolTip(f"点击选中,双击切换至用户:{user}")
            self.user_btns[user].doubleClicked.connect(self.choose_user)
            self.user_btns[user].clicked.connect(self.delete_chose_user)
            user_box.addWidget(self.user_btns[user])
            self.user_num += 1
            user_box.addStretch(1)

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(logo)
        vbox = QVBoxLayout()
        if self._config.name:
            vbox.addWidget(lb_line_1)
            user_box.setAlignment(Qt.AlignmentFlag.AlignCenter)
            vbox.addLayout(user_box)
            vbox.addWidget(lb_line_2)
            if self.user_num > 1:
                self.del_user_btn = QPushButton("删除账户")
                self.del_user_btn.setIcon(QIcon(SRC_DIR + "delete.ico"))
                self.del_user_btn.setStyleSheet("QPushButton {min-width: 180px;max-width: 180px;}")
                self.del_user_btn.clicked.connect(self.call_del_chose_user)
                vbox.addWidget(self.del_user_btn)
            else:
                self.del_user_btn = None
            vbox.addStretch(1)

        vbox.addLayout(self.form)
        vbox.addStretch(1)
        vbox.addLayout(hbox)
        vbox.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.hand_tab.setLayout(vbox)
        auto_cookie_vbox = QVBoxLayout()
        auto_cookie_vbox.addWidget(self.auto_get_cookie_ok)
        auto_cookie_vbox.addWidget(self.auto_get_cookie_btn)
        auto_cookie_vbox.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.auto_tab.setLayout(auto_cookie_vbox)
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
        self.update_selection(self._config.name)
Beispiel #12
0
 def __init__(self, parent: QWidget):
     super().__init__()
     self.logger = logging.getLogger(__name__)
     with open(file="config.json", mode="r",
               encoding="utf-8") as conf_reader:
         self.conf = json.loads(conf_reader.read())
     self.logger.debug("初始化设置界面。设置内容:%s" % self.conf)
     layout = QGridLayout()
     self.setLayout(layout)
     self.setModal(True)
     self.setParent(parent)
     self.resize(400, 300)
     title = QLabel("设置")
     title.setStyleSheet(
         "QLabel{border:none;border-radius:5px;background:transparent;color:#9AD3BC;font-size:20px;}"
     )
     title.setAlignment(Qt.Alignment.AlignCenter)
     layout.addWidget(title, 0, 1, Qt.Alignment.AlignCenter)
     control_close = QPushButton()
     control_close.setStyleSheet(
         "QPushButton{background:#FFE3ED;border-radius:5px;border:none;}QPushButton:hover{background:#EC524B;}"
     )
     control_close.setToolTip("关闭")
     control_close.setFixedHeight(20)
     control_close.clicked.connect(self.close_callback)
     layout.addWidget(control_close, 0, 0)
     debug_check = QCheckBox("调试模式")
     debug_check.setChecked(self.conf["debug"])
     debug_check.setToolTip("单击切换开关状态")
     debug_check.setStyleSheet(
         "QCheckBox::indicator{width:10px;height:10px;border:none;border-radius:5px;background:#9BE3DE;}QCheckBox::indicator:unchecked{background:#BEEBE9;}QCheckBox::indicator:unchecked:hover{background:#9AD3BC;}QCheckBox::indicator:checked{background:#95E1D3;}QCheckBox::indicator:checked:hover{background:#98DED9;}"
     )
     self.content = QGridLayout()
     (x, y) = self.show_setting(conf=self.conf,
                                layout=self.content)  # 返回content的最后一个元素的x,y
     proxy = QGroupBox()
     proxy.setObjectName("proxy")
     proxy_layout = QVBoxLayout()
     proxy_label = QLabel("代理地址:")
     proxy_label.setStyleSheet(
         "QLabel{background:transparent;border:none;}")
     proxy_input = EnhancedEdit()
     proxy_input.setText(self.conf["proxy"])
     proxy_input.setToolTip("格式为协议://IP:端口,留空保持直连")
     proxy_input.setStyleSheet(
         "QLineEdit{border:1px solid #F3EAC2;border-radius:5px;background:transparent;}QLineEdit:hover{border:1px solid #F5B461;}"
     )
     proxy_layout.addWidget(proxy_label)
     proxy_layout.addWidget(proxy_input)
     proxy.setLayout(proxy_layout)
     proxy.setStyleSheet("QGroupBox{border-radius:5px;}")
     proxy.setToolTip("代理设置")
     if y + 1 >= 3:
         y_ = 0
         x_ = x + 1
     else:
         y_ = y + 1
         x_ = x
     self.content.addWidget(proxy, x_, y_)
     self.content.addWidget(debug_check)
     layout.addLayout(self.content, 1, 1)
Beispiel #13
0
class AboutDialog(QDialog):
    check_update = pyqtSignal(str, bool)

    def __init__(self, parent=None):
        super(AboutDialog, self).__init__(parent)
        self._ver = ''
        self._github = 'https://github.com/rachpt/lanzou-gui'
        self._api_url = 'https://github.com/zaxtyson/LanZouCloud-API'
        self._gitee = 'https://gitee.com/rachpt/lanzou-gui'
        self._home_page = 'https://rachpt.cn/lanzou-gui/'
        self.initUI()
        self.setStyleSheet(others_style)

    def set_values(self, version):
        self._ver = version
        self.lb_name_text.setText(f"v{version}  (点击检查更新)")  # 更新版本

    def show_update(self, ver, msg):
        self.lb_new_ver = QLabel("新版")  # 检测新版
        self.lb_new_ver_msg = QLabel()
        self.lb_new_ver_msg.setOpenExternalLinks(True)
        self.lb_new_ver_msg.setWordWrap(True)
        if ver != '0':
            self.lb_name_text.setText(f"{self._ver}  ➡  {ver}")
        self.lb_new_ver_msg.setText(msg)
        self.lb_new_ver_msg.setMinimumWidth(700)
        if self.form.rowCount() < 5:
            self.form.insertRow(1, self.lb_new_ver, self.lb_new_ver_msg)

    def initUI(self):
        self.setWindowTitle("关于 lanzou-gui")
        about = f'本项目使用PyQt6实现图形界面,可以完成蓝奏云的大部分功能<br/> \
    得益于 <a href="{self._api_url}">API</a> 的功能,可以间接突破单文件最大 100MB 的限制,同时增加了批量上传/下载的功能<br/> \
Python 依赖见<a href="{self._github }/blob/master/requirements.txt">requirements.txt</a>,\
<a href="{self._github}/releases">releases</a> 有打包好了的 Windows 可执行程序,但可能不是最新的'

        project_url = f'<a href="{self._home_page}">主页</a> | <a href="{self._github}">repo</a> | \
                        <a href="{self._gitee}">mirror repo</a>'

        self.logo = QLabel()  # logo
        self.logo.setPixmap(QPixmap(SRC_DIR + "logo2.gif"))
        self.logo.setStyleSheet("background-color:rgb(255,255,255);")
        self.logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.lb_qt_ver = QLabel("依赖")  # QT 版本
        self.lb_qt_text = QLabel(
            f"QT: {QT_VERSION_STR}, PyQt: {PYQT_VERSION_STR}")  # QT 版本
        self.lb_name = QLabel("版本")  # 版本
        self.lb_name_text = QPushButton("")  # 版本
        self.lb_name_text.setToolTip("点击检查更新")
        ver_style = "QPushButton {border:none; background:transparent;font-weight:bold;color:blue;}"
        self.lb_name_text.setStyleSheet(ver_style)
        self.lb_name_text.clicked.connect(
            lambda: self.check_update.emit(self._ver, True))
        self.lb_about = QLabel("关于")  # about
        self.lb_about_text = QLabel()
        self.lb_about_text.setText(about)
        self.lb_about_text.setOpenExternalLinks(True)
        self.lb_author = QLabel("作者")  # author
        self.lb_author_mail = QLabel(
            "<a href='mailto:[email protected]'>rachpt</a>")
        self.lb_author_mail.setOpenExternalLinks(True)
        self.lb_update = QLabel("项目")  # 更新
        self.lb_update_url = QLabel(project_url)
        self.lb_update_url.setOpenExternalLinks(True)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.StandardButton.Close)
        self.buttonBox.button(
            QDialogButtonBox.StandardButton.Close).setText("关闭")
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.setStyleSheet(btn_style)

        self.recommend = QLabel(
            "<br />大文件推荐使用 <a href='https://github.com/Aruelius/cloud189'>cloud189-cli</a>"
        )
        self.recommend.setOpenExternalLinks(True)

        self.line = QLine(QPoint(), QPoint(550, 0))
        self.lb_line = QLabel('<html><hr /></html>')

        vbox = QVBoxLayout()
        vbox.addWidget(self.logo)
        vbox.addStretch(1)
        self.form = QFormLayout()
        self.form.setLabelAlignment(Qt.AlignmentFlag.AlignRight)
        self.form.setFormAlignment(Qt.AlignmentFlag.AlignLeft)
        self.form.setHorizontalSpacing(40)
        self.form.setVerticalSpacing(15)
        self.form.addRow(self.lb_qt_ver, self.lb_qt_text)
        self.form.addRow(self.lb_name, self.lb_name_text)
        self.form.addRow(self.lb_update, self.lb_update_url)
        self.form.addRow(self.lb_author, self.lb_author_mail)
        self.form.addRow(self.lb_about, self.lb_about_text)
        self.form.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.
                                       AllNonFixedFieldsGrow)  # 覆盖MacOS的默认样式
        vbox.addLayout(self.form)
        vbox.addStretch(1)
        vbox.addWidget(self.recommend)
        vbox.addWidget(self.lb_line)
        donate = QLabel()
        donate.setText("<b>捐助我</b>&nbsp;如果你愿意")
        donate.setAlignment(Qt.AlignmentFlag.AlignCenter)
        hbox = QHBoxLayout()
        hbox.addStretch(2)
        for it in ["wechat", "alipay", "qqpay"]:
            lb = QLabel()
            lb.setPixmap(QPixmap(SRC_DIR + f"{it}.jpg"))
            hbox.addWidget(lb)
        hbox.addStretch(1)
        hbox.addWidget(self.buttonBox)
        vbox.addWidget(donate)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        self.setMinimumWidth(720)

    def paintEvent(self, event):
        QDialog.paintEvent(self, event)
        if not self.line.isNull():
            painter = QPainter(self)
            pen = QPen(Qt.GlobalColor.red, 3)
            painter.setPen(pen)
            painter.drawLine(self.line)
Beispiel #14
0
class MergeFileDialog(QDialog):
    check_update = pyqtSignal(str, bool)

    def __init__(self, user_home, parent=None):
        super(MergeFileDialog, self).__init__(parent)
        self.cwd = user_home
        self.selected = ""
        self.initUI()
        self.setStyleSheet(others_style)

    def initUI(self):
        self.setWindowTitle("合并文件")
        self.setWindowIcon(QIcon(SRC_DIR + "upload.ico"))
        self.logo = QLabel()
        self.logo.setPixmap(QPixmap(SRC_DIR + "logo3.gif"))
        self.logo.setStyleSheet("background-color:rgb(0,153,255);")
        self.logo.setAlignment(Qt.AlignmentFlag.AlignCenter)

        # lable
        self.choose_lb = QLabel("选择文件夹")
        # folder
        self.choose_folder = MyLineEdit(self)
        self.choose_folder.setObjectName("choose_folder")
        self.choose_folder.clicked.connect(self.slot_choose_folder)
        self.status = QLabel(self)

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.StandardButton.Ok
            | QDialogButtonBox.StandardButton.Cancel)
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText("提取")
        self.buttonBox.button(
            QDialogButtonBox.StandardButton.Cancel).setText("关闭")
        self.buttonBox.setStyleSheet(btn_style)

        vbox = QVBoxLayout()
        hbox_head = QHBoxLayout()
        hbox_button = QHBoxLayout()
        hbox_head.addWidget(self.choose_lb)
        hbox_head.addWidget(self.choose_folder)
        hbox_button.addWidget(self.buttonBox)
        vbox.addWidget(self.logo)
        vbox.addStretch(1)
        vbox.addWidget(self.status)
        vbox.addLayout(hbox_head)
        vbox.addStretch(1)
        vbox.addLayout(hbox_button)
        self.setLayout(vbox)
        self.setMinimumWidth(350)

        # 设置信号
        self.buttonBox.accepted.connect(self.slot_btn_ok)
        self.buttonBox.rejected.connect(self.slot_btn_no)
        self.buttonBox.rejected.connect(self.reject)

    def slot_choose_folder(self):
        dir_choose = QFileDialog.getExistingDirectory(self, "选择文件夹",
                                                      self.cwd)  # 起始路径
        if dir_choose == "":
            return
        self.selected = dir_choose
        self.choose_folder.setText(self.selected)
        self.status.setText("")
        self.cwd = os.path.dirname(dir_choose)

    def slot_btn_no(self):
        self.selected = ""
        self.choose_folder.setText(self.selected)
        self.status.setText("")

    def slot_btn_ok(self):
        if self.selected:
            success, msg = un_serialize(self.selected)
            if success:
                text = "提取成功✅"
            else:
                text = f"提取失败❌, {msg}"
        else:
            text = "未选择文件夹📂"
        self.status.setText(text)
Beispiel #15
0
    def initUI(self):
        self.setWindowTitle("设置")
        logo = QLabel()
        logo.setPixmap(QPixmap(SRC_DIR + "logo2.gif"))
        logo.setStyleSheet("background-color:rgb(255,255,255);")
        logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.download_threads_lb = QLabel("同时下载文件数")
        self.download_threads_var = QLineEdit()
        self.download_threads_var.setPlaceholderText("范围:1-9")
        self.download_threads_var.setToolTip("范围:1-9")
        self.download_threads_var.setInputMask("D")
        self.max_size_lb = QLabel("分卷大小(MB)")
        self.max_size_var = QLineEdit()
        self.max_size_var.setPlaceholderText("普通用户最大100,vip用户根据具体情况设置")
        self.max_size_var.setToolTip("普通用户最大100,vip用户根据具体情况设置")
        self.max_size_var.setInputMask("D99")
        self.timeout_lb = QLabel("请求超时(秒)")
        self.timeout_var = QLineEdit()
        self.timeout_var.setPlaceholderText("范围:1-99")
        self.timeout_var.setToolTip("范围:1-99")
        self.timeout_var.setInputMask("D9")
        self.upload_delay_lb = QLabel("上传延时(秒)")
        self.upload_delay_var = QLineEdit()
        self.upload_delay_var.setPlaceholderText("范围:1-99")
        self.upload_delay_var.setToolTip("范围:1-99")
        self.upload_delay_var.setInputMask("D9")
        self.dl_path_lb = QLabel("下载保存路径")
        self.dl_path_var = MyLineEdit(self)
        self.dl_path_var.clicked.connect(self.set_download_path)
        self.time_fmt_box = QCheckBox("使用[年-月-日]时间格式")
        self.time_fmt_box.setToolTip("文件上传日期显示格式")
        self.to_tray_box = QCheckBox("关闭到系统托盘")
        self.to_tray_box.setToolTip("点击关闭软件按钮是最小化软件至系统托盘")
        self.watch_clipboard_box = QCheckBox("监听系统剪切板")
        self.watch_clipboard_box.setToolTip("检测到系统剪切板中有符合规范的蓝奏链接时自动唤起软件,并提取")
        self.debug_box = QCheckBox("开启调试日志")
        self.debug_box.setToolTip("记录软件 debug 信息至 debug-lanzou-gui.log 文件")
        self.set_pwd_box = QCheckBox("上传文件自动设置密码")
        self.set_pwd_var = AutoResizingTextEdit()
        self.set_pwd_var.setPlaceholderText(" 2-8 位数字或字母")
        self.set_pwd_var.setToolTip("2-8 位数字或字母")
        self.set_desc_box = QCheckBox("上传文件自动设置描述")
        self.set_desc_var = AutoResizingTextEdit()
        self.big_file_box = QCheckBox(f"允许上传超过 {self.max_size}MB 的大文件")
        self.big_file_box.setToolTip("开启大文件上传支持 (功能下线)")
        self.upgrade_box = QCheckBox("自动检测新版本")
        self.upgrade_box.setToolTip("在软件打开时自动检测是否有新的版本发布,如有则弹出更新信息")

        self.time_fmt_box.toggle()
        self.time_fmt_box.stateChanged.connect(self.change_time_fmt)
        self.to_tray_box.stateChanged.connect(self.change_to_tray)
        self.watch_clipboard_box.stateChanged.connect(self.change_watch_clipboard)
        self.debug_box.stateChanged.connect(self.change_debug)
        self.set_pwd_box.stateChanged.connect(self.change_set_pwd)
        self.set_pwd_var.editingFinished.connect(self.check_pwd)
        self.set_desc_box.stateChanged.connect(self.change_set_desc)
        self.big_file_box.stateChanged.connect(self.change_big_file)
        self.upgrade_box.stateChanged.connect(self.change_upgrade)

        buttonBox = QDialogButtonBox()
        buttonBox.setOrientation(Qt.Orientation.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Reset | QDialogButtonBox.StandardButton.Save | QDialogButtonBox.StandardButton.Cancel)
        buttonBox.button(QDialogButtonBox.StandardButton.Reset).setText("重置")
        buttonBox.button(QDialogButtonBox.StandardButton.Save).setText("保存")
        buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText("取消")
        buttonBox.button(QDialogButtonBox.StandardButton.Reset).clicked.connect(lambda: self.set_values(reset=True))
        buttonBox.button(QDialogButtonBox.StandardButton.Save).clicked.connect(self.slot_save)
        buttonBox.rejected.connect(self.reject)

        form = QFormLayout()
        form.setLabelAlignment(Qt.AlignmentFlag.AlignRight)
        form.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)  # 覆盖MacOS的默认样式
        form.setSpacing(10)
        form.addRow(self.download_threads_lb, self.download_threads_var)
        form.addRow(self.timeout_lb, self.timeout_var)
        form.addRow(self.upload_delay_lb, self.upload_delay_var)
        form.addRow(self.max_size_lb, self.max_size_var)
        form.addRow(self.dl_path_lb, self.dl_path_var)

        vbox = QVBoxLayout()
        vbox.addWidget(logo)
        vbox.addStretch(1)
        vbox.addLayout(form)
        vbox.addStretch(1)
        hbox = QHBoxLayout()
        hbox.addWidget(self.time_fmt_box)
        hbox.addWidget(self.to_tray_box)
        hbox.addWidget(self.watch_clipboard_box)
        hbox.addWidget(self.debug_box)
        vbox.addLayout(hbox)
        vbox.addStretch(1)
        hbox_2 = QHBoxLayout()
        hbox_2.addWidget(self.set_pwd_box)
        hbox_2.addWidget(self.set_pwd_var)
        vbox.addLayout(hbox_2)
        vbox.addStretch(1)
        hbox_3 = QHBoxLayout()
        hbox_3.addWidget(self.set_desc_box)
        hbox_3.addWidget(self.set_desc_var)
        vbox.addLayout(hbox_3)
        hbox_4 = QHBoxLayout()
        hbox_4.addWidget(self.big_file_box)
        hbox_4.addWidget(self.upgrade_box)
        vbox.addStretch(1)
        vbox.addLayout(hbox_4)
        vbox.addStretch(2)
        vbox.addWidget(buttonBox)
        self.setLayout(vbox)
        self.setMinimumWidth(500)
Beispiel #16
0
class MainWindow(QWidget):
    def reload(self):
        if len(self.file_list): return
        self.webEngineView.reload()

    def on_downloadRequestState(self,event):
        if not len(self.file_list):
            self.label.setText('Статус:...')
            self.reload()
            try:
                for b in self.buttons: b.setEnabled(True)
            except: pass
            return
        if event.value>1:
            if event.value==2:
                if len(self.file_list[-1])>5:
                    h0=self.file_list[-1][6]
                    h1=gethash(self.file_list[-1][-1])
                    if h0==h1:
                        try:
                            tm=mktime(datetime.strptime(self.file_list[-1][4],"%d.%m.%Y %H:%M").timetuple())
                            tm+=(int(self.file_list[-1][5])%60)
                            utime(self.file_list[-1][-1],(tm,tm))
                        except: pass
                    else:
                        print('Error. ("%s") - %i'%(self.file_list[-1][-1],event.value))
                        self.label.setText('Статус: ошибка скачивания файла ("'+self.file_list[-1][-1]+'")')
                self.file_list.pop()
                self.download_files()
            else:
                print('Error. ("%s") - %i'%(self.file_list[-1][-1],event.value))
                self.label.setText('Статус: ошибка скачивания файла ("%s", код ошибки: %i)!'%(self.file_list[-1][-1],event.value))
                self.reload()
                try:
                    for b in self.buttons: b.setEnabled(True)
                except: pass

    def check_canceled(self,event):
        if event: self.canceled_callback()

    def on_downloadRequested(self,event):
        self.webEngineView.page().runJavaScript(\
            """
            function check_canceled(){
                if(window.process_canceled) return 1;
                else return 0;
            };
            check_canceled();
            """,self.check_canceled)
        if event.state().value==0:
            event.stateChanged.connect(lambda event: self.on_downloadRequestState(event))
            event.accept()

    def download_files(self):
        if len(self.file_list):
            if not self.file_number: self.file_number=len(self.file_list)
            tmp=self.file_list[-1]
            if exists(tmp[-1]):
                try: remove(tmp[-1])
                except: pass
            self.webEngineView.page().profile().downloadRequested.connect(lambda event:\
                self.on_downloadRequested(event))
            self.label.setText('Статус: скачивание файла "%s" ( %i из %i )'%\
                               (tmp[2],self.file_number-len(self.file_list)+1,self.file_number))
            self.webEngineView.page().download(QUrl(tmp[3]),tmp[-1])
        else:
            self.webEngineView.page().profile().downloadRequested.disconnect()
            self.label.setText('Статус:...')
            self.reload()
            try:
                for b in self.buttons: b.setEnabled(True)
            except: pass

    def canceled_callback(self):
        self.label.setText('Статус: операция отменена!')
        self.file_list=[]
        self.file_number=0
        self.reload()
        try:
            for b in self.buttons: b.setEnabled(True)
        except: pass

    def getfilelist_error_callback(self):
        self.label.setText('Статус: ошибка при получении списка файлов для скачивания!')
        self.file_list=[]
        self.file_number=0
        self.reload()
        try:
            for b in self.buttons: b.setEnabled(True)
        except: pass

    def getfilelist_success_callback(self,links):
        for link in links:
            path=join(self.basepath,link[0],link[1])
            try: makedirs(path,exist_ok=True)
            except: return
            link.append(realpath(join(path,link[2])))
            self.file_list.append(link)
        if len(self.file_list):
            self.download_files()

    def progress_callback(self,counter):
        self.label.setText('Статус: получение списка файлов для скачивания (получено %d ссылок)...'%counter)

    def getfileslist(self):
        if len(self.file_list): return
        self.url=self.webEngineView.url().toString()
        if not('Files/prt0' in self.url): return
        self.file_list=[]
        self.file_number=0
        try:
            for b in self.buttons: b.setEnabled(False)
        except: pass
        self.label.setText('Статус: получение списка файлов для скачивания...')
        self.webEngineView.page().runJavaScript(\
            self.qwebchannel_js+self.busy+"""
            function get_sig_links_details_parse(file_links,details_links,partitions,partition,section,data){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                var parser=new DOMParser();
                var doc=parser.parseFromString(data,'text/html');
                var req=doc.querySelectorAll('a[href*=\"GetFile\"]');
                for(const e of req){
                    if(e.text.includes('.sig')){
                        file_links.push([pd_replace(partition),sec_replace(section),e.text,e.href]);
                        progress(file_links);
                    };
                };
                if(details_links.length) get_sig_links_details(file_links,details_links,partitions);
                else success(file_links);
            };
            function start_parser(){
                var file_links=[];
                var details_links=[];
                var url=window.location.href.toString();
                var path='';
                if(url.includes('ProjectDocuments')) path='ProjectDocuments';
                else if(url.includes('RIIDocuments')) path='RIIDocuments';
                    else if(url.includes('SmetaDocuments')) path='SmetaDocuments';
                        else if(url.includes('IrdDocuments')) path='IrdDocuments';
                var href=''.concat('https://lk.spbexp.ru/Grid/',path,'FilesRead/own',
                    window.location.href.toString().split('\/').pop());
                var v=document.querySelector('span[style=\"font-weight:600; color:darkblue\"]');\
                if(v==null) return;
                var section=v.textContent;
                var links=[[path,section,href]];
                new QWebChannel(qt.webChannelTransport,(channel)=>{
                    window.qtwebchannel=channel.objects.backend;
                });
                get_pd_links_details(links,file_links,details_links,[]);
            };
            start_parser();
            """,lambda x: None)

    def getallfileslist(self):
        if len(self.file_list): return
        self.url=self.webEngineView.url().toString()
        if not('lk.spbexp.ru/Zeg/Zegmain' in self.url or\
               ('lk.spbexp.ru/SF/' in self.url and '/prt0/' in self.url)): return
        self.file_list=[]
        self.file_number=0
        try:
            for b in self.buttons: b.setEnabled(False)
        except: pass
        self.label.setText('Статус: получение списка файлов для скачивания...')
        self.webEngineView.page().runJavaScript(\
            self.qwebchannel_js+self.busy+"""
            function get_sig_links_details_parse(file_links,details_links,partitions,partition,section,data){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                var parser=new DOMParser();
                var doc=parser.parseFromString(data,'text/html');
                var req=doc.querySelectorAll('a[href*=\"GetFile\"]');
                for(const e of req){
                    if(e.text.includes('.sig')){
                        file_links.push([pd_replace(partition),sec_replace(section),e.text,e.href]);
                        progress(file_links);
                    };
                };
                if(details_links.length) get_sig_links_details(file_links,details_links,partitions);
                else get_file_links(file_links,details_links,partitions);
            };
            function get_pd_links_parse(path,file_links,details_links,partitions,data){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                var links=[];
                for(const d of data.Data){
                    if(d['NumberOfFiles']){
                        var href=''.concat('https://lk.spbexp.ru/Grid/',path,'FilesRead/own',d['IDRow']);
                        if(path.includes('IrdDocuments')) links.push([path,d['Content'],href]);
                        else links.push([path,d['Nazvanie'],href]);
                    };
                };
                if(links.length) get_pd_links_details(links,file_links,details_links,partitions);
            };
            async function get_pd_links(path,file_links,details_links,partitions){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                var req=document.querySelector('a[href*="/Zeg/Zegmain1"]');
                if(req){
                    var href=''.concat('https://lk.spbexp.ru/Grid/',path,'Read/own',req.pathname.split('\/').pop());
                    return await fetch(href)
                                .then(async (response) => {
                                const j=await response.json();
                                get_pd_links_parse(path,file_links,details_links,partitions,j);
                                }).catch((error) => { errlog(error); });
                };
            };
            function get_file_links(file_links,details_links,partitions){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                if(partitions.length) get_pd_links(partitions.pop(),file_links,details_links,partitions);
                else success(file_links);
            };
            function start_parser(){
                var file_links=[];
                var details_links=[];
                var partitions=['ProjectDocuments','RIIDocuments','SmetaDocuments','IrdDocuments'];
                new QWebChannel(qt.webChannelTransport,(channel)=>{
                    window.qtwebchannel=channel.objects.backend;
                });
                get_file_links(file_links,details_links,partitions);
            };
            start_parser();
            """,lambda x: None)

    def __init__(self):
        super().__init__()
        self.setWindowTitle('ExpGet')
        self.busy="""
            window.process_canceled=false;
            function errlog(error){
                window.qtwebchannel.backrun_error(error);
            };
            function success(file_links){
                window.qtwebchannel.backrun_success(file_links);
            };
            function progress(file_links){
                window.qtwebchannel.backrun_progress(file_links.length);
            };
            async function cancel(){
                window.qtwebchannel.backrun_cancel();
            };
            function pd_replace(partition){
                switch(partition){
                    case 'ProjectDocuments': return 'ПД';
                    case 'RIIDocuments': return 'РИИ';
                    case 'SmetaDocuments': return 'СД';
                    case 'IrdDocuments': return 'ИРД';
                };
            };
            function sec_replace(section){
                return section.trim().replaceAll('"','_').slice(0,64).trim();
            };
            async function get_sig_links_details(file_links,details_links,partitions){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                if(details_links.length){
                    var d=details_links.pop();
                    return await fetch(d[2])
                                .then(async (response) => {
                                    const j=await response.text();
                                    get_sig_links_details_parse(file_links,details_links,partitions,d[0],d[1],j);
                                }).catch((error) => { errlog(error); });
                };
            };
            function get_pd_links_details_parse(links,file_links,details_links,partitions,partition,section,data){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                for(const d of data.Data){
                    file_links.push([pd_replace(partition),sec_replace(section),d['Nazvanie'],
                        ''.concat('https://lk.spbexp.ru/File/GetFile/',d['IDRow']),d['sDateTo'],d['Number'],d['sMD5']]);
                    progress(file_links);
                    details_links.push([partition,section,''.concat('https://lk.spbexp.ru/SF/FileCspViewer/',d['IDRow'])]);
                };
                if(links.length) get_pd_links_details(links,file_links,details_links,partitions);
                else get_sig_links_details(file_links,details_links,partitions);
            };
            async function get_pd_links_details(links,file_links,details_links,partitions){
                if(window.process_canceled){
                    cancel();
                    return;
                };
                if(links.length){
                    var d=links.pop();
                    return await fetch(d[2])
                                .then(async (response) => {
                                    const j=await response.json();
                                    get_pd_links_details_parse(links,file_links,details_links,partitions,d[0],d[1],j);
                                }).catch((error) => { errlog(error); });
                };
            };
            function button_click(){
                window.process_canceled=true;
            };
            class ProgressRing extends HTMLElement{
                constructor(){
                    super();
                    const stroke=this.getAttribute('stroke');
                    const radius=this.getAttribute('radius');
                    const normalizedRadius=radius-stroke*2;
                    this._circumference=normalizedRadius*2*Math.PI;
                    this._root=this.attachShadow({mode:'open'});
                    this._root.innerHTML=`
                        <svg height="${radius*2}" width="${radius*2}">
                            <circle
                                class="ring"
                                stroke="#3c3b3a"
                                stroke-width="${stroke*2}"
                                stroke-opacity="0.5"
                                fill="transparent"
                                r="${normalizedRadius}"
                                cx="${radius}"
                                cy="${radius}"
                                shape-rendering="geometricPrecision"
                            />
                            <circle
                                class="ring"
                                stroke="#c8c5c3"
                                stroke-dasharray="${this._circumference} ${this._circumference}"
                                style="stroke-dashoffset:${this._circumference}"
                                stroke-width="${stroke}"
                                fill="transparent"
                                r="${normalizedRadius}"
                                cx="${radius}"
                                cy="${radius}"
                                shape-rendering="geometricPrecision"
                            />
                            <circle
                                class="button"
                                stroke="#191919"
                                stroke-width="1"
                                fill="#f44336"
                                r="${normalizedRadius-stroke}"
                                cx="${radius}"
                                cy="${radius}"
                                shape-rendering="geometricPrecision"
                                onclick="button_click()"
                            />
                            <text class="txt" x="50%" y="52%" text-rendering="geometricPrecision">STOP</text>
                            <circle
                                class="ring"
                                stroke="#000000"
                                stroke-width="1"
                                stroke-opacity="0.5"
                                fill="transparent"
                                r="${normalizedRadius+8}"
                                cx="${radius}"
                                cy="${radius}"
                                shape-rendering="geometricPrecision"
                            />
                        </svg>
                        <style>
                            .ring {
                                transition: stroke-dashoffset 0.35s;
                                transform: rotate(-90deg);
                                transform-origin: 50% 50%;
                                pointer-events: none;
                            }
                            .button:hover {
                                fill: #ce000f;
                                opacity: 1;
                            }
                            .txt {
                                font: bold 40px sans-serif;
                                fill: #323232;
                                stroke: #4c4c4c;
                                stroke-width: 1px;
                                text-anchor: middle;
                                dominant-baseline: middle;
                                pointer-events: none;
                            }
                        </style>
                    `;
                }
                setProgress(percent){
                    const offset=this._circumference-(percent/100*this._circumference);
                    const circle=this._root.querySelectorAll('circle')[1];
                    circle.style.strokeDashoffset=offset;
                }
                setTransition(value){
                    const circle=this._root.querySelectorAll('circle')[1];
                    circle.style.transition='stroke-dashoffset '+value+'s';
                }
                static get observedAttributes(){ return ['progress','transition']; }
                attributeChangedCallback(name,oldValue,newValue){
                    if(name==='progress') this.setProgress(newValue);
                    if(name==='transition') this.setTransition(newValue);
                }
            }
            function overlay() {
                [].forEach.call(document.querySelectorAll('nav'), function (el) {
                    el.style.visibility = 'hidden';
                });
                [].forEach.call(document.querySelectorAll('*[class*=popover]'), function (el) {
                    el.style.visibility = 'hidden';
                });
                var overlay=document.createElement("div");
                overlay.style.opacity=0.9;
                overlay.style.width='100%';
                overlay.style.height='100%';
                overlay.style.top='0px';
                overlay.style.left='0px';
                overlay.style.backgroundColor='#666666';
                overlay.style.zIndex='1000';
                overlay.style.position = 'absolute';
                document.getElementsByTagName('body')[0].appendChild(overlay);
                window.customElements.define('progress-ring',ProgressRing);
                const circle=document.createElement("div");
                circle.innerHTML=`<progress-ring stroke="8" radius="88" progress="0"></progress-ring>`
                circle.style.top='50%';
                circle.style.left='50%';
                circle.style.marginTop='-88px'
                circle.style.marginLeft='-88px'
                circle.style.zIndex='2000';
                circle.style.position='absolute';
                window.cprogress=0;
                document.body.appendChild(circle);
                document.body.style.overflow='hidden';
            };
            overlay();
            const interval=setInterval(()=>{
                const el=document.querySelector('progress-ring');
                if(window.cprogress==200){
                    el.setAttribute('transition','0');
                    window.cprogress=0;
                    el.setAttribute('progress',window.cprogress);
                }
                else{
                    if(window.cprogress==0) el.setAttribute('transition','0.35');
                    window.cprogress+=2;
                    el.setAttribute('progress',window.cprogress);
                };
            },100);
        """

        self.webEngineView=QWebEngineView()
        ws=self.webEngineView.page().profile().defaultProfile()
        ws.setHttpCacheMaximumSize(0)
        ws=self.webEngineView.settings()
        ws.setAttribute(ws.WebAttribute.AutoLoadImages,True)
        ws.setAttribute(ws.WebAttribute.PluginsEnabled,False)

        qwebchannel_js=QFile(':/qtwebchannel/qwebchannel.js')
        if not qwebchannel_js.open(QIODeviceBase.OpenModeFlag.ReadOnly):
            raise SystemExit(
                'Failed to load qwebchannel.js with error: %s' %
                qwebchannel_js.errorString())
        self.qwebchannel_js=bytes(qwebchannel_js.readAll()).decode('utf-8')
        self.channel=QWebChannel()
        self.handler=CallHandler()
        self.handler.set_parent(self)
        self.channel.registerObject('backend',self.handler)
        self.webEngineView.page().setWebChannel(self.channel)

        self.grid=QGridLayout()
        self.grid.setContentsMargins(0,0,0,0)
        self.grid.setVerticalSpacing(0)
        self.grid.setHorizontalSpacing(0)
        self.hbox=QHBoxLayout()
        self.hbox.setSpacing(0)
        self.reload_button=QPushButton('Обновить страницу')
        self.get_data_button=QPushButton('Получить данные')
        self.get_all_data_button=QPushButton('Скачать данные проекта')
        self.buttons=[self.reload_button,self.get_data_button,self.get_all_data_button]
        self.hbox.addWidget(self.reload_button,1)
        self.hbox.addWidget(self.get_data_button,1)
        self.hbox.addWidget(self.get_all_data_button,1)
        self.grid.addLayout(self.hbox,0,0)
        self.grid.addWidget(self.webEngineView,1,0)
        self.label=QLabel('Статус:...')
        self.label.setStyleSheet("QLabel {background-color:gray;color:black;}")
        self.grid.addWidget(self.label,2,0)
        self.grid.setRowStretch(0,0)
        self.grid.setRowStretch(1,1)
        self.grid.setRowStretch(2,0)
        self.setLayout(self.grid)

        self.webEngineView.load(QUrl('https://lk.spbexp.ru'))
        self.webEngineView.loadFinished.connect(self.login)

        self.file_list=[]
        self.file_number=0
        self.lock=False
        self.basepath=realpath('out')
        try: makedirs(self.basepath,exist_ok=True)
        except: pass

        self.reload_button.clicked.connect(self.reload)
        self.get_data_button.clicked.connect(self.getfileslist)
        self.get_all_data_button.clicked.connect(self.getallfileslist)

    def goto_projects(self):
        self.webEngineView.loadFinished.disconnect()
        self.webEngineView.load(QUrl('https://lk.spbexp.ru/SF/Zayava/'))

    def login_callback(self,result):
        if len(result):
            self.webEngineView.loadFinished.connect(self.goto_projects)

    def login(self):
        l=p=''
        try:
            f=open('login','r')
            d=f.readlines()
            f.close()
            l=d[0].strip()
            p=d[1].strip()
        except:
            self.webEngineView.loadFinished.disconnect()
            return
        self.webEngineView.page().runJavaScript("""
            function find_login_form(){
                var v=document.querySelector('input[id=Login]');
                if(v!=null){
                    v.value=`%s`;
                    v=document.querySelector('input[id=Password]');
                    if(v!=null){
                        v.value=`%s`;
                        v=document.querySelector('button[type=submit]');
                        if(v!=null){
                            v.click();
                            return 'ok';
                        };
                    };
                };
                return '';
            };
            find_login_form();"""%(l,p),self.login_callback)
Beispiel #17
0
class PlayerBox(QGroupBox):
    """PlayerBox Subclass of QGroupBox.

    Returns GroupBoxWidget data and cards for each player.
    """

    offsheet = """QGroupBox {
        font-size: 14pt;
        padding: 4px;
        margin: 5px;
        color: #efeefe;
        border: 9px solid #dfa;}"""

    onsheet = """QGroupBox {
        color: red;
        padding: 4px;
        margin: 5px;
        border: 5px solid red;
        border-radius: 2px;}"""

    labelsheet = """QLabel {
        color: #efeefe;
        margin-bottom: 8px;
        font-weight: bold;
        font-size: 14pt;
        font-style: italic;}"""

    scoresheet = """QLabel {
        border: 1px solid #efeefe;
        padding: 3px;
        margin-bottom: 8px;
        color: #efeefe;
        font-weight: bold;
        font-size: 16pt;
        font-style: italic;}"""

    def __init__(self, title, parent=None, player=None):
        """Construct a PlayerBox Widget.

        Args:
            parent (QWidget, optional) Parent widget object. Defaults to None.
            player (Player) The player this box will be assigned to.
        """
        super().__init__(title, parent=parent)
        self.player = player
        self._turn = False
        self.player.set_box(self)
        self.setStyleSheet(self.offsheet)
        self._setupUi()

    def _setupUi(self):
        """Create UI elements."""
        self.vbox = QVBoxLayout()
        self.vbox.setObjectName(self.player.title + "BoxVertLayout")
        self.grid = QGridLayout()
        self.grid.setObjectName(self.player.title + "BoxCardPicsLayout")
        self.hbox = QHBoxLayout()
        self.hbox.setObjectName(self.player.title + "BoxHorizLayout")
        self.vbox.addLayout(self.hbox)
        self.vbox.addLayout(self.grid)
        self.setLayout(self.vbox)
        self._setupLabels()
        self._setupCards()

    def _setupLabels(self):
        """Set up window labels."""
        expolicy = QSizePolicy.Policy.MinimumExpanding
        minpolicy = QSizePolicy.Policy.Minimum
        self.label = QLabel("Score: ")
        self.label.setObjectName("ScoreLabel")
        self.label.setStyleSheet(self.labelsheet)
        self.hbox.addWidget(self.label)
        self.hbox.addSpacerItem(QSpacerItem(10, 0, minpolicy, minpolicy))
        self.scorelabel = QLabel("0")
        self.scorelabel.setObjectName("ScoreValue")
        self.scorelabel.setStyleSheet(self.scoresheet)
        self.hbox.addWidget(self.scorelabel)
        self.hbox.addSpacerItem(QSpacerItem(50, 0, expolicy, minpolicy))

    def _setupCards(self):
        """Create card covers."""
        card = CardWidget(parent=self)
        card.setObjectName("Card1")
        self.addCard(card)
        self.grid.addWidget(card, 0, 0, -1, -1)
        card2 = CardWidget(parent=self)
        card2.setObjectName(self.player.title + "Card2")
        self.addCard(card2)
        self.grid.addWidget(card2, 0, 1, -1, -1)

    @property
    def cardCount(self):
        """Count cards in players hand.

        Returns:
            int: Total number of cards in players hand.
        """
        return len(self.player.cards)

    @property
    def cards(self):
        """Shortcut method accessing players cards property.

        Returns:
            list: List of card widgets.
        """
        return self.player.cards

    def addCard(self, card):
        """Shortcut for adding card widget to players list of cards.

        Args:
            card (obj): CardWidget object.
        """
        self.player.cards.append(card)

    def deleteCard(self, card):
        """Remove card from Players list of cards property."""
        if card in self.player.cards:
            self.player.cards.remove(card)

    def reset(self):
        """Clear PlayerBox of all widgets.

        Called when current round ends and new deal begins.
        """
        while len(self.cards) > 0:
            card = self.cards[0]
            self.grid.removeWidget(card)
            card.setVisible(False)
            card.hide()
            card.destroy(True, True)
            self.deleteCard(card)
            del card
            self.repaint()
            self.update()

    def addWidget(self, card):
        """Add another card to Window.

        Args:
            card (obj): Card object from deck.

        Returns:
            bool: True if successful else None
        """
        if self.cardCount <= 2:
            for widget in self.cards:
                if not widget.has_card():
                    return widget.setCard(card)
        widget = CardWidget(card=card)
        widget.setObjectName("Card" + str(self.cardCount))
        self.grid.addWidget(widget, 0, self.cardCount, -1, -1)
        return self.addCard(widget)

    def isTurn(self):
        """Return True if currently players turn.

        Returns:
            bool: True if it's players turn else false.
        """
        return self._turn

    def turn(self):
        """Flip `self.turn` property False or True.

        Changes the style of PlayerBox to indicate if it
        is or isn't currently players turn.
        """
        if self.isTurn():
            self._turn = False
            self.setStyleSheet(self.offsheet)
        else:
            self._turn = True
            self.setStyleSheet(self.onsheet)
Beispiel #18
0
class InfoDialog(QDialog):
    """文件信息对话框"""
    get_dl_link = pyqtSignal(str, str)
    closed = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.infos = None
        self._short_link_flag = True  # 防止多次重试
        self.initUI()
        self.setStyleSheet(dialog_qss_style)

    def update_ui(self):
        self.tx_dl_link.setPlaceholderText("单击获取")
        self.tx_name.setText(self.infos.name)
        if self.infos.is_file:
            self.setWindowTitle("文件信息")
            self.lb_name.setText("文件名:")
            self.lb_desc.setText("文件描述:")
            self.tx_dl_link.setText("")  # 清空旧的信息
            self.lb_dl_link.setVisible(True)
            self.tx_dl_link.setVisible(True)
        else:
            self.setWindowTitle("文件夹信息")
            self.lb_name.setText("文件夹名:")
            self.lb_desc.setText("文件夹描述:")
            self.lb_dl_link.setVisible(False)
            self.tx_dl_link.setVisible(False)

        if self.infos.size:
            self.tx_size.setText(self.infos.size)
            self.lb_size.setVisible(True)
            self.tx_size.setVisible(True)
        else:
            self.tx_size.setVisible(False)
            self.lb_size.setVisible(False)

        if self.infos.time:
            self.lb_time.setVisible(True)
            self.tx_time.setVisible(True)
            self.tx_time.setText(self.infos.time)
        else:
            self.lb_time.setVisible(False)
            self.tx_time.setVisible(False)

        if self.infos.downs:
            self.lb_dl_count.setVisible(True)
            self.tx_dl_count.setVisible(True)
            self.tx_dl_count.setText(str(self.infos.downs))
        else:
            self.tx_dl_count.setVisible(False)
            self.lb_dl_count.setVisible(False)

        if self.infos.pwd:
            self.tx_pwd.setText(self.infos.pwd)
            self.tx_pwd.setPlaceholderText("")
        else:
            self.tx_pwd.setText("")
            self.tx_pwd.setPlaceholderText("无")

        if self.infos.desc:
            self.tx_desc.setText(self.infos.desc)
            self.tx_desc.setPlaceholderText("")
        else:
            self.tx_desc.setText("")
            self.tx_desc.setPlaceholderText("无")

        self.tx_share_url.setText(self.infos.url)
        self.adjustSize()

    def set_values(self, infos):
        self.infos = infos
        self.update_ui()

    def set_dl_link_tx(self, text):
        self.tx_dl_link.setText(text)
        self.adjustSize()

    def call_get_dl_link(self):
        url = self.tx_share_url.text()
        pwd = self.tx_pwd.text()
        self.get_dl_link.emit(url, pwd)
        self.tx_dl_link.setPlaceholderText("后台获取中,请稍候!")

    def call_get_short_url(self):
        if self._short_link_flag:
            self._short_link_flag = False
            self.tx_short.setPlaceholderText("后台获取中,请稍候!")
            url = self.tx_share_url.text()
            from lanzou.api.extra import get_short_url

            short_url = get_short_url(url)
            if short_url:
                self.tx_short.setText(short_url)
                self.tx_short.setPlaceholderText("")
                self._short_link_flag = True
            else:
                self.tx_short.setText("")
                self.tx_short.setPlaceholderText("生成失败!api 可能已经失效")

    def clean(self):
        self._short_link_flag = True
        self.tx_short.setText("")
        self.tx_short.setPlaceholderText("单击获取")

    def initUI(self):
        self.setWindowIcon(QIcon(SRC_DIR + "share.ico"))
        self.setWindowTitle("文件信息")
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Close)
        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setText("关闭")
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.rejected.connect(self.clean)
        self.buttonBox.rejected.connect(self.closed.emit)

        self.logo = QLabel()
        self.logo.setPixmap(QPixmap(SRC_DIR + "q9.gif"))
        self.logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.logo.setStyleSheet("background-color:rgb(255,204,51);")

        self.lb_name = QLabel()
        self.lb_name.setText("文件名:")
        self.tx_name = AutoResizingTextEdit()
        self.tx_name.setReadOnly(True)
        self.tx_name.setMinimumLines(1)

        self.lb_size = QLabel()
        self.lb_size.setText("文件大小:")
        self.tx_size = QLabel()

        self.lb_time = QLabel()
        self.lb_time.setText("上传时间:")
        self.tx_time = QLabel()

        self.lb_dl_count = QLabel()
        self.lb_dl_count.setText("下载次数:")
        self.tx_dl_count = QLabel()

        self.lb_share_url = QLabel()
        self.lb_share_url.setText("分享链接:")
        self.tx_share_url = QLineEdit()
        self.tx_share_url.setReadOnly(True)

        self.lb_pwd = QLabel()
        self.lb_pwd.setText("提取码:")
        self.tx_pwd = QLineEdit()
        self.tx_pwd.setReadOnly(True)

        self.lb_short = QLabel()
        self.lb_short.setText("短链接:")
        self.tx_short = AutoResizingTextEdit(self)
        self.tx_short.setPlaceholderText("单击获取")
        self.tx_short.clicked.connect(self.call_get_short_url)
        self.tx_short.setReadOnly(True)
        self.tx_short.setMinimumLines(1)

        self.lb_desc = QLabel()
        self.lb_desc.setText("文件描述:")
        self.tx_desc = AutoResizingTextEdit()
        self.tx_desc.setReadOnly(True)
        self.tx_desc.setMinimumLines(1)

        self.lb_dl_link = QLabel()
        self.lb_dl_link.setText("下载直链:")
        self.tx_dl_link = AutoResizingTextEdit(self)
        self.tx_dl_link.setPlaceholderText("单击获取")
        self.tx_dl_link.clicked.connect(self.call_get_dl_link)
        self.tx_dl_link.setReadOnly(True)
        self.tx_dl_link.setMinimumLines(1)

        vbox = QVBoxLayout()
        vbox.addWidget(self.logo)
        vbox.addStretch(1)
        form = QFormLayout()
        form.setLabelAlignment(Qt.AlignmentFlag.AlignRight)
        form.addRow(self.lb_name, self.tx_name)
        form.addRow(self.lb_size, self.tx_size)
        form.addRow(self.lb_time, self.tx_time)
        form.addRow(self.lb_dl_count, self.tx_dl_count)
        form.addRow(self.lb_share_url, self.tx_share_url)
        form.addRow(self.lb_pwd, self.tx_pwd)
        form.addRow(self.lb_short, self.tx_short)
        form.addRow(self.lb_desc, self.tx_desc)
        form.addRow(self.lb_dl_link, self.tx_dl_link)
        form.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)  # 覆盖MacOS的默认样式
        vbox.addLayout(form)
        vbox.addStretch(1)
        vbox.addWidget(self.buttonBox)

        self.setLayout(vbox)
        self.setMinimumWidth(500)
Beispiel #19
0
class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.width = 500
        self.height = 500
        self.xPos = 600
        self.yPos = 400
        self.initUI()

    def initUI(self):
        self.setGeometry(self.xPos, self.yPos, self.width, self.height)
        self.vBoxLayout = QVBoxLayout()

        self.slider = Slider(
            direction=Qt.Orientation.Horizontal,
            duration=750,
            animationType=QEasingCurve.Type.OutQuad,
            wrap=False,
        )

        self.label1 = QLabel()
        self.label1.setText('First Slide')
        self.label1.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label1.setStyleSheet(
            'QLabel{background-color: rgb(245, 177, 66); color: rgb(21, 21, 21); font: 25pt;}'
        )
        self.slider.addWidget(self.label1)

        self.label2 = QLabel()
        self.label2.setText('Second Slide')
        self.label2.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label2.setStyleSheet(
            'QLabel{background-color: rgb(21, 21, 21); color: rgb(245, 177, 66); font: 25pt;}'
        )
        self.slider.addWidget(self.label2)

        self.label3 = QLabel()
        self.label3.setText('Third Slide')
        self.label3.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label3.setStyleSheet(
            'QLabel{background-color: rgb(93, 132, 48); color: rgb(245, 177, 66); font: 25pt;}'
        )
        self.slider.addWidget(self.label3)

        self.buttonPrevious = QPushButton()
        self.buttonPrevious.setText('Previous Slide')
        self.buttonPrevious.clicked.connect(self.slider.slidePrevious)

        self.buttonNext = QPushButton()
        self.buttonNext.setText('Next Slide')
        self.buttonNext.clicked.connect(self.slider.slideNext)

        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.addWidget(self.buttonPrevious)
        self.buttonLayout.addWidget(self.buttonNext)

        self.vBoxLayout.addWidget(self.slider)
        self.vBoxLayout.addLayout(self.buttonLayout)

        self.centralWidget = QWidget(self)
        self.centralWidget.setLayout(self.vBoxLayout)
        self.setCentralWidget(self.centralWidget)

        self.show()
Beispiel #20
0
class UploadDialog(QDialog):
    """文件上传对话框"""
    new_infos = pyqtSignal(object)

    def __init__(self, user_home):
        super().__init__()
        self.cwd = user_home
        self._folder_id = -1
        self._folder_name = "LanZouCloud"
        self.set_pwd = False
        self.set_desc = False
        self.pwd = ''
        self.desc = ''
        self.allow_big_file = False
        self.max_size = 100
        self.selected = []
        self.initUI()
        self.set_size()
        self.setStyleSheet(dialog_qss_style)

    def set_pwd_desc_bigfile(self, settings):
        self.set_pwd = settings["set_pwd"]
        self.set_desc = settings["set_desc"]
        self.pwd = settings["pwd"]
        self.desc = settings["desc"]
        self.allow_big_file = settings["allow_big_file"]
        self.max_size = settings["max_size"]
        if self.allow_big_file:
            self.btn_chooseMultiFile.setToolTip("")
        else:
            self.btn_chooseMultiFile.setToolTip(f"文件大小上限 {self.max_size}MB")

    def set_values(self, folder_name, folder_id, files):
        self.setWindowTitle("上传文件至 ➩ " + str(folder_name))
        self._folder_id = folder_id
        self._folder_name = folder_name
        if files:
            self.selected = files
            self.show_selected()
        self.exec()

    def initUI(self):
        self.setWindowTitle("上传文件")
        self.setWindowIcon(QIcon(SRC_DIR + "upload.ico"))
        self.logo = QLabel()
        self.logo.setPixmap(QPixmap(SRC_DIR + "logo3.gif"))
        self.logo.setStyleSheet("background-color:rgb(0,153,255);")
        self.logo.setAlignment(Qt.AlignmentFlag.AlignCenter)

        # btn 1
        self.btn_chooseDir = QPushButton("选择文件夹", self)
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setIcon(QIcon(SRC_DIR + "folder.gif"))

        # btn 2
        self.btn_chooseMultiFile = QPushButton("选择多文件", self)
        self.btn_chooseDir.setObjectName("btn_chooseMultiFile")
        self.btn_chooseMultiFile.setObjectName("btn_chooseMultiFile")
        self.btn_chooseMultiFile.setIcon(QIcon(SRC_DIR + "file.ico"))

        # btn 3
        self.btn_deleteSelect = QPushButton("移除", self)
        self.btn_deleteSelect.setObjectName("btn_deleteSelect")
        self.btn_deleteSelect.setIcon(QIcon(SRC_DIR + "delete.ico"))
        self.btn_deleteSelect.setToolTip("按 Delete 移除选中文件")

        # 列表
        self.list_view = MyListView()
        self.list_view.drop_files.connect(self.add_drop_files)
        self.list_view.setViewMode(QListView.ViewMode.ListMode)
        self.slm = QStandardItem()
        self.model = QStandardItemModel()
        self.list_view.setModel(self.model)
        self.model.removeRows(0, self.model.rowCount())  # 清除旧的选择
        self.list_view.setEditTriggers(
            QAbstractItemView.EditTrigger.NoEditTriggers)
        self.list_view.setSelectionBehavior(
            QAbstractItemView.SelectionBehavior.SelectRows)
        self.list_view.setSelectionMode(
            QAbstractItemView.SelectionMode.ExtendedSelection)

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.StandardButton.Ok
            | QDialogButtonBox.StandardButton.Cancel)
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText("确定")
        self.buttonBox.button(
            QDialogButtonBox.StandardButton.Cancel).setText("取消")

        vbox = QVBoxLayout()
        hbox_head = QHBoxLayout()
        hbox_button = QHBoxLayout()
        hbox_head.addWidget(self.btn_chooseDir)
        hbox_head.addStretch(1)
        hbox_head.addWidget(self.btn_chooseMultiFile)
        hbox_button.addWidget(self.btn_deleteSelect)
        hbox_button.addStretch(1)
        hbox_button.addWidget(self.buttonBox)
        vbox.addWidget(self.logo)
        vbox.addLayout(hbox_head)
        vbox.addWidget(self.list_view)
        vbox.addLayout(hbox_button)
        self.setLayout(vbox)
        self.setMinimumWidth(350)

        # 设置信号
        self.btn_chooseDir.clicked.connect(self.slot_btn_chooseDir)
        self.btn_chooseMultiFile.clicked.connect(self.slot_btn_chooseMultiFile)
        self.btn_deleteSelect.clicked.connect(self.slot_btn_deleteSelect)

        self.buttonBox.accepted.connect(self.slot_btn_ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.clear_old)
        self.buttonBox.rejected.connect(self.reject)

    def set_size(self):
        if self.selected:
            h = 18 if len(self.selected) > 18 else 10
            w = 40
            for i in self.selected:
                i_len = len(i)
                if i_len > 100:
                    w = 100
                    break
                if i_len > w:
                    w = i_len
            self.resize(120 + w * 7, h * 30)
        else:
            self.resize(400, 300)

    def clear_old(self):
        self.selected = []
        self.model.removeRows(0, self.model.rowCount())
        self.set_size()

    def show_selected(self):
        self.model.removeRows(0, self.model.rowCount())
        for item in self.selected:
            if os.path.isfile(item):
                self.model.appendRow(
                    QStandardItem(QIcon(SRC_DIR + "file.ico"), item))
            else:
                self.model.appendRow(
                    QStandardItem(QIcon(SRC_DIR + "folder.gif"), item))
            self.set_size()

    def backslash(self):
        """Windows backslash"""
        tasks = {}
        for item in self.selected:
            url = os.path.normpath(item)
            total_size = 0
            total_file = 0
            if os.path.isfile(url):
                total_size = os.path.getsize(url)
                if not total_size:
                    continue  # 空文件无法上传
                total_file += 1
            else:
                for filename in os.listdir(url):
                    file_path = os.path.join(url, filename)
                    if not os.path.isfile(file_path):
                        continue  # 跳过子文件夹
                    total_size += os.path.getsize(file_path)
                    total_file += 1
            tasks[url] = UpJob(url=url,
                               fid=self._folder_id,
                               folder=self._folder_name,
                               pwd=self.pwd if self.set_pwd else None,
                               desc=self.desc if self.set_desc else None,
                               total_size=total_size,
                               total_file=total_file)
        return tasks

    def slot_btn_ok(self):
        tasks = self.backslash()
        if self.selected:
            self.new_infos.emit(tasks)
            self.clear_old()

    def slot_btn_deleteSelect(self):
        _indexes = self.list_view.selectionModel().selection().indexes()
        if not _indexes:
            return
        indexes = []
        for i in _indexes:  # 获取所选行号
            indexes.append(i.row())
        indexes = set(indexes)
        for i in sorted(indexes, reverse=True):
            self.selected.remove(self.model.item(i, 0).text())
            self.model.removeRow(i)
        self.set_size()

    def add_drop_files(self, files):
        for item in files:
            if item not in self.selected:
                self.selected.append(item)
            self.show_selected()

    def slot_btn_chooseDir(self):
        dir_choose = QFileDialog.getExistingDirectory(self, "选择文件夹",
                                                      self.cwd)  # 起始路径
        if dir_choose == "":
            return
        if dir_choose not in self.selected:
            self.selected.append(dir_choose)
            self.cwd = os.path.dirname(dir_choose)
        self.show_selected()

    def slot_btn_chooseMultiFile(self):
        files, _ = QFileDialog.getOpenFileNames(self, "选择多文件", self.cwd,
                                                "All Files (*)")
        if len(files) == 0:
            return
        for _file in files:
            if _file not in self.selected:
                if os.path.getsize(_file) <= self.max_size * 1048576:
                    self.selected.append(_file)
                elif self.allow_big_file:
                    self.selected.append(_file)
        self.show_selected()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key.Key_Delete:  # delete
            self.slot_btn_deleteSelect()