Ejemplo n.º 1
0
class SVGButton(QPushButton):
    def __init__(self, text=None):
        super(SVGButton, self).__init__(text)

        self.layout = QHBoxLayout()
        self.setLayout(self.layout)

        self.svg = QSvgWidget("./assets/loading.svg", self)
        self.svg.setVisible(False)

        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.svg)

    def setEnabled(self, enabled):
        super().setEnabled(enabled)
        self.svg.setVisible(not enabled)
Ejemplo n.º 2
0
class ScrollWindow(QScrollArea):
    def __init__(self, *args, **kwargs):
        super(ScrollWindow, self).__init__(*args, **kwargs)
        # self.setAcceptDrops(True)  # 2
        self.resize(800, 600)
        self.setFrameShape(self.NoFrame)
        self.setWidgetResizable(True)
        self.setAlignment(Qt.AlignCenter)
        self._loadStart = False
        # 网格窗口
        self._widget = GridWidget(self)
        self._widget.loadStarted.connect(self.setLoadStarted)
        self.setWidget(self._widget)
        ####################################################
        # 连接竖着的滚动条滚动事件
        # self.verticalScrollBar().actionTriggered.connect(self.onActionTriggered)
        ####################################################
        # 进度条
        self.loadWidget = QSvgWidget(self,
                                     minimumHeight=180,
                                     minimumWidth=180,
                                     visible=False)
        self.loadWidget.load(Svg_icon_loading)

    def setLoadStarted(self, started):
        self._loadStart = started
        self.loadWidget.setVisible(started)

    def onActionTriggered(self, action):
        # 这里要判断action=QAbstractSlider.SliderMove,可以避免窗口大小改变的问题
        # 同时防止多次加载同一个url
        if action != QAbstractSlider.SliderMove or self._loadStart:
            return
        # 使用sliderPosition获取值可以同时满足鼠标滑动和拖动判断
        if self.verticalScrollBar().sliderPosition() == self.verticalScrollBar(
        ).maximum():
            # 可以下一页了
            self._widget.load()

    def resizeEvent(self, event):
        super(ScrollWindow, self).resizeEvent(event)
        self.loadWidget.setGeometry(
            int((self.width() - self.loadWidget.minimumWidth()) / 2),
            int((self.height() - self.loadWidget.minimumHeight()) / 2),
            self.loadWidget.minimumWidth(), self.loadWidget.minimumHeight())
Ejemplo n.º 3
0
class Window(QListWidget):
    Page = 0

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        self.resize(800, 600)
        self.setFrameShape(self.NoFrame)  # 无边框
        self.setFlow(self.LeftToRight)  # 从左到右
        self.setWrapping(True)  # 这三个组合可以达到和FlowLayout一样的效果
        self.setResizeMode(self.Adjust)

        self._loadStart = False
        # 连接竖着的滚动条滚动事件
        self.verticalScrollBar().actionTriggered.connect(
            self.onActionTriggered)
        # 进度条
        self.loadWidget = QSvgWidget(self,
                                     minimumHeight=120,
                                     minimumWidth=120,
                                     visible=False)
        self.loadWidget.load(Svg_icon_loading)

        # 异步网络下载管理器
        self._manager = QNetworkAccessManager(self)
        self._manager.finished.connect(self.onFinished)

    def load(self):
        if self.Page == -1:
            return
        self._loadStart = True
        self.loadWidget.setVisible(True)
        # 延迟一秒后调用目的在于显示进度条
        QTimer.singleShot(1000, self._load)

    def _load(self):
        print("load url:", Url.format(self.Page * 30))
        url = QUrl(Url.format(self.Page * 30))
        self._manager.get(QNetworkRequest(url))

    def onFinished(self, reply):
        # 请求完成后会调用该函数
        req = reply.request()  # 获取请求
        iwidget = req.attribute(QNetworkRequest.User + 1, None)
        path = req.attribute(QNetworkRequest.User + 2, None)
        html = reply.readAll().data()
        reply.deleteLater()
        del reply
        if iwidget and path and html:
            # 这里是图片下载完毕
            open(path, "wb").write(html)
            iwidget.setCover(path)
            return
        # 解析网页
        self._parseHtml(html)
        self._loadStart = False
        self.loadWidget.setVisible(False)

    def _parseHtml(self, html):
        #         encoding = chardet.detect(html) or {}
        #         html = html.decode(encoding.get("encoding","utf-8"))
        html = HTML(html)
        # 查找所有的li list_item
        lis = html.xpath("//li[@class='list_item']")
        if not lis:
            self.Page = -1  # 后面没有页面了
            return
        self.Page += 1
        self._makeItem(lis)

    def _makeItem(self, lis):
        for li in lis:
            a = li.find("a")
            video_url = a.get("href")  # 视频播放地址
            img = a.find("img")
            cover_url = "http:" + img.get("r-lazyload")  # 封面图片
            figure_title = img.get("alt")  # 电影名
            figure_info = a.find("div/span")
            figure_info = "" if figure_info is None else figure_info.text  # 影片信息
            figure_score = "".join(li.xpath(".//em/text()"))  # 评分
            # 主演
            figure_desc = "<span style=\"font-size: 12px;\">主演:</span>" + \
                          "".join([Actor.format(**dict(fd.items()))
                                   for fd in li.xpath(".//div[@class='figure_desc']/a")])
            # 播放数
            figure_count = (
                li.xpath(".//div[@class='figure_count']/span/text()")
                or [""])[0]
            path = "cache/{0}.jpg".format(
                os.path.splitext(os.path.basename(video_url))[0])
            cover_path = "Data/pic_v.png"
            if os.path.isfile(path):
                cover_path = path
            iwidget = ItemWidget(cover_path, figure_info, figure_title,
                                 figure_score, figure_desc, figure_count,
                                 video_url, cover_url, path, self._manager,
                                 self)
            item = QListWidgetItem(self)
            item.setSizeHint(iwidget.sizeHint())
            self.setItemWidget(item, iwidget)

    def onActionTriggered(self, action):
        # 这里要判断action=QAbstractSlider.SliderMove,可以避免窗口大小改变的问题
        # 同时防止多次加载同一个url
        if action != QAbstractSlider.SliderMove or self._loadStart:
            return
        # 使用sliderPosition获取值可以同时满足鼠标滑动和拖动判断
        if self.verticalScrollBar().sliderPosition() == self.verticalScrollBar(
        ).maximum():
            # 可以下一页了
            self.load()

    def resizeEvent(self, event):
        super(Window, self).resizeEvent(event)
        self.loadWidget.setGeometry(
            int((self.width() - self.loadWidget.minimumWidth()) / 2),
            int((self.height() - self.loadWidget.minimumHeight()) / 2),
            self.loadWidget.minimumWidth(), self.loadWidget.minimumHeight())
Ejemplo n.º 4
0
class GUI(QMainWindow):
    def __init__(self, app, bot, stream):
        # app
        super(GUI, self).__init__()
        QDir.setCurrent(bundle_dir)
        self.app = app

        # window info
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
        window_icon = QIcon('./assets/favicon.ico')
        self.setWindowTitle('Discord Audio Pipe')
        self.app.setWindowIcon(window_icon)
        self.position = None

        # discord
        self.bot = bot
        self.voice = None
        self.stream = stream

        # layout
        central = QWidget()
        layout = QGridLayout()
        central.setLayout(layout)

        # loading
        self.info = QLabel('Connecting...')
        self.loading = QSvgWidget('./assets/loading.svg')

        # devices
        self.devices = QComboBox(self)
        self.devices.setItemDelegate(QStyledItemDelegate())
        self.devices.setPlaceholderText('None')
        device_lb = QLabel('Devices')
        device_lb.setObjectName('label')

        for device, idx in sound.query_devices().items():
            self.devices.addItem(device + '   ', idx)

        # servers
        self.servers = QComboBox(self)
        self.servers.setItemDelegate(QStyledItemDelegate())
        self.servers.setPlaceholderText('None')
        server_lb = QLabel('Servers     ')
        server_lb.setObjectName('label')

        # channels
        self.channels = QComboBox(self)
        self.channels.setItemDelegate(QStyledItemDelegate())
        self.channels.setPlaceholderText('None')
        channel_lb = QLabel('Channels  ')
        channel_lb.setObjectName('label')

        # mute
        self.mute = QPushButton('Mute', self)
        self.mute.setObjectName('mute')

        # add widgets
        layout.addWidget(self.info, 0, 0, 1, 3)
        layout.addWidget(self.loading, 0, 3, alignment=Qt.AlignHCenter)
        layout.addWidget(device_lb, 1, 0)
        layout.addWidget(self.devices, 2, 0)
        layout.addWidget(server_lb, 1, 1)
        layout.addWidget(self.servers, 2, 1)
        layout.addWidget(channel_lb, 1, 2)
        layout.addWidget(self.channels, 2, 2)
        layout.addWidget(self.mute, 2, 3)

        # events
        self.devices.currentTextChanged.connect(self.change_device)
        self.servers.currentTextChanged.connect(
            lambda: asyncio.ensure_future(self.change_server()))
        self.channels.currentTextChanged.connect(
            lambda: asyncio.ensure_future(self.change_channel()))
        self.mute.clicked.connect(self.toggle_mute)

        # build window
        titlebar = TitleBar(self)
        self.setMenuWidget(titlebar)
        self.setCentralWidget(central)
        self.disable_ui()

        # load styles
        QFontDatabase.addApplicationFont('./assets/Roboto-Black.ttf')
        with open('./assets/style.qss', 'r') as qss:
            self.app.setStyleSheet(qss.read())

        # show window
        self.show()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.position = event.pos()
            event.accept()

    def mouseMoveEvent(self, event):
        if self.position is not None and event.buttons() == Qt.LeftButton:
            self.move(self.pos() + event.pos() - self.position)
            event.accept()

    def mouseReleaseEvent(self, event):
        self.position = None
        event.accept()

    def disable_ui(self):
        self.loading.setVisible(True)
        self.devices.setEnabled(False)
        self.servers.setEnabled(False)
        self.channels.setEnabled(False)
        self.mute.setEnabled(False)

    def enable_ui(self):
        self.loading.setVisible(False)
        self.devices.setEnabled(True)
        self.servers.setEnabled(True)
        self.channels.setEnabled(True)
        self.mute.setEnabled(True)

    async def run_Qt(self, interval=0.01):
        while True:
            QCoreApplication.processEvents(QEventLoop.AllEvents,
                                           interval * 1000)
            await asyncio.sleep(interval)

    def resize_combobox(self, combobox):
        font = combobox.property('font')
        metrics = QFontMetrics(font)
        min_width = 0

        for i in range(combobox.count()):
            size = metrics.horizontalAdvance(combobox.itemText(i))
            if size > min_width:
                min_width = size

        combobox.setMinimumWidth(min_width + 30)

    async def ready(self):
        await self.bot.wait_until_ready()
        self.info.setText(f'Logged in as: {self.bot.user.name}')

        for guild in self.bot.guilds:
            self.servers.addItem(guild.name, guild)

        self.resize_combobox(self.servers)
        self.enable_ui()

    def change_device(self):
        try:
            selection = self.devices.currentData()
            self.mute.setText('Mute')

            if self.voice is not None:
                self.voice.stop()
                self.stream.change_device(selection)

                if self.voice.is_connected():
                    self.voice.play(discord.PCMAudio(self.stream))

            else:
                self.stream.change_device(selection)

        except Exception:
            logging.exception('Error on change_device')

    async def change_server(self):
        try:
            selection = self.servers.currentData()
            self.channels.clear()
            self.channels.addItem('None', None)

            for channel in selection.channels:
                if isinstance(channel, discord.VoiceChannel):
                    self.channels.addItem(channel.name, channel)

            self.resize_combobox(self.channels)

        except Exception:
            logging.exception('Error on change_server')

    async def change_channel(self):
        try:
            selection = self.channels.currentData()
            self.mute.setText('Mute')
            self.disable_ui()

            if selection is not None:
                not_connected = (self.voice is None or self.voice is not None
                                 and not self.voice.is_connected())

                if not_connected:
                    self.voice = await selection.connect(timeout=10)
                else:
                    await self.voice.move_to(selection)

                not_playing = (self.devices.currentData() is not None
                               and not self.voice.is_playing())

                if not_playing:
                    self.voice.play(discord.PCMAudio(self.stream))

            else:
                if self.voice is not None:
                    await self.voice.disconnect()

        except Exception:
            logging.exception('Error on change_channel')

        finally:
            self.enable_ui()

    def toggle_mute(self):
        try:
            if self.voice is not None:
                if self.voice.is_playing():
                    self.voice.pause()
                    self.mute.setText('Resume')
                else:
                    self.voice.resume()
                    self.mute.setText('Mute')

        except Exception:
            logging.exception('Error on toggle_mute')
Ejemplo n.º 5
0
class MissevanKit(QMainWindow, Ui_mainWindow):
    def __init__(self, parent=None):
        super(MissevanKit, self).__init__(parent)
        self.setupUi(self)
        # self.set_style()
        self.center()
        self.setTab1()
        self.setTab2()
        self.setTab3()
        self.setTab4()
        self.gen_data_thread = None
        self.collect_thread = None
        self.tab_1_log = gen_date_filename(APP_LogPath, "数据采集日志.txt")
        self.tab_2_log = gen_date_filename(APP_LogPath, "数据处理日志.txt")

    # self.tabWidget.setCurrentIndex(0)

    def center(self):  # 实现窗体在屏幕中央
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()  # 同上
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 4)

    def setTab1(self):
        self.pushButton.clicked.connect(self.start_collect)
        self.pushButton_2.clicked.connect(lambda: self.collect_progress(STOP))
        self.pushButton_9.clicked.connect(self.set_choose_rect_brower)
        # self.pushButton_4.clicked.connect(lambda: self.set_browser_collapse(self.textBrowser_3))

    def gen_tab1_config(self):
        # worktime
        # 是否只是工作日抓取
        GLOBAL_CONFIG[ONLY_WORK_DAY] = False
        if self.checkBox.isChecked():
            GLOBAL_CONFIG[ONLY_WORK_DAY] = True
        if self.radioButton_5.isChecked():
            if self.textEdit.toPlainText():
                try:
                    GLOBAL_CONFIG[WORK_TIME] = [
                        int(i) for i in self.textEdit.toPlainText().split()
                    ]
                except:
                    self.echo_error('抓取的时间点输入格式不对,24小时制,用空格分隔')
                    return False
            else:
                self.echo_error('抓取的时间点(小时)为空,请检查')
                return False
        elif self.radioButton_4.isChecked():
            GLOBAL_CONFIG[WORK_TIME] = [i for i in range(24)]
        elif self.radioButton_3.isChecked():
            GLOBAL_CONFIG[WORK_TIME] = [i for i in range(7, 9)
                                        ] + [i for i in range(17, 19)]
        elif self.radioButton_2.isChecked():
            GLOBAL_CONFIG[WORK_TIME] = [i for i in range(17, 19)]
        elif self.radioButton.isChecked():
            GLOBAL_CONFIG[WORK_TIME] = [i for i in range(7, 9)]

        if self.textEdit_left.toPlainText():
            # 左下角换到左上角
            left_p = self.textEdit_left.toPlainText().split(',')
            right_p = self.textEdit_right.toPlainText().split(',')
            GLOBAL_CONFIG[LEFT_POINT] = [left_p[0], right_p[1]]
            GLOBAL_CONFIG[RIGHT_POINT] = [right_p[0], left_p[1]]
        else:
            self.echo_error('矩形区域为空,请检查')
            return False

        if self.textEdit_9.toPlainText():
            try:
                spacing_time = int(self.textEdit_9.toPlainText())
                if spacing_time < 0:
                    self.echo_error('间隔时间不能小于0,请重新输入')
                    return False
                GLOBAL_CONFIG[SPACING_TIME] = spacing_time
            except:
                self.echo_error('间隔时间输入错误,请检查')

        else:
            self.echo_error('间隔时间为空,请检查')
            return False
        return True

    def start_collect(self):
        if self.gen_tab1_config():
            write_to_log(self.tab_1_log, "程序开始运行...")
            write_to_log(self.tab_1_log, GLOBAL_CONFIG)
            # 初始化
            if self.collect_thread:
                self.collect_thread.terminate()
                self.collect_thread = None
            self.collect_thread = CollectThread()
            self.collect_thread.sinOut.connect(self.collect_progress)
            self.collect_thread.start()
            # 循环滚动
            self.progressBar.setMaximum(0)
            self.pushButton.setEnabled(False)
            self.pushButton_2.setEnabled(True)

    def collect_progress(self, flag):
        # 向列表控件中添加条目
        if flag == STOP:
            write_to_log(self.tab_1_log, "用户终止程序")
            self.collect_thread.terminate()
            GLOBAL_CONFIG[THREAD_FLAG] = False
            self.pushButton.setEnabled(True)
            self.pushButton_2.setEnabled(False)
            self.progressBar.setMaximum(100)
        elif flag == ERROR:
            write_to_log(self.tab_1_log, "系统发生错误,请检查")
            self.collect_thread.terminate()
            GLOBAL_CONFIG[THREAD_FLAG] = False
            self.pushButton.setEnabled(True)
            self.pushButton_2.setEnabled(False)

            self.progressBar.setMaximum(100)
        else:
            write_to_log(self.tab_1_log, flag)

    def set_date_time(self):
        # datetime = Qcommon_roadDateTime.currentDateTime()
        pass

    def set_choose_rect_brower(self):
        map_win = MapWindow(self)
        map_win.rectSignal.connect(self.getRect)
        map_win.exec_()

    def set_browser_collapse(self, browser):
        if browser.isVisible():
            browser.setVisible(False)
            browser.clear()
        else:
            browser.setVisible(True)

    def getRect(self, rect):
        if rect:
            leftb = rect.split(' ')[0]
            right = rect.split(' ')[1]

            self.textEdit_left.setText(leftb)
            self.textEdit_right.setText(right)

    def setTab2(self):
        self.pushButton_14.clicked.connect(self.start_gen_data)
        self.pushButton_7.clicked.connect(self.choose_data_dir)
        # self.pushButton_choose_road.clicked.connect(self.choose_road_dialog)
        self.pushButton_13.clicked.connect(
            lambda: self.gen_data_progress(STOP))
        # self.textEdit_red.selectionChanged.connect(self.change_green_threshold)

    def change_green_threshold(self):
        try:
            red = float(self.textEdit_red.toPlainText())
            yellow = float(self.textEdit_yellow.toPlainText())
            green = float(self.textEdit_green.toPlainText())
            if is_float(red) and is_float(yellow) and is_float(green):
                if not red > yellow > green:
                    self.echo_error("输入错误,拥堵比例关系应该是红点大于橙黄点大于黄色")
                    return False
                GLOBAL_CONFIG[RED_THRESHOLD] = red
                GLOBAL_CONFIG[YELLOW_THRESHOLD] = yellow
                GLOBAL_CONFIG[GREEN_THRESHOLD] = green
                return True
            else:
                self.echo_error("输入错误 ,需要为(0-1)的小数")
                return False

        except:
            self.echo_error("输入错误,需要为(0-1)的小数")
            return False

    def gen_tab2_config(self):
        if not self.change_green_threshold():
            return False

        if self.radioButton_9.isChecked():
            GLOBAL_CONFIG[GEN_ROAD_TYPE] = ALL_ROAD
        elif self.radioButton_10.isChecked():
            GLOBAL_CONFIG[GEN_ROAD_TYPE] = FAST_ROAD
        elif self.radioButton_11.isChecked():
            GLOBAL_CONFIG[GEN_ROAD_TYPE] = COMMON_ROAD
        data_dir = self.textEdit_7.toPlainText()
        if data_dir:
            flag = False
            for roots, dirs, files in os.walk(data_dir):
                for f in files:
                    if f.endswith('npz'):
                        flag = True
            if not flag:
                self.echo_error('数据所在路径中没有所需要的数据文件,请检查')
                return False
            if data_dir.endswith(os.sep):
                GLOBAL_CONFIG[DATA_DIR] = data_dir
            else:
                GLOBAL_CONFIG[DATA_DIR] = data_dir + os.sep
        else:
            self.echo_error('数据所在路径不能为空,请检查')
            return False

        return True

    def choose_road_dialog(self):
        road, ok = QInputDialog.getItem(self, "选择指定道路", "'全部'代表所有道路\n\n请选择道路:",
                                        ROAD_DATAS, 1, True)
        if ok:
            if road:
                self.textEdit_11.setText(road)
                if road == ROAD_DATAS[0]:
                    pass

    def start_gen_data(self):
        if self.gen_tab2_config():
            print(GLOBAL_CONFIG)
            write_to_log(self.tab_2_log, "程序开始运行...")
            write_to_log(self.tab_2_log, GLOBAL_CONFIG)
            self.pushButton_14.setEnabled(False)
            self.pushButton_13.setEnabled(True)
            if self.gen_data_thread:
                self.gen_data_thread.terminate()
                self.gen_data_thread = None
            self.progressBar_3.setValue(0)
            self.gen_data_thread = GenDataThread()
            self.gen_data_thread.sinOut.connect(self.gen_data_progress)
            self.gen_data_thread.start()

    def gen_data_progress(self, flag):
        if flag == STOP:
            write_to_log(self.tab_2_log, "用户终止程序")
            self.gen_data_thread.terminate()
            GLOBAL_CONFIG[THREAD_FLAG] = False
            self.pushButton_14.setEnabled(True)
            self.pushButton_13.setEnabled(False)

            self.progressBar_3.setValue(0)

        elif flag == ERROR:
            write_to_log(self.tab_2_log, "系统崩溃,请查明原因")
            self.echo("系统崩溃,请查明原因")
            self.gen_data_thread.terminate()
            GLOBAL_CONFIG[THREAD_FLAG] = False
            self.pushButton_14.setEnabled(True)
            self.pushButton_13.setEnabled(False)
            self.progressBar_3.setValue(0)

        elif flag == SUCCESS:
            write_to_log(self.tab_2_log, "数据生成完成,可进入识别或评价标签进行处理")
            self.echo("数据生成完成,可进入识别或评价标签进行处理")
            self.webview.reload()
            GLOBAL_CONFIG[THREAD_FLAG] = False
            self.pushButton_14.setEnabled(True)
            self.pushButton_13.setEnabled(False)

            self.progressBar_3.setValue(100)

        else:
            try:
                flag = int(flag)
                self.progressBar_3.setValue(flag)
            except:
                write_to_log(self.tab_2_log, flag)

    def choose_data_dir(self):
        dir = QFileDialog.getExistingDirectory(self, "选择数据文件夹", APP_DirPath)
        if dir:
            self.textEdit_7.setText(dir)

    def setTab3(self):
        self.setLoading()
        self.setBrower()

    def setLoading(self):
        self.loadWidget = QSvgWidget()
        self.loadWidget.setMaximumSize(QSize(60, 60))
        self.loadWidget.load(Svg_icon_loading)
        self.gridLayout_2.addWidget(self.loadWidget)
        self.loadWidget.setVisible(False)

    def setLoadStarted(self):
        self.loadWidget.setVisible(True)
        print('开始')

    def setLoadFinished(self, ):
        self.webview.setVisible(True)
        self.loadWidget.setVisible(False)

    def setBrower(self):
        self.webview = QWebEngineView()
        html_path = APP_HtmlPath + os.sep + "index.html"
        self.webview.load(QUrl.fromLocalFile(html_path))
        self.gridLayout_2.addWidget(self.webview)
        self.webview.setVisible(False)
        self.webview.page().loadStarted.connect(self.setLoadStarted)
        self.webview.page().loadFinished.connect(self.setLoadFinished)

    def setTab4(self):
        self.pushButton_16.clicked.connect(self.export_excel)
        self.pushButton_15.clicked.connect(self.gen_table)

    def gen_table(self):

        time_weight = self.textEdit_timeweight.toPlainText()
        if time_weight:
            time_weight = float(time_weight)
        else:
            self.echo_error('拥堵时长权重不能为空,请检查')
            return False
        length_weight = self.textEdit_lengthweight.toPlainText()
        if length_weight:
            length_weight = float(length_weight)
        else:
            self.echo_error('拥堵距离权重不能为空,请检查')
            return False
        # 表格处理要完全清除
        self.tableWidget.clear()
        self.tableWidget.setRowCount(0)
        self.tableWidget.setColumnCount(0)
        self.tableWidget.setSortingEnabled(True)
        self.tableWidget.horizontalHeader().setStyleSheet(
            "background-color: gray")
        self.tableWidget.setSelectionBehavior(1)
        self.tableWidget.horizontalHeader().setStretchLastSection(True)
        self.tableWidget.horizontalHeader().setSectionResizeMode(1)
        self.tableWidget.setShowGrid(True)

        file = open(JSON_FILE_PATH, 'r', encoding='utf-8')
        json_datas = json.load(file)
        time_max = max([float(x['jam_time']) for x in json_datas])
        length_max = max([float(x['distance']) for x in json_datas])
        json_datas.sort(
            key=lambda x: time_weight * float(x['jam_time']) / time_max +
            length_weight * float(x['distance']) / length_max,
            reverse=True)
        self.tableWidget.setColumnCount(len(TITLE_ROW))
        self.tableWidget.setRowCount(len(json_datas))
        self.tableWidget.setHorizontalHeaderLabels(TITLE_ROW)
        for row_index, json_data in enumerate(json_datas):
            no = json_data[JSON_NO]
            distance = json_data[JSON_DISTANCE]
            jam_time = json_data[JSON_JAM_TIME]
            start_point = json_data[JSON_START_POINT]
            start_place = json_data[JSON_START_PLACE]
            end_point = json_data[JSON_END_POINT]
            end_place = json_data[JSON_END_PLACE]
            # TODO
            date_type = json_data[JSON_DAY]
            jam_type = json_data[JSON_TYPE]
            if jam_type == 'red':
                color = '红色'
            elif jam_type == 'yellow':
                color = '橙黄'
            else:
                color = '黄色'
            if date_type == 'morning':
                day = '早高峰'
            else:
                day = '晚高峰'
            row_data = [
                no, day, start_place,
                str(start_point).replace('[', '').replace(']', ''), end_place,
                str(end_point).replace('[', '').replace(']', ''),
                float(distance), color, jam_time
            ]
            for col_index, item in enumerate(row_data):
                qitem = QTableWidgetItem()
                qitem.setTextAlignment(Qt.AlignCenter)
                # set data好,不然text排序只按字符串排
                qitem.setData(0, item)
                self.tableWidget.setItem(row_index, col_index, qitem)

    def export_excel(self):

        dir = QFileDialog.getExistingDirectory(self, "EXCEL文件保存到")
        if dir:
            file_path = gen_date_filename(dir, '-拥堵分析.xlsx')
            workbook = xw.Book()
            worksheet = workbook.sheets[0]
            rows = self.tableWidget.rowCount()
            cols = self.tableWidget.columnCount()
            rows_data = []
            for row in range(rows):
                row_data = []
                for col in range(cols):
                    data = self.tableWidget.item(row, col).text()
                    row_data.append(data)
                rows_data.append(row_data)
            worksheet.range('A1').value = EXCEL_TITLE_ROW
            worksheet.range('A2').value = rows_data
            workbook.save(file_path)
            workbook.close()
            self.echo(f"导出完成,EXCEL文件所在路径:\n{file_path}")
        else:
            self.echo_error("EXCEL文件存储路径不能为空")
            return False

    def echo(self, value):
        '''显示对话框返回值'''
        box = QMessageBox(self)
        box.information(self, "操作成功", "{}\n".format(value), QMessageBox.Ok)

    def echo_error(self, value):
        box = QMessageBox(self)
        box.warning(self, "错误", "{}\n".format(value), QMessageBox.Ok)
Ejemplo n.º 6
0
class PaneSelectItem(QWidget):
    pane_selected = pyqtSignal(QWidget)

    def __init__(self, icon_inactive_filename, icon_active_filename, icon_hover_filename, label_text=None, *args):
        super(PaneSelectItem, self).__init__(*args)
        self.setMouseTracking(True)
        self.setAutoFillBackground(True)
        self.active = False
        self.active_color = QColor(239, 0, 183)
        self.background_color = QColor(30, 30, 30)
        self.v_layout = QVBoxLayout()
        self.v_layout.addStretch()
        self.icon_layout = QHBoxLayout()
        self.icon_layout.addStretch()
        self.icon_inactive = QSvgWidget(icon_inactive_filename)
        self.set_icon_size(self.icon_inactive, 200, 43)
        self.icon_active = QSvgWidget(icon_active_filename)
        self.set_icon_size(self.icon_active, 200, 43)
        self.icon_active.setVisible(False)
        self.icon_hover = QSvgWidget(icon_hover_filename)
        self.set_icon_size(self.icon_hover, 200, 43)
        self.icon_hover.setVisible(False)
        self.icon_layout.addWidget(self.icon_inactive)
        self.icon_layout.addWidget(self.icon_active)
        self.icon_layout.addWidget(self.icon_hover)
        self.icon_layout.addStretch()
        self.v_layout.addLayout(self.icon_layout)
        if label_text is not None:
            self.label_layout = QHBoxLayout()
            self.label_layout.addStretch()
            self.label = QLabel()
            self.label.setStyleSheet("QLabel {color: #ffffff;}")
            self.label.setVisible(False)
            self.label.setText(label_text)
            self.label_layout.addWidget(self.label)
            self.label_layout.addStretch()
            self.v_layout.addLayout(self.label_layout)
        else:
            self.label = None
        self.v_layout.addStretch()
        self.setLayout(self.v_layout)

    @staticmethod
    def set_icon_size(svg_widget, width, height):
        svg_widget.setMaximumHeight(height)
        svg_widget.setMaximumWidth(width)
        svg_widget.setMinimumHeight(height)
        svg_widget.setMinimumWidth(width)

    def set_active(self, state):
        self.active = state
        self.icon_active.setVisible(self.active)
        if self.active:
            palette = self.palette()
            palette.setColor(self.backgroundRole(), self.active_color)
            self.setPalette(palette)
            if self.label is not None:
                self.label.setVisible(True)
                self.label.setStyleSheet("color: #000000;")
            self.icon_active.setVisible(True)
            self.icon_inactive.setVisible(False)
            self.icon_hover.setVisible(False)
        else:
            self.icon_inactive.setVisible(True)
            self.icon_hover.setVisible(False)
            self.icon_active.setVisible(False)
            palette = self.palette()
            palette.setColor(self.backgroundRole(), self.background_color)
            self.setPalette(palette)
            if self.label is not None:
                self.label.setVisible(False)
                self.label.setStyleSheet("QLabel {color: #ffffff;}")

    def enterEvent(self, event):
        if not self.active:
            self.icon_hover.setVisible(True)
            self.icon_inactive.setVisible(False)
            self.icon_active.setVisible(False)
        if self.label is not None:
            self.label.setVisible(True)

    def leaveEvent(self, event):
        if not self.active:
            self.icon_hover.setVisible(False)
            self.icon_inactive.setVisible(True)
            self.icon_active.setVisible(False)
        if self.label is not None:
            self.label.setVisible(self.active)

    def mousePressEvent(self, event):
        self.pane_selected.emit(self)