Esempio n. 1
0
class UI(QMainWindow):
    def __init__(self):
        super(UI, self).__init__()
        # -- 基础设置 -- #
        self.cp = QDesktopWidget().availableGeometry().center()
        qr = self.frameGeometry()
        qr.moveCenter(self.cp)
        self.move(qr.topLeft())
        self.resize(340, 150)
        self.setMinimumSize(340, 150)
        self.setMaximumSize(340, 150)
        self.setWindowTitle('pdf转长图助手')
        self.setWindowIcon(QIcon('tools.png'))
        # --字体设置--#
        # 字体8号
        self.font_8 = QFont()
        self.font_8.setPointSize(8)
        # 字体9号
        self.font_9 = QFont()
        self.font_9.setPointSize(9)

        # --菜单控件设置 -- #
        self.menubar = QMenuBar()  # 这里暂时不设置父类
        self.menubar.setFont(self.font_8)
        menu = self.menubar.addMenu('&菜单')
        self.menu_about = self.menubar.addMenu('&关于')
        self.action4 = QAction('版本号', self)
        self.action4.setFont(self.font_8)
        self.menu_about.addAction(self.action4)
        self.action4.triggered.connect(self.about_dialog)  # 菜单栏4触发器
        self.action1 = QAction('使用说明', self)
        self.action1.setFont(self.font_8)
        self.action2 = QAction('更新记录', self)
        self.action2.setFont(self.font_8)
        self.action3 = QAction('我要反馈', self)
        self.action3.setFont(self.font_8)
        menu.addAction(self.action1)
        menu.addAction(self.action2)
        menu.addAction(self.action3)

        # -- 菜单控制连接器
        self.action1.triggered.connect(self.notice_dialog)  # 菜单栏1触发器
        self.action2.triggered.connect(self.update_dialog)  # 菜单栏2触发器
        self.action3.triggered.connect(self.feedback_dialog)  # 菜单栏3触发器

        # -- 窗口1
        self.frame1 = None
        self.line_edit1_1 = None  # 窗口1的文件夹路径
        self.pdf_path = None  # 窗口1的pdf路径
        self.push_button1_1 = QPushButton()  # 按钮1_1,选择文件
        self.push_button1_2 = QPushButton()  # 按钮1_2,pdf转png
        self.push_button1_3 = QPushButton()  # 按钮1_3,我要退出

        # --窗口2
        self.frame2 = None
        self.line_edit2_1 = None  # 输入框
        self.pdf_dir1 = None  # pdf转成图片后的文件夹
        self.push_button2_1 = QPushButton()  # 按钮2_1:自定义路径
        self.push_button2_2 = QPushButton()  # 按钮2_2:一键长图
        self.push_button2_3 = QPushButton()  # 按钮2_3:自定义拼接

        # --窗口3
        self.frame3 = None
        self.pdf_dir2 = None
        self.line_edit3_1 = None  # 输入框
        self.combo_box3_1 = None  # 多选框3_1
        self.combo_box3_2 = None  # 多选框3_2
        self.line_edit3_2 = None  # 输入框百分比
        self.push_button3_1 = QPushButton()  # 自定义路径
        self.push_button3_2 = QPushButton()  # 一键压缩
        self.push_button3_3 = QPushButton()  # 退出软件

        # --- dialog会话 --
        self.dialog_line_edit1 = None  # 会话输入框1:拼接数量
        self.dialog_line_edit2 = None  # 会话输入框2:拼接列数
        self.dialog_line_edit3 = None  # 会话输入框3:拼接行数
        self.dialog_line_edit4 = None  # 会话输入框4:拼接间隙
        self.dialog_push_button1 = None  # 会话按钮1:开始单列拼接
        self.dialog_push_button2 = None  # 会话按钮1:开始矩阵拼接
        self.dialog1 = None  # 单列拼接
        self.dialog2 = None  # 矩阵拼接

        # --运行主界面--#
        self.init_ui()

    def init_ui(self):
        self.show_frame1()
        self.show()

    def show_frame1(self):
        self.frame1 = QWidget(self)
        super(QWidget, self.frame1).__init__()
        # --按钮标签1:格式转换,用来代替按钮1
        button_label1 = QLabel(self.frame1)
        button_label1.setGeometry(90, 0, 80, 24)
        button_label1.setFont(self.font_8)
        button_label1.setText('格式转换')
        button_label1.setAlignment(Qt.AlignCenter)
        # 转换按键
        # --按钮2:图片拼接
        push_button2 = QPushButton(self.frame1)
        push_button2.setGeometry(170, 0, 80, 24)
        push_button2.setFont(self.font_8)
        push_button2.setText('图片拼接')
        push_button2.clicked.connect(self.show_frame2)  # 连接件显示窗口2
        # --按钮3:图片压缩
        push_button3 = QPushButton(self.frame1)
        push_button3.setGeometry(250, 0, 80, 24)
        push_button3.setFont(self.font_8)
        push_button3.setText('图片压缩')
        push_button3.clicked.connect(self.show_frame3)  # 连接件显示窗口3

        # --标签1:pdf路径
        label1_1 = QLabel(self.frame1)
        label1_1.setText('pdf路径')
        label1_1.setFont(self.font_8)
        label1_1.setAlignment(Qt.AlignCenter)
        label1_1.setGeometry(15, 40, 69, 20)

        # --路径1:pdf路径
        self.line_edit1_1 = QLineEdit(self.frame1)
        self.line_edit1_1.setFont(self.font_8)
        self.line_edit1_1.setGeometry(90, 40, 220, 26)
        # 加入上次的路径保留
        pdf_path = self.read_data_dict('pdf_path')
        if pdf_path is not None:
            self.line_edit1_1.setText(pdf_path)

        # -- 按钮1_1:选择pdf文件
        self.push_button1_1 = QPushButton(self.frame1)
        self.push_button1_1.setGeometry(10, 95, 93, 29)
        self.push_button1_1.setText('选择文件')
        self.push_button1_1.setFont(self.font_9)
        # -- 按钮1_2:pdf转png
        self.push_button1_2 = QPushButton(self.frame1)
        self.push_button1_2.setGeometry(115, 95, 93, 29)
        self.push_button1_2.setText('pdf转png')
        self.push_button1_2.setFont(self.font_9)
        # -- 按钮1_3:我要退出
        self.push_button1_3 = QPushButton(self.frame1)
        self.push_button1_3.setGeometry(220, 95, 93, 29)
        self.push_button1_3.setText('退出软件')
        self.push_button1_3.setFont(self.font_9)

        # 移动其它控件
        self.menubar.setParent(self.frame1)  # 设置菜单栏依赖于窗口1
        self.setCentralWidget(self.frame1)  # 设置主窗口的当前窗口为窗口1
        self.frame1.setVisible(True)

    def show_frame2(self):
        # 重新定义构件
        self.frame2 = QWidget(self)
        super(QWidget, self.frame2).__init__()
        # --按钮1:格式转换
        push_button1 = QPushButton(self.frame2)
        push_button1.setGeometry(90, 0, 80, 24)
        push_button1.setFont(self.font_8)
        push_button1.setText('格式转换')
        push_button1.clicked.connect(self.show_frame1)

        # --按钮标签2:格式转换,用来代替按钮2
        button_label2 = QLabel(self.frame2)  # 暂时不设置父标签
        button_label2.setGeometry(170, 0, 80, 24)
        button_label2.setFont(self.font_8)
        button_label2.setText('图片拼接')
        button_label2.setAlignment(Qt.AlignCenter)
        # --按钮3:图片压缩
        push_button3 = QPushButton(self.frame2)
        push_button3.setGeometry(250, 0, 80, 24)
        push_button3.setFont(self.font_8)
        push_button3.setText('图片压缩')
        push_button3.clicked.connect(self.show_frame3)  # 连接件显示窗口3

        # -- 标签2_1:文件夹路径
        label2_1 = QLabel(self.frame2)
        label2_1.setGeometry(15, 40, 80, 20)
        label2_1.setText('文件夹路径')
        label2_1.setFont(self.font_8)

        # -- 输入框2_1:文件夹路径
        self.line_edit2_1 = QLineEdit(self.frame2)
        self.line_edit2_1.setGeometry(90, 40, 220, 26)
        self.line_edit2_1.setFont(self.font_8)

        # 加入默认路径
        pdf_path = self.read_data_dict('pdf_path')
        if pdf_path is not None:
            dir1 = path.split(pdf_path)[0]
            self.pdf_dir1 = dir1 + '/导出图片'
            self.line_edit2_1.setText(self.pdf_dir1)

        # -- 按钮2_1:自定义路径
        self.push_button2_1 = QPushButton(self.frame2)
        self.push_button2_1.setGeometry(10, 95, 93, 29)
        self.push_button2_1.setText('自定义路径')
        self.push_button2_1.setFont(self.font_9)
        # -- 按钮2_2:一键长图
        self.push_button2_2 = QPushButton(self.frame2)
        self.push_button2_2.setGeometry(115, 95, 93, 29)
        self.push_button2_2.setText('一键长图')
        self.push_button2_2.setFont(self.font_9)
        # -- 按钮2_3:自定义拼接
        self.push_button2_3 = QPushButton(self.frame2)
        self.push_button2_3.setGeometry(220, 95, 93, 29)
        self.push_button2_3.setText('自定义拼接')
        self.push_button2_3.setFont(self.font_9)
        self.push_button2_3.clicked.connect(self.show_dialog)
        # -- 移动其它控件
        self.menubar.setParent(self.frame2)  # 设置菜单栏依赖于窗口2
        self.setCentralWidget(self.frame2)
        self.frame2.setVisible(True)

    def show_frame3(self):
        self.frame3 = QWidget(self)
        super(QWidget, self.frame3).__init__()
        # --按钮1:格式转换
        push_button1 = QPushButton(self.frame3)
        push_button1.setGeometry(90, 0, 80, 24)
        push_button1.setFont(self.font_8)
        push_button1.setText('格式转换')
        push_button1.clicked.connect(self.show_frame1)

        # --按钮2:图片拼接
        push_button2 = QPushButton(self.frame3)
        push_button2.setGeometry(170, 0, 80, 24)
        push_button2.setFont(self.font_8)
        push_button2.setText('图片拼接')
        push_button2.clicked.connect(self.show_frame2)  # 连接件显示窗口2
        # -- 设置主窗口
        self.setCentralWidget(self.frame3)

        # -- 标签3:图片压缩
        button_label3 = QLabel(self.frame3)
        button_label3.setGeometry(250, 0, 80, 24)
        button_label3.setFont(self.font_8)
        button_label3.setText('图片压缩')
        button_label3.setAlignment(Qt.AlignCenter)
        # -- 标签3_1:文件夹路径
        label3_1 = QLabel(self.frame3)
        label3_1.setGeometry(15, 40, 80, 20)
        label3_1.setText('文件夹路径')
        label3_1.setFont(self.font_8)
        # -- 输入框3_1:文件夹路径
        self.line_edit3_1 = QLineEdit(self.frame3)
        self.line_edit3_1.setFont(self.font_8)
        self.line_edit3_1.setGeometry(90, 40, 220, 26)
        # 加入默认路径
        pdf_path = self.read_data_dict('pdf_path')
        if pdf_path is not None:
            dir1 = path.split(pdf_path)[0]
            self.pdf_dir2 = dir1 + '/单列长图'
            self.line_edit3_1.setText(self.pdf_dir2)
        # -- 标签3_2:宽度
        label3_2 = QLabel(self.frame3)
        label3_2.setGeometry(10, 80, 35, 20)
        label3_2.setText('宽度')
        label3_2.setFont(self.font_8)
        # -- 多选框3_1
        self.combo_box3_1 = QComboBox(self.frame3)
        self.combo_box3_1.setGeometry(45, 80, 60, 25)
        self.combo_box3_1.addItems(['普通', '720p', '1080p'])
        self.combo_box3_1.setFont(self.font_8)
        # -- 多选框3_2
        self.combo_box3_2 = QComboBox(self.frame3)
        self.combo_box3_2.setGeometry(155, 80, 50, 25)
        self.combo_box3_2.addItems(['jpg', 'png'])
        self.combo_box3_2.setFont(self.font_8)
        # -- 标签3_3
        label3_3 = QLabel(self.frame3)
        label3_3.setGeometry(120, 80, 40, 20)
        label3_3.setText('格式')
        label3_3.setFont(self.font_8)
        # -- 标签3_4
        label3_4 = QLabel(self.frame3)
        label3_4.setGeometry(220, 80, 51, 20)
        label3_4.setText('压缩比')
        label3_4.setFont(self.font_8)
        # -- 输入框3_2:压缩百分比
        self.line_edit3_2 = QLineEdit(self.frame3)
        self.line_edit3_2.setGeometry(265, 80, 25, 25)
        self.line_edit3_2.setFont(self.font_8)
        # -- 标签3_5
        label3_4 = QLabel(self.frame3)
        label3_4.setGeometry(295, 80, 14, 20)
        label3_4.setText('%')
        label3_4.setFont(self.font_8)
        # -- 按键3_1:自定义路径
        self.push_button3_1 = QPushButton(self.frame3)
        self.push_button3_1.setGeometry(10, 115, 93, 29)
        self.push_button3_1.setText('自定义路径')
        self.push_button3_1.setFont(self.font_9)
        # -- 按键3_2:一键压缩
        self.push_button3_2 = QPushButton(self.frame3)
        self.push_button3_2.setGeometry(115, 115, 93, 29)
        self.push_button3_2.setText('一键压缩')
        self.push_button3_2.setFont(self.font_9)
        # -- 按键3_3:退出软件
        self.push_button3_3 = QPushButton(self.frame3)
        self.push_button3_3.setGeometry(220, 115, 93, 29)
        self.push_button3_3.setText('我要退出')
        self.push_button3_3.setFont(self.font_9)
        # -- 设置其它依赖转移过来
        self.menubar.setParent(self.frame3)  # 设置菜单栏依赖于窗口3
        self.frame3.setVisible(True)

    def show_dialog(self):
        self.show_dialog1()

    def show_dialog1(self):
        if self.dialog2 is not None:
            self.dialog2.close()
        self.dialog1 = QDialog(self)
        self.dialog1.resize(340, 150)
        self.dialog1.setMinimumSize(340, 150)
        self.dialog1.setMaximumSize(340, 150)
        self.dialog1.setWindowIcon(QIcon('tools.png'))
        self.dialog1.setWindowTitle('自定义拼接')
        self.dialog1.setFont(self.font_8)

        # -- 设置标签1---
        label1 = QLabel(self.dialog1)
        label1.setGeometry(40, 10, 70, 29)
        label1.setText('单列拼接')
        label1.setAlignment(Qt.AlignCenter)
        # -- 设置按键2 ---
        push_button2 = QPushButton(self.dialog1)
        push_button2.setGeometry(40, 70, 70, 29)
        push_button2.setText('矩阵拼接')
        push_button2.clicked.connect(self.show_dialog2)

        # -- 标签2:拼接数量
        label2 = QLabel(self.dialog1)
        label2.setText('拼接数量')
        label2.setGeometry(150, 20, 51, 20)

        # -- 输入框:单列拼接数量
        self.dialog_line_edit1 = QLineEdit(self.dialog1)
        self.dialog_line_edit1.setGeometry(210, 20, 30, 20)
        self.dialog_push_button1 = QPushButton(self.dialog1)
        self.dialog_push_button1.setGeometry(150, 60, 93, 25)
        self.dialog_push_button1.setText('开始单列拼接')

    def show_dialog2(self):
        if self.dialog1 is not None:
            self.dialog1.close()  # 关闭会话1
        self.dialog2 = QDialog(self)
        self.dialog2.resize(340, 150)
        self.dialog2.setFont(self.font_8)
        self.dialog2.setMinimumSize(340, 150)
        self.dialog2.setMaximumSize(340, 150)
        self.dialog2.setWindowIcon(QIcon('tools.png'))
        self.dialog2.setWindowTitle('矩阵拼接')
        # -- 设置按键1---
        push_button1 = QPushButton(self.dialog2)
        push_button1.setGeometry(40, 10, 70, 29)
        push_button1.setText('单列拼接')
        push_button1.clicked.connect(self.show_dialog1)

        # -- 设置标签2---
        label1 = QLabel(self.dialog2)
        label1.setGeometry(40, 70, 70, 29)
        label1.setText('矩阵拼接')
        label1.setAlignment(Qt.AlignCenter)

        # -- 标签2:拼接列数
        label2 = QLabel(self.dialog2)
        label2.setText('拼接行数')
        label2.setGeometry(160, 20, 51, 20)
        # -- 标签3:拼接行数
        label3 = QLabel(self.dialog2)
        label3.setText('拼接列数')
        label3.setGeometry(160, 45, 51, 20)
        # -- 标签4:拼接行数
        label4 = QLabel(self.dialog2)
        label4.setText('拼接间隙')
        label4.setGeometry(160, 70, 51, 20)

        # -- 标签5:行数
        label4 = QLabel(self.dialog2)
        label4.setText('行')
        label4.setGeometry(260, 20, 41, 20)

        # -- 标签6:列数
        label4 = QLabel(self.dialog2)
        label4.setText('列')
        label4.setGeometry(260, 50, 41, 20)

        # -- 标签7:px像素
        label4 = QLabel(self.dialog2)
        label4.setText('px')
        label4.setGeometry(260, 70, 41, 20)

        # -- 输入框:拼接列数
        self.dialog_line_edit2 = QLineEdit(self.dialog2)
        self.dialog_line_edit2.setGeometry(220, 20, 30, 20)
        # -- 输入框:拼接行数
        self.dialog_line_edit3 = QLineEdit(self.dialog2)
        self.dialog_line_edit3.setGeometry(220, 45, 30, 20)
        # -- 输入框:拼接间隙
        self.dialog_line_edit4 = QLineEdit(self.dialog2)
        self.dialog_line_edit4.setGeometry(220, 70, 30, 20)

        self.dialog_push_button2 = QPushButton(self.dialog2)
        self.dialog_push_button2.setGeometry(160, 100, 93, 25)
        self.dialog_push_button2.setText('开始矩阵拼接')

    def notice_dialog(self):
        dialog = QDialog(self)
        dialog.resize(500, 450)
        dialog.setMinimumSize(340, 150)
        text = """\
<b>使用说明</b>:
主要功能有格式转换、图片拼接,图片压缩三项<br>
<b>格式转换</b>:目前只支持pdf转png<br>
<b>图片拼接</b>:<br>
1.支持自定义拼接路径。<br>
2.默认路径是你转成png图片后的路径。<br>
3.可以设置为一键拼接成一张长图。<br>
4.自定义拼接还可以按单列拼成长图,或者按矩阵进行拼接。<br>
5.单列拼接指的是按多张图拼接成一张图,比如15张图,<br>
  可以按5张图拼成一张长图,这样就获得了3张长图。<br>
6.矩阵拼接类似微信的九宫格,比如3行三列为一张长图,<br>
  中间可以设置10像素的间隙,然后可以获得多张这样的长图。<br>
7.矩阵拼接兼容单列拼接,即列为1,间隙为0时即为矩阵拼接。<br>
<b>图片压缩</b>:<br>
1.关于宽度<br>
  普通模式即自动压缩成1M以内,<br>
  720p和1080p则自动压缩图片为这个宽度<br>
2.关于格式<br>
  即压缩后图片的格式是jpg还是png<br>
3.关于压缩比<br>
  即压缩成jpg格式时,图片的质量百分比。
        """
        dialog.setWindowTitle('使用说明')
        label = QLabel(text, dialog)
        label.setFont(self.font_9)
        dialog.show()

    def update_dialog(self):
        """
        更新记录
        """
        dialog = QDialog(self)
        dialog.resize(500, 450)
        dialog.setMinimumSize(340, 150)
        text = """\
<b>V1.1版更新记录:</b><br>
1.增加窗口抽屉功能,将图片转换、图片拼接、图片压缩功能拆分。<br>
2.增加更多自定义功能,可以自定义图片文件夹来源,<br>
还可以自定义拼接方式了。<br>
3.优化了压缩图片算法的一个小bug,增加了压缩图片的最终格式自定义,<br>
可以选择压缩为jpg或者png。<br>
4.自定义拼接中,单列拼接与矩阵拼接多了一个翻转的过度动画。<br>
5.加入操作历史记录保留,自动保留上次的操作的方式<br>
注意,只会保留你的最后一次转图片、拼接图片、压缩图片的记录,<br>
选择文件的记录不在此列<br>
6.导出路径更改为与原pdf路径同级<br>
7.导出图片时自动删除上次导出的图片<br>
7.其他更新请阅读使用说明<br>
<br>
<b>V1.0版更新记录:</b><br>
1.使用PyQt5重构了界面<br>
2.增加了进度条,减少等待时间<br>
3.选择pdf文件时,默认上次的路径<br>
4.增加了二次确认操作<br>
5.使用多线程,提高了软件速度<br>
6.美化了GUI,变得好看了<br>
        """

        dialog.setWindowTitle('更新记录')
        label = QLabel(text, dialog)
        label.setFont(self.font_9)
        dialog.show()

    def feedback_dialog(self):
        """
        我要反馈
        """
        dialog = QDialog(self)
        dialog.resize(500, 50)
        dialog.setMinimumSize(340, 150)
        text = """\
qq群:<b>974759263</b><br>
        """

        dialog.setWindowTitle('我要反馈')
        label = QLabel(text, dialog)
        label.setFont(self.font_9)
        dialog.show()

    def about_dialog(self):
        dialog = QDialog(self)
        dialog.resize(500, 50)
        dialog.setMinimumSize(340, 150)
        text = """\
        版本号:<b>V1.1</b><br>
        编译日期:2020年6月3日<br>
                """
        dialog.setWindowTitle('关于')
        label = QLabel(text, dialog)
        label.setFont(self.font_9)
        dialog.show()

    # 公用读取字典
    @staticmethod
    def read_data_dict(key, data_path='./data.json'):
        """
        根据索引读取data.json的内容
        :param key: 索引
        :param data_path: json所在路径
        :return: data:读取到的值
        """
        with open(data_path, 'rt', encoding='utf-8') as f1:
            data_dict1 = json.load(f1)
        data = data_dict1.get(key, None)  # 没有内容则为None
        return data

    # 公用写入字典
    @staticmethod
    def write_data_dict(key, value2, data_path='./data.json'):
        """
        根据索引读取data.json的内容
        :param key: 写入键
        :return: value2:写入值
        :param data_path: json所在路径
        """
        f1 = open(data_path, 'rt', encoding='utf-8')
        data_dict1 = json.load(f1)
        f1.close()
        with open(data_path, 'wt', encoding='utf-8') as f2:
            data_dict1[key] = value2
            json.dump(data_dict1, f2)
Esempio n. 2
0
class Browser(Application):
    # pylint: disable=too-many-instance-attributes
    """The main browser"""
    url_scheme: QWebEngineUrlScheme
    bridge_initialized: bool
    dev_view: QWebEngineView
    dev_page: WebPage
    qdock: QDockWidget

    def __init__(self):
        super().__init__()
        self.init()
        # self.load()

    def init(self):
        """Initialize browser"""
        logger.debug("Initializing Browser Window")

        if web_greeter_config["config"]["greeter"]["debug_mode"]:
            os.environ['QTWEBENGINE_REMOTE_DEBUGGING'] = '12345'

        url_scheme = "web-greeter"
        self.url_scheme = QWebEngineUrlScheme(url_scheme.encode())
        self.url_scheme.setDefaultPort(QWebEngineUrlScheme.PortUnspecified)
        self.url_scheme.setFlags(QWebEngineUrlScheme.SecureScheme
                                 or QWebEngineUrlScheme.LocalScheme
                                 or QWebEngineUrlScheme.LocalAccessAllowed)
        QWebEngineUrlScheme.registerScheme(self.url_scheme)

        self.profile = QWebEngineProfile.defaultProfile()
        self.interceptor = QtUrlRequestInterceptor(url_scheme)
        self.url_scheme_handler = QtUrlSchemeHandler()

        self.view = QWebEngineView(parent=self.window)
        self.page = WebPage()
        self.view.setPage(self.page)
        self.page.setObjectName("WebG Page")
        self.view.setObjectName("WebG View")

        self.channel = QWebChannel(self.page)
        self.bridge_initialized = False

        self.profile.installUrlSchemeHandler(url_scheme.encode(),
                                             self.url_scheme_handler)

        self._initialize_page()

        if web_greeter_config["config"]["greeter"]["debug_mode"]:
            self._initialize_devtools()
        else:
            self.view.setContextMenuPolicy(Qt.PreventContextMenu)

        self._init_actions()
        if web_greeter_config["app"]["frame"]:
            self._init_menu_bar()
        else:
            self.window.setWindowFlags(self.window.windowFlags()
                                       | Qt.FramelessWindowHint)

        if web_greeter_config["config"]["greeter"]["secure_mode"]:
            if hasattr(QWebEngineProfile, "setUrlRequestInterceptor"):
                self.profile.setUrlRequestInterceptor(self.interceptor)
            else:  # Older Qt5 versions
                self.profile.setRequestInterceptor(self.interceptor)

        self.page.setBackgroundColor(QColor(0, 0, 0))
        self.window.setStyleSheet("""QMainWindow, QWebEngineView {
	                                background: #000000;
                                 }""")

        self.window.setCentralWidget(self.view)

        logger.debug("Browser Window created")

    def load(self):
        """Load theme and initialize bridge"""
        self.load_theme()

        self.bridge_objects = (self.greeter, self.greeter_config,
                               self.theme_utils)
        self.initialize_bridge_objects()
        self.load_script(':/_greeter/js/bundle.js', 'Web Greeter Bundle')

    def _initialize_devtools(self):
        self.dev_view = QWebEngineView(parent=self.window)
        self.dev_page = WebPage()
        self.dev_view.setPage(self.dev_page)
        self.page.setDevToolsPage(self.dev_page)
        self.dev_view.setObjectName("Devtools view")
        self.dev_page.setObjectName("Devtools page")

        self.dev_page.windowCloseRequested.connect(
            lambda: self.toggle_devtools_value(False))

        inspect_element_action = self.page.action(self.page.InspectElement)
        inspect_element_action.triggered.connect(
            lambda: self.toggle_devtools_value(True))

        self.qdock = QDockWidget()
        self.qdock.setWidget(self.dev_view)
        self.qdock.setFeatures(QDockWidget.DockWidgetMovable
                               or QDockWidget.DockWidgetClosable)

        self.window.addDockWidget(Qt.RightDockWidgetArea, self.qdock)
        self.qdock.hide()
        logger.debug("DevTools initialized")

    def toggle_devtools(self):
        """Toggle devtools"""
        if not web_greeter_config["config"]["greeter"]["debug_mode"]:
            return
        self.toggle_devtools_value(not self.qdock.isVisible())

    def toggle_devtools_value(self, value: bool):
        """Toggle devtools by value"""
        if not web_greeter_config["config"]["greeter"]["debug_mode"]:
            return

        if value:
            self.qdock.show()
            self.dev_view.setFocus()
        else:
            self.qdock.hide()
            self.view.setFocus()

    def _init_actions(self):
        """Init browser actions"""
        self.exit_action = QAction(QIcon("exit.png"), "&Quit", self.window)
        self.exit_action.setShortcut("Ctrl+Q")
        self.exit_action.setStatusTip("Exit application")
        self.exit_action.triggered.connect(qApp.quit)

        self.toggle_dev_action = QAction("Toggle Developer Tools", self.window)
        self.toggle_dev_action.setShortcut("Ctrl+Shift+I")
        self.toggle_dev_action.triggered.connect(self.toggle_devtools)

        self.fullscreen_action = QAction("Toggle Fullscreen", self.window)
        self.fullscreen_action.setShortcut("F11")
        self.fullscreen_action.triggered.connect(
            lambda: self.toggle_fullscreen(not self.window.isFullScreen()))

        self.inc_zoom_action = QAction("Zoom In", self.window)
        self.inc_zoom_action.setShortcut("Ctrl++")
        self.inc_zoom_action.triggered.connect(self._inc_zoom)
        self.dec_zoom_action = QAction("Zoom Out", self.window)
        self.dec_zoom_action.setShortcut("Ctrl+-")
        self.dec_zoom_action.triggered.connect(self._dec_zoom)
        self.reset_zoom_action = QAction("Actual Size", self.window)
        self.reset_zoom_action.setShortcut("Ctrl+0")
        self.reset_zoom_action.triggered.connect(self._reset_zoom)

        self.window.addAction(self.exit_action)
        self.window.addAction(self.toggle_dev_action)
        self.window.addAction(self.fullscreen_action)
        self.window.addAction(self.inc_zoom_action)
        self.window.addAction(self.dec_zoom_action)
        self.window.addAction(self.reset_zoom_action)

    def _inc_zoom(self):
        if self.view.hasFocus():
            self.page.increaseZoom()
        else:
            self.dev_page.increaseZoom()

    def _dec_zoom(self):
        if self.view.hasFocus():
            self.page.decreaseZoom()
        else:
            self.dev_page.decreaseZoom()

    def _reset_zoom(self):
        if self.view.hasFocus():
            self.page.setZoomFactor(1)
        else:
            self.dev_page.setZoomFactor(1)

    def _init_menu_bar(self):
        minimize_action = QAction("Minimize", self.window)
        minimize_action.setShortcut("Ctrl+M")
        minimize_action.triggered.connect(self.window.showMinimized)
        close_action = QAction("Close", self.window)
        close_action.setShortcut("Ctrl+W")
        close_action.triggered.connect(self.window.close)

        self.page.action(
            self.page.ReloadAndBypassCache).setText("Force Reload")

        self.page.fullScreenRequested.connect(self.accept_fullscreen)

        self.menu_bar = QMenuBar()

        file_menu = self.menu_bar.addMenu("&File")
        file_menu.addAction(self.exit_action)

        edit_menu = self.menu_bar.addMenu("&Edit")
        edit_menu.addAction(self.page.action(self.page.Undo))
        edit_menu.addAction(self.page.action(self.page.Redo))
        edit_menu.addSeparator()
        edit_menu.addAction(self.page.action(self.page.Cut))
        edit_menu.addAction(self.page.action(self.page.Copy))
        edit_menu.addAction(self.page.action(self.page.Paste))
        edit_menu.addSeparator()
        edit_menu.addAction(self.page.action(self.page.SelectAll))

        view_menu = self.menu_bar.addMenu("&View")
        view_menu.addAction(self.page.action(self.page.Reload))
        view_menu.addAction(self.page.action(self.page.ReloadAndBypassCache))
        view_menu.addAction(self.toggle_dev_action)
        view_menu.addSeparator()
        view_menu.addAction(self.reset_zoom_action)
        view_menu.addAction(self.inc_zoom_action)
        view_menu.addAction(self.dec_zoom_action)
        view_menu.addSeparator()
        view_menu.addAction(self.fullscreen_action)

        window_menu = self.menu_bar.addMenu("&Window")
        window_menu.addAction(minimize_action)
        window_menu.addAction(close_action)

        # help_menu = menu_bar.addMenu("&Help")

        self.window.setMenuBar(self.menu_bar)

    def accept_fullscreen(self, request):
        """Accepts fullscreen requests"""
        if web_greeter_config["config"]["greeter"]["debug_mode"]:
            request.reject()
            return
        if request.toggleOn():
            self.toggle_fullscreen(True)
        else:
            self.toggle_fullscreen(False)
        request.accept()

    def toggle_fullscreen(self, value: bool):
        """Toggle fullscreen"""
        if not web_greeter_config["config"]["greeter"]["debug_mode"]:
            return
        if value:
            state = self.states["FULLSCREEN"]
            self.window.setWindowFlags(self.window.windowFlags()
                                       or Qt.FramelessWindowHint)
            self.menu_bar.setParent(None)
            self.window.setMenuBar(None)
        else:
            state = self.states["NORMAL"]
            self.window.setWindowFlags(self.window.windowFlags()
                                       or not Qt.FramelessWindowHint)
            self.window.setMenuBar(self.menu_bar)
        try:
            self.window.windowHandle().setWindowState(state)
        except (AttributeError, TypeError):
            self.window.setWindowState(state)

    def _initialize_page(self):
        page_settings = self.page.settings().globalSettings()

        if not web_greeter_config["config"]["greeter"]["secure_mode"]:
            ENABLED_SETTINGS.append('LocalContentCanAccessRemoteUrls')
        else:
            DISABLED_SETTINGS.append('LocalContentCanAccessRemoteUrls')

        for setting in DISABLED_SETTINGS:
            try:
                page_settings.setAttribute(
                    getattr(QWebEngineSettings, setting), False)
            except AttributeError:
                pass

        for setting in ENABLED_SETTINGS:
            try:
                page_settings.setAttribute(
                    getattr(QWebEngineSettings, setting), True)
            except AttributeError:
                pass

        self.page.setView(self.view)

    def load_theme(self):
        """Load theme"""
        theme = web_greeter_config["config"]["greeter"]["theme"]
        dir_t = "/usr/share/web-greeter/themes/"
        path_to_theme = os.path.join(dir_t, theme, "index.html")
        def_theme = "gruvbox"

        if theme.startswith("/"):
            path_to_theme = theme
        elif theme.__contains__(".") or theme.__contains__("/"):
            path_to_theme = os.path.join(os.getcwd(), theme)
            path_to_theme = os.path.realpath(path_to_theme)

        if not path_to_theme.endswith(".html"):
            path_to_theme = os.path.join(path_to_theme, "index.html")

        if not os.path.exists(path_to_theme):
            print("Path does not exists", path_to_theme)
            path_to_theme = os.path.join(dir_t, def_theme, "index.html")

        web_greeter_config["config"]["greeter"]["theme"] = path_to_theme

        url = QUrl(f"web-greeter://app/{path_to_theme}")
        self.page.load(url)

        logger.debug("Theme loaded")

    @staticmethod
    def _create_webengine_script(path: Url, name: str) -> QWebEngineScript:
        script = QWebEngineScript()
        script_file = QFile(path)

        # print(script_file, path)

        if script_file.open(QFile.ReadOnly):
            script_string = str(script_file.readAll(), 'utf-8')

            script.setInjectionPoint(QWebEngineScript.DocumentCreation)
            script.setName(name)
            script.setWorldId(QWebEngineScript.MainWorld)
            script.setSourceCode(script_string)
            # print(script_string)

        return script

    def _get_channel_api_script(self) -> QWebEngineScript:
        return self._create_webengine_script(':/qtwebchannel/qwebchannel.js',
                                             'QWebChannel API')

    def _init_bridge_channel(self) -> None:
        self.page.setWebChannel(self.channel)
        self.bridge_initialized = True

    def initialize_bridge_objects(self) -> None:
        """Initialize bridge objects :D"""
        if not self.bridge_initialized:
            self._init_bridge_channel()
        registered_objects = self.channel.registeredObjects()

        for obj in self.bridge_objects:
            if obj not in registered_objects:
                # pylint: disable=protected-access
                self.channel.registerObject(obj._name, obj)
                # print("Registered", obj._name)

    def load_script(self, path: Url, name: str):
        """Loads a script in page"""
        qt_api = self._get_channel_api_script()
        qt_api_source = qt_api.sourceCode()
        script = self._create_webengine_script(path, name)
        script.setSourceCode(qt_api_source + "\n" + script.sourceCode())
        self.page.scripts().insert(script)