示例#1
0
class Demo(QWidget):
    sb_roundness = None
    sb_opacity = None
    sb_fadeperc = None
    sb_lines = None
    sb_line_length = None
    sb_line_width = None
    sb_inner_radius = None
    sb_rev_s = None

    btn_start = None
    btn_stop = None
    btn_pick_color = None

    spinner = None

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        grid = QGridLayout()
        groupbox1 = QGroupBox()
        groupbox1_layout = QHBoxLayout()
        groupbox2 = QGroupBox()
        groupbox2_layout = QGridLayout()
        button_hbox = QHBoxLayout()
        self.setLayout(grid)
        self.setWindowTitle("QtWaitingSpinner Demo")
        self.setWindowFlags(Qt.Dialog)

        # SPINNER
        self.spinner = QtWaitingSpinner(self)

        # Spinboxes
        self.sb_roundness = QDoubleSpinBox()
        self.sb_opacity = QDoubleSpinBox()
        self.sb_fadeperc = QDoubleSpinBox()
        self.sb_lines = QSpinBox()
        self.sb_line_length = QDoubleSpinBox()
        self.sb_line_width = QDoubleSpinBox()
        self.sb_inner_radius = QDoubleSpinBox()
        self.sb_rev_s = QDoubleSpinBox()

        # set spinbox default values
        self.sb_roundness.setValue(70)
        self.sb_roundness.setRange(0, 9999)
        self.sb_opacity.setValue(15)
        self.sb_opacity.setRange(0, 9999)
        self.sb_fadeperc.setValue(70)
        self.sb_fadeperc.setRange(0, 9999)
        self.sb_lines.setValue(12)
        self.sb_lines.setRange(1, 9999)
        self.sb_line_length.setValue(10)
        self.sb_line_length.setRange(0, 9999)
        self.sb_line_width.setValue(5)
        self.sb_line_width.setRange(0, 9999)
        self.sb_inner_radius.setValue(10)
        self.sb_inner_radius.setRange(0, 9999)
        self.sb_rev_s.setValue(1)
        self.sb_rev_s.setRange(0.1, 9999)

        # Buttons
        self.btn_start = QPushButton("Start")
        self.btn_stop = QPushButton("Stop")
        self.btn_pick_color = QPushButton("Pick Color")

        # Connects
        self.sb_roundness.valueChanged.connect(self.set_roundness)
        self.sb_opacity.valueChanged.connect(self.set_opacity)
        self.sb_fadeperc.valueChanged.connect(self.set_fadeperc)
        self.sb_lines.valueChanged.connect(self.set_lines)
        self.sb_line_length.valueChanged.connect(self.set_line_length)
        self.sb_line_width.valueChanged.connect(self.set_line_width)
        self.sb_inner_radius.valueChanged.connect(self.set_inner_radius)
        self.sb_rev_s.valueChanged.connect(self.set_rev_s)

        self.btn_start.clicked.connect(self.spinner_start)
        self.btn_stop.clicked.connect(self.spinner_stop)
        self.btn_pick_color.clicked.connect(self.show_color_picker)

        # Layout adds
        groupbox1_layout.addWidget(self.spinner)
        groupbox1.setLayout(groupbox1_layout)

        groupbox2_layout.addWidget(QLabel("Roundness:"), *(1, 1))
        groupbox2_layout.addWidget(self.sb_roundness, *(1, 2))
        groupbox2_layout.addWidget(QLabel("Opacity:"), *(2, 1))
        groupbox2_layout.addWidget(self.sb_opacity, *(2, 2))
        groupbox2_layout.addWidget(QLabel("Fade Perc:"), *(3, 1))
        groupbox2_layout.addWidget(self.sb_fadeperc, *(3, 2))
        groupbox2_layout.addWidget(QLabel("Lines:"), *(4, 1))
        groupbox2_layout.addWidget(self.sb_lines, *(4, 2))
        groupbox2_layout.addWidget(QLabel("Line Length:"), *(5, 1))
        groupbox2_layout.addWidget(self.sb_line_length, *(5, 2))
        groupbox2_layout.addWidget(QLabel("Line Width:"), *(6, 1))
        groupbox2_layout.addWidget(self.sb_line_width, *(6, 2))
        groupbox2_layout.addWidget(QLabel("Inner Radius:"), *(7, 1))
        groupbox2_layout.addWidget(self.sb_inner_radius, *(7, 2))
        groupbox2_layout.addWidget(QLabel("Rev/s:"), *(8, 1))
        groupbox2_layout.addWidget(self.sb_rev_s, *(8, 2))

        groupbox2.setLayout(groupbox2_layout)

        button_hbox.addWidget(self.btn_start)
        button_hbox.addWidget(self.btn_stop)
        button_hbox.addWidget(self.btn_pick_color)

        grid.addWidget(groupbox1, *(1, 1))
        grid.addWidget(groupbox2, *(1, 2))
        grid.addLayout(button_hbox, *(2, 1))

        self.spinner.start()
        self.show()

    def set_roundness(self):
        self.spinner.setRoundness(self.sb_roundness.value())

    def set_opacity(self):
        self.spinner.setMinimumTrailOpacity(self.sb_opacity.value())

    def set_fadeperc(self):
        self.spinner.setTrailFadePercentage(self.sb_fadeperc.value())

    def set_lines(self):
        self.spinner.setNumberOfLines(self.sb_lines.value())

    def set_line_length(self):
        self.spinner.setLineLength(self.sb_line_length.value())

    def set_line_width(self):
        self.spinner.setLineWidth(self.sb_line_width.value())

    def set_inner_radius(self):
        self.spinner.setInnerRadius(self.sb_inner_radius.value())

    def set_rev_s(self):
        self.spinner.setRevolutionsPerSecond(self.sb_rev_s.value())

    def spinner_start(self):
        self.spinner.start()

    def spinner_stop(self):
        self.spinner.stop()

    def show_color_picker(self):
        self.spinner.setColor(QColorDialog.getColor())
示例#2
0
class Main(QWizard):
    def __init__(self):
        super(Main, self).__init__()

        # build UI
        self.ui = WizardUI()
        self.ui.setup_ui(self)

        # connect signals
        self.threadpool = QThreadPool()

        self.keytree_dir_dict = {
            1: {'dirname': 'Home', 'dirparent': False, 'nfiles': 78, 'cumfiles': 123,
                'childkeys': {2}, 'mtime': 1330884000.0, 'selection_state': 1, 'exclusion_state': 0,
                'description': "Partial: some contents (files and/or folders) are relevant to the collection"},
            2: {'dirname': 'Work files', 'dirparent': 1, 'nfiles': 32, 'cumfiles': 45,
                'childkeys': {3, 4}, 'mtime': 1330797600.0, 'selection_state': 1, 'exclusion_state': 0,
                'description': "Partial: some contents (files and/or folders) are relevant to the collection"},
            3: {'dirname': 'Travel photos', 'dirparent': 2, 'nfiles': 6, 'cumfiles': 6,
                'childkeys': set(), 'mtime': 1330624800.0, 'selection_state': 0, 'exclusion_state': 0,
                'description': "Unchecked: this folder is simply not relevant to the collection"},
            4: {'dirname': 'Project A', 'dirparent': 2, 'nfiles': 1, 'cumfiles': 7,
                'childkeys': {5, 6}, 'mtime': 1325527200.0, 'selection_state': 2, 'exclusion_state': 0,
                'description': "Checked: this folder is relevant to the collection"},
            5: {'dirname': 'Drafts', 'dirparent': 4, 'nfiles': 2, 'cumfiles': 2,
                'childkeys': set(), 'mtime': 1255891200.0, 'selection_state': 2, 'exclusion_state': 0,
                'description': "Checked: this folder is relevant to the collection"},
            6: {'dirname': 'Bank transfer', 'dirparent': 4, 'nfiles': 4, 'cumfiles': 4,
                'childkeys': set(), 'mtime': 1322202000.0, 'selection_state': 0, 'exclusion_state': 2,
                'description': "Excluded: this folder is excluded (e.g., it contains sensitive information/work)"},
        }

        self.demo_dir_dict = {
            1: {'dirname': 'folder 1', 'dirparent': False, 'nfiles': 78, 'cumfiles': 123,
                'childkeys': {2}, 'mtime': 1330884000.0, 'selection_state': None, 'exclusion_state': None},
            2: {'dirname': 'folder 2', 'dirparent': 1, 'nfiles': 32, 'cumfiles': 45,
                'childkeys': {3, 4}, 'mtime': 1330797600.0, 'selection_state': None, 'exclusion_state': None},
            3: {'dirname': 'folder 3', 'dirparent': 2, 'nfiles': 6, 'cumfiles': 6,
                'childkeys': set(), 'mtime': 1330624800.0, 'selection_state': None, 'exclusion_state': None},
            4: {'dirname': 'folder 4', 'dirparent': 2, 'nfiles': 1, 'cumfiles': 7,
                'childkeys': {5, 6}, 'mtime': 1325527200.0, 'selection_state': None, 'exclusion_state': None},
            5: {'dirname': 'folder 5', 'dirparent': 4, 'nfiles': 2, 'cumfiles': 2,
                'childkeys': set(), 'mtime': 1255891200.0, 'selection_state': None, 'exclusion_state': None},
            6: {'dirname': 'folder 6', 'dirparent': 4, 'nfiles': 4, 'cumfiles': 4,
                'childkeys': set(), 'mtime': 1322202000.0, 'selection_state': None, 'exclusion_state': None},
        }

        self.spinner = QtWaitingSpinner(self, True, True, Qt.ApplicationModal)
        self.spinner.setRoundness(70.0)
        self.spinner.setMinimumTrailOpacity(15.0)
        self.spinner.setTrailFadePercentage(70.0)
        self.spinner.setNumberOfLines(12)
        self.spinner.setLineLength(30)
        self.spinner.setLineWidth(10)
        self.spinner.setInnerRadius(15)
        self.spinner.setRevolutionsPerSecond(1)

        keytree = KeyTreeOperations(
            self.ui.og_tree_key, self.threadpool, self.spinner)
        tree0 = TreeOperations(
            self.ui.og_tree_0, self.threadpool, self.spinner)
        tree1 = TreeOperations(
            self.ui.og_tree_1, self.threadpool, self.spinner,
            self.ui.select_btn_1, self.ui.save_btn_1, self.ui.load_btn_1, self.ui.less_btn_1)

        keytree.load_dir_dicts(self.keytree_dir_dict, checkable=False, expand_all=True)
        tree0.load_dir_dicts(self.demo_dir_dict, expand_all=True)
        self.ui.reset_demo_btn.clicked.connect(
            lambda: tree0.refresh_treeview(tree0.og_model, tree0.og_tree, self.demo_dir_dict, expand_all=True))
        tree1.select_btn.clicked.connect(lambda: self.select_tree_root(tree1))
        tree1.save_btn.clicked.connect(lambda: self.save_collected_data(tree1))
        tree1.load_btn.clicked.connect(lambda: self.load_collected_data(tree1))
        tree1.less_btn.clicked.connect(lambda: self.expand_to_depth(tree1, 0))
        self.ui.consent_savebutton.clicked.connect(self.save_consent)
        self.ui.wizardpage1.registerField("consentbox*", self.ui.consentbox)

    def select_tree_root(self, tree):
        dirpath = QFileDialog.getExistingDirectory(
            self, 'Select Folder', path_str(tree.root_path))
        if dirpath:
            tree.root_path = Path(dirpath)
            tree.build_tree_structure_threaded(tree.root_path)
        else:
            tree.clear_root()
            tree.save_btn.setDisabled(True)
            tree.less_btn.setDisabled(True)

    def save_consent(self):
        formats = "Text (*.txt)"
        filename, extension = QFileDialog.getSaveFileName(
            self, 'Save File', path_str(Path('~').expanduser() / 'my_consent.txt'), formats)
        if filename != '':
            with open(filename, 'w', encoding='utf8') as file:
                consent_txt = (self.ui.welcomelabel.text() +
                               self.ui.consentbox.text() +
                               self.ui.reblabel.text())
                doc = QTextDocument()
                doc.setHtml(consent_txt)
                consent_plaintext = doc.toPlainText()
                file.write(consent_plaintext)

    def make_super_dict(self, dict_list, name_list):
        super_dict = dict()
        if len(dict_list) == len(name_list):
            for dict_, name in zip(dict_list, name_list):
                super_dict[name] = dict_
            return super_dict
        else:
            print('Mismatch in number of dicts and supplied names.')

    def save_collected_data(self, tree):
        formats = "JavaScript Object Notation (*.json)"
        filename, extension = QFileDialog.getSaveFileName(
            self, 'Save File', path_str(Path('~').expanduser() / 'my_folder_data.json'), formats)
        if filename != '':
            anon_dir_dict = _pickle.loads(_pickle.dumps(tree.og_dir_dict))
            tree.save_checkstates_root(anon_dir_dict)
            json_serializable(anon_dir_dict)
            super_dict = self.make_super_dict(
                [anon_dir_dict, self.ui.textarea_wp3_0.toPlainText()],
                ['dir_dict', 'software_choice'])
            with open(filename, 'w', encoding='utf8') as file:
                json.dump(super_dict, file, indent=4)

    def load_collected_data(self, tree):
        formats = "JavaScript Object Notation (*.json)"
        filename, extension = QFileDialog.getOpenFileName(
            self, 'Load File', path_str(Path('~').expanduser()), formats)
        if filename != '':
            with open(filename, 'r', encoding='utf8') as file:
                super_dict = json.load(file)
                self.ui.textarea_wp3_0.setPlainText(super_dict['software_choice'])
                tree.og_dir_dict = super_dict['dir_dict']
                dict_readable(tree.og_dir_dict)
                tree.anon_dir_dict = _pickle.loads(_pickle.dumps(tree.og_dir_dict))
                tree.refresh_treeview(tree.og_model, tree.og_tree, tree.og_dir_dict)
                tree.save_btn.setEnabled(True)
                tree.less_btn.setEnabled(True)

    def expand_to_depth(self, tree, depth):
        tree.og_tree.expandToDepth(depth)
示例#3
0
class LoginDialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        super(LoginDialog, self).__init__(parent)
        self.initUI()
        self.session = Utility().session
        self.userName = None

    def initUI(self):
        self.setupUi(self)
        self.setFixedSize(QSize(self.width(), self.height()))
        self.setWindowIcon(QIcon('Pictures/loginIcon.png'))
        self.setWindowTitle('12306登录')
        self.loginButton.setText('立即登录')
        # self.userNameEdit.setClearButtonEnabled(True) #设置清空按钮

        self.setLineEditIcon(self.passwordEdit, 'Pictures/password_new.png')
        self.setLineEditIcon(self.userNameEdit, 'Pictures/user_new.png')

        self.userNameEdit.textChanged.connect(self.isLoginable)
        self.passwordEdit.textChanged.connect(self.isLoginable)

        self.loginButton.clicked.connect(self.login)

        self.initSettings()

        self.setupStyleSheet()

        self.isLoginable()

        self.initSpinner()

        self.initMessageLabel()

        self.remberCheckBox.stateChanged.connect(self.setupRememberCheck)

    def setupRememberCheck(self, state):

        if state == Qt.Checked:
            self.remberCheckBox.setStyleSheet(rememberBoxStyle +
                                              'QCheckBox{color:#d81e06}')
            self.settings.setValue('isChecked', True)
            self.settings.setValue('username', self.userNameEdit.text())
            self.settings.setValue('password', self.passwordEdit.text())
        else:
            self.remberCheckBox.setStyleSheet(rememberBoxStyle +
                                              'QCheckBox{color:white}')
            self.settings.setValue('isChecked', False)
        self.settings.sync()

    def isLoginable(self):
        self.messageLabel.hide()

        if self.userNameEdit.text() == '' or self.passwordEdit.text() == '':
            self.loginButton.setStyleSheet(
                'QPushButton{color:white;background-color:rgba(0,0,0,0.5);border:1px;border-radius:5px;}'
            )
            self.loginButton.setEnabled(False)
        else:
            self.loginButton.setStyleSheet(
                'QPushButton{color:white;background-color:rgb(250,80,0);border-radius:5px}'
            )
            self.loginButton.setEnabled(True)

    def login(self):

        self.spinner.start()

        runnable = RequestRunnable(target=self.login12306)
        self.pool = QThreadPool.globalInstance()
        self.pool.start(runnable)

    def login12306(self):
        # step 1: check验证码

        self.captchaCheck()

        # step 2: login
        loginData = {
            'username': self.userNameEdit.text(),
            'password': self.passwordEdit.text(),
            'appid': 'otn'
        }
        result = self.session.post(API.login, data=loginData).json()

        if result['result_code'] != 0:  # 出错的话,显示错误信息
            self.messageLabel.setText('出错啦:' + result['result_message'])
            self.messageLabel.show()
            self.spinner.stop()
            return

        # step 3:checkuser
        data = {'_json_att': ''}
        self.session.post(API.checkUser, data=data)

        # step 4: uamtk
        data = {'appid': 'otn'}
        uamtk_res = self.session.post(API.uamtk, data=data)
        newapptk = uamtk_res.json()['newapptk']

        # step 5: uamauthclient
        clientData = {'tk': newapptk}
        uamauthclient_res = self.session.post(API.uamauthclient,
                                              data=clientData)
        username = uamauthclient_res.json()['username']
        self.userName = username

        # step 6: initMy12306
        html = self.session.get(API.initMy12306).text

        genderStr = re.findall(r'<div id="my12306page".*?</span>(.*?)</h3>',
                               html, re.S)[0].replace('\n', '').split(',')[0]
        print("恭喜{}成功登录12306网站".format(username))
        if genderStr:
            self.accept()

    # 获取验证码正确答案
    def getCaptchaAnswer(self):

        response = self.session.get(API.captchaImage)
        if response.status_code == 200:
            print('验证码图片请求成功')
            with open(const.captchaFilePath, 'wb') as f:
                f.write(response.content)  # 写入文件
        else:
            print('验证码图片下载失败, 正在重试...')
            self.getCaptchaAnswer()  # 递归
        try:
            img = open(const.captchaFilePath, 'rb').read()  # 读取文件图片
            answerStr, cjyAnswerDict = const.chaoJiYing.PostPic(img, 9004)
            return answerStr, cjyAnswerDict  # 返回自己写的验证码信息和平台反应的信息
        except Exception as e:
            print(str(e))

    def captchaCheck(self):
        answer, cjyAnswerDict = self.getCaptchaAnswer()
        # ca = Captcha(self)
        # ca.show()
        # answer = ca.coordinates

        data = {
            'login_site': 'E',  # 固定的
            'rand': 'sjrand',  # 固定的
            'answer': answer  # 验证码对应的坐标,两个为一组,跟选择顺序有关,有几个正确的,输入几个
        }
        result = self.session.post(API.captchaCheck, data=data).json()

        if result['result_code'] == '4':
            print('验证码验证成功')
        else:
            print('验证码验证失败')
            picID = cjyAnswerDict['pic_id']
            # 报错到打码平台
            const.chaoJiYing.ReportError(picID)
            self.captchaCheck()
            return

    def setLineEditIcon(self, lineEdit, iconPath):
        action = QAction(lineEdit)
        action.setIcon(QIcon(iconPath))
        lineEdit.addAction(action,
                           QLineEdit.TrailingPosition)  #LeadingPosition

    def setupStyleSheet(self):

        self.setStyleSheet('QDialog{border-image:url(Pictures/loginBg.png)}')

        self.bgLabel.setStyleSheet(
            'QLabel{background-color:rgba(0,0,0,0.25);border-radius:5px}'
        )  # 设置透明背景色

        if self.settings.value('isChecked') == 'true':
            self.remberCheckBox.setStyleSheet('QCheckBox{color:#d81e06}' +
                                              rememberBoxStyle)
        else:
            self.remberCheckBox.setStyleSheet('QCheckBox{color:white}' +
                                              rememberBoxStyle)

        self.userNameEdit.setStyleSheet(lineEditStyle)
        self.passwordEdit.setStyleSheet(lineEditStyle)

    def initSettings(self):

        self.settings = QSettings('Honeywell', '12306Train')
        if self.settings.value('isChecked') == 'true':
            self.remberCheckBox.setChecked(True)
            self.userNameEdit.setText(self.settings.value('username'))
            self.passwordEdit.setText(self.settings.value('password'))
        else:
            self.remberCheckBox.setChecked(False)

    def initMessageLabel(self):
        self.messageLabel.adjustSize()
        self.messageLabel.setGeometry(QRect(70, 15, 360, 50))
        self.messageLabel.setWordWrap(True)
        self.messageLabel.setScaledContents(True)
        self.messageLabel.setStyleSheet(
            'QLabel{background-color:rgb(255,0,79);color:white;font:9pt;padding-left:5px;padding-right:5px;}'
        )  # border-radius:5px

        # height = self.messageLabel.fontMetrics().boundingRect(self.messageLabel.text()).height()
        self.messageLabel.hide()

    def initSpinner(self):
        self.spinner = QtWaitingSpinner(self,
                                        centerOnParent=True,
                                        disableParentWhenSpinning=True)
        self.spinner.setNumberOfLines(15)
        # self.spinner.setColor(QColor(81, 4, 71))
        self.spinner.setInnerRadius(20)  # 设置内圆大小
        self.spinner.setLineLength(15)  # 设置线长
        self.spinner.setLineWidth(5)  # 设置线宽
        self.spinner.setTrailFadePercentage(80)
示例#4
0
class Demo(QWidget):
    sb_roundness = None
    sb_opacity = None
    sb_fadeperc = None
    sb_lines = None
    sb_line_length = None
    sb_line_width = None
    sb_inner_radius = None
    sb_rev_s = None

    btn_start = None
    btn_stop = None
    btn_pick_color = None

    spinner = None

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        grid = QGridLayout()
        groupbox1 = QGroupBox()
        groupbox1_layout = QHBoxLayout()
        groupbox2 = QGroupBox()
        groupbox2_layout = QGridLayout()
        button_hbox = QHBoxLayout()
        self.setLayout(grid)
        self.setWindowTitle("QtWaitingSpinner Demo")
        self.setWindowFlags(Qt.Dialog)

        # SPINNER
        self.spinner = QtWaitingSpinner(self)

        # Spinboxes
        self.sb_roundness = QDoubleSpinBox()
        self.sb_opacity = QDoubleSpinBox()
        self.sb_fadeperc = QDoubleSpinBox()
        self.sb_lines = QSpinBox()
        self.sb_line_length = QDoubleSpinBox()
        self.sb_line_width = QDoubleSpinBox()
        self.sb_inner_radius = QDoubleSpinBox()
        self.sb_rev_s = QDoubleSpinBox()

        # set spinbox default values
        self.sb_roundness.setValue(70)
        self.sb_roundness.setRange(0, 9999)
        self.sb_opacity.setValue(15)
        self.sb_opacity.setRange(0, 9999)
        self.sb_fadeperc.setValue(70)
        self.sb_fadeperc.setRange(0, 9999)
        self.sb_lines.setValue(12)
        self.sb_lines.setRange(1, 9999)
        self.sb_line_length.setValue(10)
        self.sb_line_length.setRange(0, 9999)
        self.sb_line_width.setValue(5)
        self.sb_line_width.setRange(0, 9999)
        self.sb_inner_radius.setValue(10)
        self.sb_inner_radius.setRange(0, 9999)
        self.sb_rev_s.setValue(1)
        self.sb_rev_s.setRange(0.1, 9999)

        # Buttons
        self.btn_start = QPushButton("Start")
        self.btn_stop = QPushButton("Stop")
        self.btn_pick_color = QPushButton("Pick Color")

        # Connects
        self.sb_roundness.valueChanged.connect(self.set_roundness)
        self.sb_opacity.valueChanged.connect(self.set_opacity)
        self.sb_fadeperc.valueChanged.connect(self.set_fadeperc)
        self.sb_lines.valueChanged.connect(self.set_lines)
        self.sb_line_length.valueChanged.connect(self.set_line_length)
        self.sb_line_width.valueChanged.connect(self.set_line_width)
        self.sb_inner_radius.valueChanged.connect(self.set_inner_radius)
        self.sb_rev_s.valueChanged.connect(self.set_rev_s)

        self.btn_start.clicked.connect(self.spinner_start)
        self.btn_stop.clicked.connect(self.spinner_stop)
        self.btn_pick_color.clicked.connect(self.show_color_picker)

        # Layout adds
        groupbox1_layout.addWidget(self.spinner)
        groupbox1.setLayout(groupbox1_layout)

        groupbox2_layout.addWidget(QLabel("Roundness:"), *(1, 1))
        groupbox2_layout.addWidget(self.sb_roundness, *(1, 2))
        groupbox2_layout.addWidget(QLabel("Opacity:"), *(2, 1))
        groupbox2_layout.addWidget(self.sb_opacity, *(2, 2))
        groupbox2_layout.addWidget(QLabel("Fade Perc:"), *(3, 1))
        groupbox2_layout.addWidget(self.sb_fadeperc, *(3, 2))
        groupbox2_layout.addWidget(QLabel("Lines:"), *(4, 1))
        groupbox2_layout.addWidget(self.sb_lines, *(4, 2))
        groupbox2_layout.addWidget(QLabel("Line Length:"), *(5, 1))
        groupbox2_layout.addWidget(self.sb_line_length, *(5, 2))
        groupbox2_layout.addWidget(QLabel("Line Width:"), *(6, 1))
        groupbox2_layout.addWidget(self.sb_line_width, *(6, 2))
        groupbox2_layout.addWidget(QLabel("Inner Radius:"), *(7, 1))
        groupbox2_layout.addWidget(self.sb_inner_radius, *(7, 2))
        groupbox2_layout.addWidget(QLabel("Rev/s:"), *(8, 1))
        groupbox2_layout.addWidget(self.sb_rev_s, *(8, 2))

        groupbox2.setLayout(groupbox2_layout)

        button_hbox.addWidget(self.btn_start)
        button_hbox.addWidget(self.btn_stop)
        button_hbox.addWidget(self.btn_pick_color)

        grid.addWidget(groupbox1, *(1, 1))
        grid.addWidget(groupbox2, *(1, 2))
        grid.addLayout(button_hbox, *(2, 1))

        self.spinner.start()
        self.show()

    def set_roundness(self):
        self.spinner.setRoundness(self.sb_roundness.value())

    def set_opacity(self):
        self.spinner.setMinimumTrailOpacity(self.sb_opacity.value())

    def set_fadeperc(self):
        self.spinner.setTrailFadePercentage(self.sb_fadeperc.value())

    def set_lines(self):
        self.spinner.setNumberOfLines(self.sb_lines.value())

    def set_line_length(self):
        self.spinner.setLineLength(self.sb_line_length.value())

    def set_line_width(self):
        self.spinner.setLineWidth(self.sb_line_width.value())

    def set_inner_radius(self):
        self.spinner.setInnerRadius(self.sb_inner_radius.value())

    def set_rev_s(self):
        self.spinner.setRevolutionsPerSecond(self.sb_rev_s.value())

    def spinner_start(self):
        self.spinner.start()

    def spinner_stop(self):
        self.spinner.stop()

    def show_color_picker(self):
        self.spinner.setColor(QColorDialog.getColor())
示例#5
0
class Window(QWidget):

    sig_abort_workers = pyqtSignal()

    def __init__(self, val, screenwidth, screenheight, parent=None):
        super().__init__(parent)
        self.setWindowTitle("qtube")

        app_exit_shortcuts = ["Ctrl+Q", "Ctrl+W"]
        for sc in app_exit_shortcuts:
            exitshortcut = QShortcut(QKeySequence(sc), self)
            exitshortcut.activated.connect(self.exit_seq)

        backshortcut = QShortcut(QKeySequence('Alt+Left'), self)
        backshortcut.activated.connect(self.on_back_clicked)

        self.setStyleSheet("background-color: " + BACKGROUND_COLOR + ";")

        self.mygroupbox = QGroupBox('')
        self.mygroupbox.setStyleSheet("color: " + FOREGROUND_COLOR +
                                      "; font-family: " + FONT +
                                      "; font-style: italic")
        self.myform = QFormLayout()
        labellist = []
        combolist = []

        self.mygroupbox.setLayout(self.myform)
        self.scroll = QScrollArea()
        self.scroll.setWidget(self.mygroupbox)
        self.scroll.setWidgetResizable(True)
        self.scroll.setStyleSheet("color: " + FOREGROUND_COLOR + ";")

        self.history = {
            'urls': [],
            'title_boxes': [],
            'data': [],
            'page_numbers': []
        }
        self.downloaded_videos = {'paths': [], 'short_titles': []}
        self.search = ''

        self.spinner = QtWaitingSpinner(self, False)
        self.spinner.setRoundness(70.0)
        self.spinner.setMinimumTrailOpacity(15.0)
        self.spinner.setTrailFadePercentage(70.0)
        self.spinner.setNumberOfLines(10)
        self.spinner.setLineLength(10)
        self.spinner.setLineWidth(4)
        self.spinner.setInnerRadius(4)
        self.spinner.setRevolutionsPerSecond(1.5)
        self.spinner.setColor(QColor(FOREGROUND_COLOR))

        # multi-threading
        QThread.currentThread().setObjectName(
            'main')  # threads can be named, useful for log output
        self.__workers_done = []
        self.__threads = []

        self.line = QLineEdit(self)
        self.line.returnPressed.connect(self.clickMethod)
        self.line.setStyleSheet("color: " + FOREGROUND_COLOR +
                                "; background-color: " + BACKGROUND_COLOR +
                                "; border: 1px solid " + FOREGROUND_COLOR +
                                "; font-family: " + FONT + ";")

        active_buttons = []
        self.inactive_buttons = []

        self.search_button = QPushButton()
        self.search_button.setText('Search')
        self.search_button.clicked.connect(self.clickMethod)
        active_buttons.append(self.search_button)

        self.home_button = QPushButton()
        self.home_button.setText('Home')
        self.home_button.clicked.connect(self.on_home_clicked)
        self.inactive_buttons.append(self.home_button)

        self.play_playlist_button = QPushButton()
        self.play_playlist_button.setText('Play All')
        self.play_playlist_button.clicked.connect(
            self.on_play_playlist_clicked)
        active_buttons.append(self.play_playlist_button)

        self.back_button = QPushButton()
        self.back_button.setText('Back')
        self.back_button.clicked.connect(self.on_back_clicked)
        self.inactive_buttons.append(self.back_button)

        for b in active_buttons:
            b.setStyleSheet("color: " + FOREGROUND_COLOR +
                            "; background-color: " + BACKGROUND_COLOR +
                            "; border: 1px solid " + FOREGROUND_COLOR +
                            "; font-family: " + FONT + ";")
            b.setCursor(Qt.PointingHandCursor)

        for b in self.inactive_buttons:
            b.setStyleSheet("color: " + INACTIVE_COLOR +
                            "; background-color: " + BACKGROUND_COLOR +
                            "; border: 1px solid " + INACTIVE_COLOR +
                            "; font-family: " + FONT + ";")

        self.download_label = QLabel()
        self.download_label.setText('0 downloads')
        self.download_label.setMaximumSize(QSize(110, 20))
        self.download_label.setStyleSheet("color: " + INACTIVE_COLOR +
                                          "; background-color: " +
                                          BACKGROUND_COLOR +
                                          "; font-family: " + FONT + ";")

        self.download_selector = QComboBox()
        self.download_selector.setStyleSheet("color: " + INACTIVE_COLOR +
                                             "; background-color: " +
                                             BACKGROUND_COLOR +
                                             "; font-family: " + FONT + ";")
        self.download_selector.currentIndexChanged.connect(
            self.select_download)

        self.download_to_play = ''

        self.play_downloaded_button = QPushButton()
        self.play_downloaded_button.setText('Play')
        self.play_downloaded_button.clicked.connect(self.on_play_downloaded)
        self.play_downloaded_button.setMaximumSize(QSize(50, 20))
        self.play_downloaded_button.setStyleSheet("color: " + INACTIVE_COLOR +
                                                  "; background-color: " +
                                                  BACKGROUND_COLOR +
                                                  "; border: 1px solid " +
                                                  INACTIVE_COLOR +
                                                  "; font-family: " + FONT +
                                                  ";")

        self.container = VideoContainer(PLAYER_SIZE)
        self.container.setAttribute(Qt.WA_DontCreateNativeAncestors)
        self.container.setAttribute(Qt.WA_NativeWindow)
        #self.container.sig_height.connect(self.resizeWindow)

        self.player = mpv.MPV(
            wid=str(int(self.container.winId())),
            ytdl=True,
            input_default_bindings=True,
            input_vo_keyboard=True,
            keep_open=True,
            reset_on_next_file='pause',
            osd_bar=True,
        )

        script_dir = str(Path.home()) + '/.config/mpv/scripts/'
        [
            self.player.command('load-script', script_dir + script)
            for script in os.listdir(script_dir)
        ]

        player_exit_shortcuts = ['q', 'ctrl+q', 'ctrl+w']
        for sc in player_exit_shortcuts:
            self.player.register_key_binding(sc, self.exit_seq)

        self.player.register_key_binding('f', self.fullscreen)
        self.player.register_key_binding('esc', self.fullscreen_off)
        self.isFullScreen = False

        self.player.register_key_binding('WHEEL_LEFT', 'seek 1')
        self.player.register_key_binding('WHEEL_RIGHT', 'seek -1')

        searchbarlayout = QHBoxLayout()
        searchbarlayout.addWidget(self.line)
        searchbarlayout.addWidget(self.search_button)
        searchbarlayout.addWidget(self.spinner)
        searchbar = QWidget()
        searchbar.setLayout(searchbarlayout)

        buttonrowlayout = QHBoxLayout()
        buttonrowlayout.addWidget(self.back_button)
        buttonrowlayout.addWidget(self.home_button)
        buttonrowlayout.addWidget(self.play_playlist_button)
        buttonrow = QWidget()
        buttonrow.setLayout(buttonrowlayout)

        downloadrowlayout = QHBoxLayout()
        downloadrowlayout.addWidget(self.download_label)
        downloadrowlayout.addWidget(self.download_selector)
        downloadrowlayout.addWidget(self.play_downloaded_button)
        downloadrow = QWidget()
        downloadrow.setLayout(downloadrowlayout)

        sublayout = QVBoxLayout()
        sublayout.addWidget(searchbar)
        sublayout.addWidget(buttonrow)
        sublayout.addWidget(self.scroll)
        sublayout.addWidget(downloadrow)
        self.left = QWidget()
        self.left.setLayout(sublayout)
        self.left.setFixedWidth(LIST_WIDTH)

        biglayout = QHBoxLayout(self)
        biglayout.addWidget(self.left)
        biglayout.addWidget(self.container)
        biglayout.setContentsMargins(0, 0, 0, 0)

        self.move(int((screenwidth - PLAYER_SIZE.width() - LIST_WIDTH) / 2),
                  int((screenheight - PLAYER_SIZE.height()) / 2))

        # load home page data
        self.spinner.start()

        idx = 'Home'
        worker = Worker(idx, HOME_URL, search=False)
        thread = QThread()
        thread.setObjectName('thread_' + idx)
        worker.moveToThread(thread)

        worker.sig_data.connect(self.on_click_data_received)

        self.sig_abort_workers.connect(worker.abort)

        thread.started.connect(worker.grabData)
        thread.start()
        self.__threads.append((thread, worker))

    def fullscreen(self, blank, blank2):
        if not self.isFullScreen:
            self.left.setFixedWidth(0)
            self.showFullScreen()
            self.isFullScreen = True
            time.sleep(.5)

    def fullscreen_off(self, blank, blank2):
        if self.isFullScreen:
            self.showNormal()
            self.left.setFixedWidth(LIST_WIDTH)
            self.isFullScreen = False
            time.sleep(.5)

    # @pyqtSlot(int)
    # def resizeWindow(self, newheight):
    #     self.setFixedHeight(newheight)

    def clickMethod(self):

        self.spinner.start()

        self.search = self.line.text()
        print('searching "' + self.search + '"...')

        idx = 'clickMethod'
        worker = Worker(idx, self.search)
        thread = QThread()
        thread.setObjectName('thread_' + idx)
        self.__threads.append((thread, worker))
        worker.moveToThread(thread)

        worker.sig_data.connect(self.on_click_data_received)

        self.sig_abort_workers.connect(worker.abort)

        thread.started.connect(worker.grabData)
        thread.start()

    @pyqtSlot(dict)
    def on_click_data_received(self, data):

        self.data = sort_dict_lists_by_list(data, 'titles')

        search_term = self.search

        if len(self.history['data']) == 0:
            title_box = data['page_title']
        elif len(search_term) > 25:
            title_box = 'results: "' + search_term[:22] + '..."'
        else:
            title_box = 'results: "' + search_term + '"'

        if len(self.history['data']) > 0:
            for b in self.inactive_buttons:
                b.setStyleSheet("color: " + FOREGROUND_COLOR +
                                "; background-color: " + BACKGROUND_COLOR +
                                "; border: 1px solid " + FOREGROUND_COLOR +
                                "; font-family: " + FONT + ";")
                b.setCursor(Qt.PointingHandCursor)

        self.history['data'].append(self.data)
        self.history['title_boxes'].append(title_box)
        self.history['urls'].append(self.data['playlist_url'])
        self.history['page_numbers'].append(1)

        self.populate()
        groupbox = QGroupBox(title_box)
        groupbox.setLayout(self.myform)
        groupbox.setStyleSheet("color: " + FOREGROUND_COLOR +
                               "; font-family: " + FONT +
                               ";font-style: italic")
        self.scroll.setWidget(groupbox)
        self.spinner.stop()

    def populate(self):

        labellist = []
        combolist = []
        form = QFormLayout()

        for i, img in enumerate(self.data['thumb_paths']):

            if self.data['titles'][i] is not None:
                title = '\n'.join(
                    textwrap.wrap(self.data['titles'][i], TEXT_LENGTH)[:2])
                if len(self.data['titles'][i]) > TEXT_LENGTH * 2:
                    title = title + '...'
            else:  # catch errors from youtube-dl failing to capture video title
                title = '[TITLE MISSING]'

            text = title + '\n' + self.data['durations'][
                i] + ' | ' + self.data['dates'][i] + '\n' + self.data['views'][
                    i] + ' views | ' + self.data['ratings'][i] + ' likes'

            descLabel = DescriptionLabel(self.data['urls'][i],
                                         self.data['titles'][i])
            descLabel.setText(text)
            descLabel.setMaximumWidth(TEXT_WIDTH)
            descLabel.video_clicked.connect(self.on_video_clicked)
            descLabel.download_clicked.connect(self.on_download_clicked)
            labellist.append(descLabel)

            imagelabel = ImageLabel(self.data['urls'][i],
                                    self.data['titles'][i])
            pixmap = QPixmap(img)
            pixmap = pixmap.scaled(THUMB_SIZE, FLAGS)
            imagelabel.setPixmap(pixmap)
            imagelabel.video_clicked.connect(self.on_video_clicked)
            imagelabel.download_clicked.connect(self.on_download_clicked)
            combolist.append(imagelabel)  #
            form.addRow(combolist[i], labellist[i])

        number_of_pages = math.ceil(self.data['total_videos'] / NUM_RESULTS)

        if number_of_pages > 1:

            current_page = self.history['page_numbers'][-1]
            pages = []

            if current_page <= 3 or number_of_pages <= 5:
                page_range = ['<']
                page_range.extend([i for i in range(1, number_of_pages + 1)])
                page_range.append('>')

            else:
                page_range = ['<', 1]
                if number_of_pages - current_page < 3:
                    page_range.extend([
                        i for i in range(number_of_pages - 3, number_of_pages +
                                         1)
                    ])
                else:
                    page_range.extend([i + current_page - 1 for i in range(4)])
                page_range.append('>')

            for i in page_range:
                active = (i != current_page
                          ) and not (i == '<' and current_page == 1) and not (
                              i == '>' and current_page == number_of_pages)
                page = PageLabel(i, active)
                page.page_clicked.connect(self.get_next_page)
                pages.append(page)

            layout = QHBoxLayout()
            for p in pages:
                layout.addWidget(p)
            page_selector = QWidget()
            page_selector.setLayout(layout)
            form.addRow(QLabel('Pages: '), page_selector)

        self.myform = form

    def exit_seq(self, blank=None, blank2=None):
        app.quit()

    def on_video_clicked(self):

        label = self.sender()
        self.url = label.url
        self.player.play(self.url)
        #self.player.command('show-text', label.title)

    def on_download_clicked(self):

        label = self.sender()

        idx = label.title
        worker = Worker(idx, label.url, label=self.download_label)
        thread = QThread()
        thread.setObjectName('thread_' + idx)
        self.__threads.append(
            (thread,
             worker))  # need to store worker too otherwise will be gc'd
        worker.moveToThread(thread)

        worker.sig_msg.connect(self.on_download_complete)

        self.sig_abort_workers.connect(worker.abort)

        # get read to start worker:
        thread.started.connect(worker.download)
        thread.start(
        )  # this will emit 'started' and start thread's event loop

    @pyqtSlot(str)
    def on_download_complete(self, title):

        title_short = title[:20]

        vid_path = [
            DOWNLOAD_LOCATION + file for file in os.listdir(DOWNLOAD_LOCATION)
            if file.startswith(title)
        ][0]

        self.downloaded_videos['short_titles'].append(title_short)
        self.downloaded_videos['paths'].append(vid_path)

        self.download_label.setText(
            str(len(self.downloaded_videos['paths'])) + ' downloads')
        self.download_label.setStyleSheet("color: " + FOREGROUND_COLOR +
                                          "; background-color: " +
                                          BACKGROUND_COLOR +
                                          "; font-family: " + FONT + ";")

        self.download_selector.insertItem(0, title_short, vid_path)
        self.download_selector.setStyleSheet("color: " + FOREGROUND_COLOR +
                                             "; background-color: " +
                                             BACKGROUND_COLOR +
                                             "; font-family: " + FONT + ";")
        self.download_selector.setCurrentIndex(0)

        self.play_downloaded_button.setStyleSheet("color: " +
                                                  FOREGROUND_COLOR +
                                                  "; background-color: " +
                                                  BACKGROUND_COLOR +
                                                  "; border: 1px solid " +
                                                  FOREGROUND_COLOR +
                                                  "; font-family: " + FONT +
                                                  ";")
        self.play_downloaded_button.setCursor(Qt.PointingHandCursor)

    def on_home_clicked(self):

        if not (HOME_URL in self.history['urls'][-1]
                and self.history['page_numbers'][-1] == 1):
            print('loading homepage...')
            self.search = ''
            self.data = self.history['data'][0]
            self.history['data'].append(self.data)
            self.history['title_boxes'].append(self.data['page_title'])
            self.history['urls'].append(self.data['playlist_url'])
            self.history['page_numbers'].append(1)
            self.populate()
            groupbox = QGroupBox(self.data['page_title'])
            groupbox.setLayout(self.myform)
            groupbox.setStyleSheet("color: " + FOREGROUND_COLOR +
                                   "; font-family: " + FONT +
                                   ";font-style: italic")
            self.scroll.setWidget(groupbox)

            self.home_button.setStyleSheet("color: " + INACTIVE_COLOR +
                                           "; background-color: " +
                                           BACKGROUND_COLOR +
                                           "; border: 1px solid " +
                                           INACTIVE_COLOR + "; font-family: " +
                                           FONT + ";")
            self.home_button.setCursor(Qt.ArrowCursor)

        else:
            print('already home')

    def on_play_playlist_clicked(self):

        self.url = self.history['urls'][-1]
        self.player.play(self.url)

        #TODO: add mpv options to limit playlist items to number of search results

    def on_back_clicked(self):
        if len(self.history['urls']) > 1:
            #self.search = ''
            self.history['urls'].pop(-1)
            self.history['page_numbers'].pop(-1)
            self.history['data'].pop(-1)
            self.data = self.history['data'][-1]
            self.populate()
            self.history['title_boxes'].pop(-1)
            groupbox = QGroupBox(self.history['title_boxes'][-1])
            groupbox.setLayout(self.myform)
            groupbox.setStyleSheet("color: " + FOREGROUND_COLOR +
                                   "; font-family: " + FONT +
                                   ";font-style: italic")
            self.scroll.setWidget(groupbox)
            print('returning to page ' + self.history['urls'][-1] + '...')

            if len(self.history['urls']) == 1:
                for b in self.inactive_buttons:
                    b.setStyleSheet("color: " + INACTIVE_COLOR +
                                    "; background-color: " + BACKGROUND_COLOR +
                                    "; border: 1px solid " + INACTIVE_COLOR +
                                    "; font-family: " + FONT + ";")
                    b.setCursor(Qt.ArrowCursor)
            elif HOME_URL not in self.history['urls'][-1]:
                self.home_button.setStyleSheet("color: " + FOREGROUND_COLOR +
                                               "; background-color: " +
                                               BACKGROUND_COLOR +
                                               "; border: 1px solid " +
                                               FOREGROUND_COLOR +
                                               "; font-family: " + FONT + ";")
                self.home_button.setCursor(Qt.PointingHandCursor)
            else:
                self.home_button.setStyleSheet("color: " + INACTIVE_COLOR +
                                               "; background-color: " +
                                               BACKGROUND_COLOR +
                                               "; border: 1px solid " +
                                               INACTIVE_COLOR +
                                               "; font-family: " + FONT + ";")
                self.home_button.setCursor(Qt.ArrowCursor)
        else:
            print('could not go back')

    def on_play_downloaded(self):

        if len(self.downloaded_videos['paths']) > 0:
            self.player.play(self.download_to_play)

        else:
            print('no videos downloaded yet')

    def select_download(self, index):

        print('queued ' + self.download_selector.itemData(index))
        self.download_to_play = self.download_selector.itemData(index)

    def get_next_page(self):

        self.spinner.start()

        search_term = self.search

        try:
            sender = self.sender()
            if sender.page == '<':
                next_page_number = self.history['page_numbers'][-1] - 1
            elif sender.page == '>':
                next_page_number = self.history['page_numbers'][-1] + 1
            else:
                next_page_number = sender.page

        except:
            next_page_number = self.history['page_numbers'][-1] + 1

        self.history['page_numbers'].append(next_page_number)

        url = self.history['urls'][-1]
        self.history['urls'].append(url)
        title_box = re.sub(r' page \d+$', '', self.history['title_boxes'][-1])
        if next_page_number > 1:
            title_box = title_box[:29] + ' page ' + str(next_page_number)

        self.history['title_boxes'].append(title_box)

        data_limits = [
            NUM_RESULTS * (next_page_number - 1),
            NUM_RESULTS * next_page_number
        ]

        idx = 'get_next_page'
        worker = Worker(idx, url, search=False, limit=data_limits)
        thread = QThread()
        thread.setObjectName('thread_' + idx)
        self.__threads.append((thread, worker))
        worker.moveToThread(thread)

        worker.sig_data.connect(self.on_next_page_received)

        self.sig_abort_workers.connect(worker.abort)

        thread.started.connect(worker.grabData)
        thread.start()

    @pyqtSlot(dict)
    def on_next_page_received(self, data):

        search_term = self.search

        self.data = data

        self.history['data'].append(self.data)

        for b in self.inactive_buttons:
            b.setStyleSheet("color: " + FOREGROUND_COLOR +
                            "; background-color: " + BACKGROUND_COLOR +
                            "; border: 1px solid " + FOREGROUND_COLOR +
                            "; font-family: " + FONT + ";")
            b.setCursor(Qt.PointingHandCursor)

        self.populate()

        groupbox = QGroupBox(self.history['title_boxes'][-1])
        groupbox.setLayout(self.myform)
        groupbox.setStyleSheet("color: " + FOREGROUND_COLOR +
                               "; font-family: " + FONT +
                               ";font-style: italic")
        self.scroll.setWidget(groupbox)
        self.spinner.stop()

    @pyqtSlot()
    def abort_workers(self):
        self.sig_abort_workers.emit()
        for thread, worker in self.__threads:  # note nice unpacking by Python, avoids indexing
            thread.quit(
            )  # this will quit **as soon as thread event loop unblocks**
            thread.wait()  # <- so you need to wait for it to *actually* quit

        # even though threads have exited, there may still be messages on the main thread's
        # queue (messages that threads emitted before the abort):
        self.log.append('All threads exited')
示例#6
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle("GTHEAT 0.2 - A Cool Program")
        self.setStyleSheet("background-color: white;")
        self.resize(1280, 768)
        self.setContentsMargins(3, 3, 3, 3)
        self.setStatusBar(QStatusBar())
        self.statusBar().setStyleSheet("border-top: 1px solid black")
        self.settings = QSettings("GT FRC", "GTHEAT")
        self._markerSize = 14
        self.mainGraph = MplCanvas(self, width=2, height=6, dpi=100)

        self._create_toolbar()

        # Create all the layouts
        self.mainLayout = QVBoxLayout()
        self.mainGraphLayout = QFormLayout()
        self.smallGraphsLayout = QHBoxLayout()
        self.leftPanelLayout = QVBoxLayout()
        self.LeftPanelAndMainLayout = QHBoxLayout()
        self.axesModifierLayout = QGridLayout()
        self.heatVisLayout = QGridLayout()
        self.heatVisFrame = QFrame()
        self.axesModifierFrame = QFrame()
        self.checkboxFrame = QFrame()
        self.checkboxLayout = QGridLayout()
        self.chiExpFrame = QFrame()
        self.chiExpLayout = QVBoxLayout()
        self.leftPanelFrame = QFrame()
        self.checkboxAndAxesModifierLayout = QVBoxLayout()

        # Set main widget and layout
        self.mainGraphLayout.addWidget(self.mainGraph)
        self.mainWidget = QWidget()
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)

        # Set geometries
        self.mainGraphLayout.setGeometry(QRect(220, 159, 551, 501))
        self.checkboxFrame.setMaximumSize(250, 150)
        self.axesModifierFrame.setMaximumSize(250, 150)
        self.smallGraphsLayout.setGeometry(QRect(50, 30, 930, 20))

        # Set widgets
        self._setNoDataGraphs()
        self._create_visc_modifiers()
        self._create_checkboxes()
        self._create_axis_modifiers()
        self._create_exp_checkboxes()

        # Add layouts
        self.checkboxAndAxesModifierLayout.addWidget(self.axesModifierFrame)
        self.checkboxAndAxesModifierLayout.addWidget(self.heatVisFrame)
        self.checkboxAndAxesModifierLayout.addWidget(self.chiExpFrame)
        self.checkboxAndAxesModifierLayout.addWidget(self.checkboxFrame)
        self.leftPanelFrame.setLayout(self.checkboxAndAxesModifierLayout)
        self.leftPanelLayout.addWidget(self.leftPanelFrame)
        self.LeftPanelAndMainLayout.addLayout(self.leftPanelLayout)
        self.LeftPanelAndMainLayout.addLayout(self.mainGraphLayout, stretch=1)
        self.mainLayout.addLayout(self.smallGraphsLayout)
        self.mainLayout.addLayout(self.LeftPanelAndMainLayout)

    def _setNoDataGraphs(self):

        smallHeight = 1
        smallWidth = 3

        self.shotDensityGraphs = MplCanvas(self,
                                           width=smallWidth,
                                           height=smallHeight,
                                           dpi=100)
        self.smallGraphsLayout.addWidget(self.shotDensityGraphs)

        self.shotTempGraph = MplCanvas(self,
                                       width=smallWidth,
                                       height=smallHeight,
                                       dpi=100)
        self.smallGraphsLayout.addWidget(self.shotTempGraph)

        self.shotRadiusGraph = MplCanvas(self,
                                         width=smallWidth,
                                         height=smallHeight,
                                         dpi=100)
        self.smallGraphsLayout.addWidget(self.shotRadiusGraph)

        self.shotVelocityGraph = MplCanvas(self,
                                           width=smallWidth,
                                           height=smallHeight,
                                           dpi=100)
        self.smallGraphsLayout.addWidget(self.shotVelocityGraph)

        self.shotSomethingGraph = MplCanvas(self,
                                            width=smallWidth,
                                            height=smallHeight,
                                            dpi=100)
        self.smallGraphsLayout.addWidget(self.shotSomethingGraph)

    def _setSmallGraphs(self, shot: chi_i):
        """

        :param shot: The chi_i shot data
        """

        plt.close()
        plt.ioff()

        self.shotDensityGraphs.updateFig(shot.rho,
                                         [shot.n.i.fsa, shot.n.e.fsa],
                                         yFormatter=FormatStrFormatter('%.0E'))
        self.shotTempGraph.updateFig(shot.rho,
                                     [shot.T.i.ev.fsa, shot.T.e.ev.fsa],
                                     yFormatter=FormatStrFormatter('%.0E'))
        self.shotRadiusGraph.updateFig(shot.rho,
                                       shot.gyro_rad_ion,
                                       yFormatter=FormatStrFormatter('%.0E'))
        self.shotVelocityGraph.updateFig(shot.rho,
                                         shot.vth,
                                         yFormatter=FormatStrFormatter('%.0E'))
        self.shotSomethingGraph.updateFig(
            shot.rho, shot.vth, yFormatter=FormatStrFormatter('%.0E'))

    def onOpenGT3Started(self, s):
        fileName = QFileDialog.getOpenFileName(self, str("Open File"),
                                               os.getcwd(),
                                               str("GT3 files (*)"))
        if path.exists(fileName[0]):
            self.gt3 = GT3loaderDialog(fileName, parent=self)  # type: QWidget
            self.chi_i = self.gt3.chi_i  # type: chi_i
            self.shot = self.gt3.shot  # type: gt3
            self.rho = self.gt3.rho
            self._setSmallGraphs(self.chi_i)
            self.mainGraph.updateFig(self.rho,
                                     self.shot.rtrans.chi.i.chi4,
                                     yFormatter=FormatStrFormatter('%.1f'))
            xAxisMin = self.XAxisMin.value()
            xAxisMax = self.XAxisMax.value()
            yAxisMin = self.YAxisMin.value()
            yAxisMax = self.YAxisMax.value()
            self.mainGraph.axes.set_xlim((xAxisMin, xAxisMax))
            self.mainGraph.axes.set_ylim((yAxisMin, yAxisMax))
            self.setCentralWidget(self.mainWidget)
            self._enable_checkboxes(True)
            self._enable_axis_modifiers(True)
            self._enable_exp_checkboxes(True)
            self.save_fig_action.setEnabled(True)
            # Enable Shot Data file menu
            self.open_velocity_graphs_action.setEnabled(True)
            self.open_temperature_graphs_action.setEnabled(True)
            self.open_scale_length_graphs_action.setEnabled(True)
            self.open_flux_graphs_action.setEnabled(True)
            self.open_electric_field_action.setEnabled(True)
            self.open_collisionality_action.setEnabled(True)
            self.open_density_graph_action.setEnabled(True)
        else:
            pass

    def _createSpinner(self):
        self.spinner = QtWaitingSpinner(parent=self)
        self.spinner.setRoundness(70.0)
        self.spinner.setMinimumTrailOpacity(15.0)
        self.spinner.setTrailFadePercentage(70.0)
        self.spinner.setNumberOfLines(12)
        self.spinner.setLineLength(10)
        self.spinner.setLineWidth(5)
        self.spinner.setInnerRadius(10)
        self.spinner.setRevolutionsPerSecond(1)
        self.spinner.setColor(QColor(81, 4, 71))

    # def createMainGraph(self):
    #
    #     self.graphWidget = pg.PlotWidget()
    #     self.graphWidget.setBackground('w')
    #     self.graphWidget.setXRange(0.85, 1.0)

    def mainReplot(self, int):
        neo = self.neoCheckbox.isChecked()
        itg12 = self.itg12Checkbox.isChecked()
        itg32 = self.itg32Checkbox.isChecked()
        gyro = self.gyroBohmCheckbox.isChecked()
        DA = self.driftAlfenCheckbox.isChecked()
        sum = self.combinedCheckbox.isChecked()
        chi1 = self.chi1RadioButton.isChecked()
        chi2 = self.chi2RadioButton.isChecked()
        chi3 = self.chi3RadioButton.isChecked()
        chi4 = self.chi4RadioButton.isChecked()
        chiAll = self.chiShowAllButton.isChecked()
        viscTor = self.heatVisTor.value()
        viscPol = self.heatVisPol.value()
        viscChi = self.shot.rtrans._calc_chi_i_visc(vpolS=viscPol,
                                                    vtorS=viscTor)
        s = self._markerSize
        if chiAll:
            self.mainGraph.updateFig(self.rho,
                                     None,
                                     color="black",
                                     keepLims=True,
                                     yFormatter=FormatStrFormatter('%.1f'))
            self.mainGraph.add_scatter(self.rho,
                                       self.shot.rtrans.chi.i.chi1,
                                       color="red",
                                       marker="x",
                                       s=s)
            self.mainGraph.add_scatter(self.rho,
                                       self.shot.rtrans.chi.i.chi2,
                                       color="green",
                                       marker="X",
                                       s=s)
            self.mainGraph.add_scatter(self.rho,
                                       self.shot.rtrans.chi.i.chi3,
                                       color="blue",
                                       marker="^",
                                       s=s)
            self.mainGraph.add_scatter(self.rho,
                                       viscChi,
                                       color="black",
                                       marker="2",
                                       s=s)
        else:
            if chi1:
                self.mainGraph.updateFig(self.rho,
                                         self.shot.rtrans.chi.i.chi1,
                                         yFormatter=FormatStrFormatter('%.1f'),
                                         keepLims=True,
                                         color="red",
                                         marker="x",
                                         s=s)
            if chi2:
                self.mainGraph.updateFig(self.rho,
                                         self.shot.rtrans.chi.i.chi2,
                                         yFormatter=FormatStrFormatter('%.1f'),
                                         keepLims=True,
                                         color="green",
                                         marker="X",
                                         s=s)
            if chi3:
                self.mainGraph.updateFig(self.rho,
                                         self.shot.rtrans.chi.i.chi3,
                                         yFormatter=FormatStrFormatter('%.1f'),
                                         keepLims=True,
                                         color="blue",
                                         marker="^",
                                         s=s)
            if chi4:
                self.mainGraph.updateFig(self.rho,
                                         viscChi,
                                         yFormatter=FormatStrFormatter('%.1f'),
                                         keepLims=True,
                                         color="black",
                                         marker="2",
                                         s=s)

        if sum:
            self.mainGraph.add_scatter(self.rho,
                                       self.chi_i.plot_chis_custom(neo=neo,
                                                                   bohm=gyro,
                                                                   itg12=itg12,
                                                                   itg32=itg32,
                                                                   DA=DA,
                                                                   sum=True,
                                                                   show=False),
                                       color="red")
        else:
            if neo:
                self.mainGraph.add_scatter(self.rho,
                                           self.chi_i.neo_chi,
                                           color="red",
                                           s=s)
            if itg12:
                self.mainGraph.add_scatter(self.rho,
                                           self.chi_i.chi_itg_TS_12,
                                           color="green",
                                           s=s)
            if itg32:
                self.mainGraph.add_scatter(self.rho,
                                           self.chi_i.chi_itg_TS_32,
                                           color="purple",
                                           s=s)
            if DA:
                self.mainGraph.add_scatter(self.rho,
                                           self.chi_i.chi_DA,
                                           color="yellow",
                                           s=s)
            if gyro:
                self.mainGraph.add_scatter(self.rho,
                                           self.chi_i.gyro_bohm,
                                           color="blue",
                                           s=s)

    def _create_visc_modifiers(self):

        self.heatVisTor = QDoubleSpinBox()
        self.heatVisPol = QDoubleSpinBox()

        self.heatVisTorLabel = MathTextLabel(r"$V_{\phi}^s$", 14)
        self.heatVisPolLabel = MathTextLabel(r"$V_{\theta}^s$", 14)

        self.heatVisTor.setSingleStep(0.01)
        self.heatVisTor.setRange(-1.0, 1.0)
        self.heatVisTor.setValue(0.1)

        self.heatVisPol.setSingleStep(0.01)
        self.heatVisPol.setRange(-1.0, 1.0)
        self.heatVisPol.setValue(0.1)

        self.heatVisTor.valueChanged.connect(self.mainReplot)
        self.heatVisPol.valueChanged.connect(self.mainReplot)

        self.heatVisLayout.addWidget(self.heatVisTorLabel, 0, 0)
        self.heatVisLayout.addWidget(self.heatVisPolLabel, 0, 1)
        self.heatVisLayout.addWidget(self.heatVisTor, 1, 0)
        self.heatVisLayout.addWidget(self.heatVisPol, 1, 1)
        self.heatVisFrame.setLayout(self.heatVisLayout)
        #self.heatVisLayout.setAlignment(Qt.AlignVCenter)
        self.heatVisFrame.setFrameStyle(QFrame.StyledPanel)
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(15)
        self.heatVisFrame.setGraphicsEffect(shadow)

    def _create_axis_modifiers(self):

        self.XAxisMin = QDoubleSpinBox()
        self.XAxisMin.setSingleStep(0.01)
        self.XAxisMin.setRange(0.0, 1.0)
        self.XAxisMin.setValue(0.85)

        self.XAxisMax = QDoubleSpinBox()
        self.XAxisMax.setRange(0.0, 1.0)
        self.XAxisMax.setSingleStep(0.01)
        self.XAxisMax.setValue(1.0)

        self.YAxisMax = QDoubleSpinBox()
        self.YAxisMax.setSingleStep(1.0)
        self.YAxisMax.setValue(10.0)
        self.YAxisMax.setMaximum(1000.)

        self.YAxisMin = QDoubleSpinBox()
        self.YAxisMin.setSingleStep(1.0)
        self.YAxisMin.setMinimum(-100.)
        self.YAxisMin.setValue(0.0)

        self.LogScale = QCheckBox()
        self.LogScale.setChecked(False)

        self.XAxisLabel = QLabel("X-axis")
        self.YAxisLabel = QLabel("Y-axis")
        self.LogAxisLabel = QLabel("Log Scale")

        self.XAxisMin.valueChanged.connect(self.mainGraph.updateXMin)
        self.XAxisMax.valueChanged.connect(self.mainGraph.updateXMax)
        self.YAxisMin.valueChanged.connect(self.mainGraph.updateYMin)
        self.YAxisMax.valueChanged.connect(self.mainGraph.updateYMax)
        self.LogScale.stateChanged.connect(self.mainGraph.set_logPlot)

        self.axesModifierLayout.addWidget(self.XAxisLabel, 0, 0)
        self.axesModifierLayout.addWidget(self.XAxisMin, 1, 0)
        self.axesModifierLayout.addWidget(self.XAxisMax, 1, 1)
        self.axesModifierLayout.addWidget(self.YAxisLabel, 2, 0)
        self.axesModifierLayout.addWidget(self.YAxisMin, 3, 0)
        self.axesModifierLayout.addWidget(self.YAxisMax, 3, 1)
        self.axesModifierLayout.addWidget(self.LogAxisLabel, 0, 2)
        self.axesModifierLayout.addWidget(self.LogScale, 1, 2)
        self.axesModifierLayout.setAlignment(Qt.AlignVCenter)
        self.axesModifierFrame.setLayout(self.axesModifierLayout)
        self.axesModifierFrame.setFrameStyle(QFrame.StyledPanel)
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(15)
        self.axesModifierFrame.setGraphicsEffect(shadow)

        self._enable_axis_modifiers(False)

    def _enable_checkboxes(self, en=True):
        self.neoCheckbox.setEnabled(en)
        self.gyroBohmCheckbox.setEnabled(en)
        self.itg12Checkbox.setEnabled(en)
        self.itg32Checkbox.setEnabled(en)
        self.driftAlfenCheckbox.setEnabled(en)
        self.combinedCheckbox.setEnabled(en)

    def _enable_exp_checkboxes(self, en=True):
        self.chi1RadioButton.setEnabled(en)
        self.chi2RadioButton.setEnabled(en)
        self.chi3RadioButton.setEnabled(en)
        self.chi4RadioButton.setEnabled(en)
        self.chiShowAllButton.setEnabled(en)

    def _enable_axis_modifiers(self, en=True):
        self.XAxisMin.setEnabled(en)
        self.XAxisMax.setEnabled(en)
        self.YAxisMin.setEnabled(en)
        self.YAxisMax.setEnabled(en)

    def _create_checkboxes(self):

        self.combinedCheckbox = QCheckBox(text="Sum Exp. Chis")
        self.neoCheckbox = QCheckBox(text="Neoclassical")
        self.neoCheckbox.setStyleSheet("color: red")

        self.gyroBohmCheckbox = QCheckBox(text="Gyro-Bohm")
        self.gyroBohmCheckbox.setStyleSheet("color: blue")

        self.itg12Checkbox = QCheckBox(text="ITG (1/2)")
        self.itg12Checkbox.setStyleSheet("color: green")

        self.itg32Checkbox = QCheckBox(text="ITG (3/2)")
        self.itg32Checkbox.setStyleSheet("color:purple")

        self.driftAlfenCheckbox = QCheckBox(text="Drift-Alfven")
        self.driftAlfenCheckbox.setStyleSheet("color: yellow")

        self._enable_checkboxes(False)

        self.combinedCheckbox.stateChanged.connect(self.mainReplot)
        self.neoCheckbox.stateChanged.connect(self.mainReplot)
        self.itg32Checkbox.stateChanged.connect(self.mainReplot)
        self.itg12Checkbox.stateChanged.connect(self.mainReplot)
        self.gyroBohmCheckbox.stateChanged.connect(self.mainReplot)
        self.driftAlfenCheckbox.stateChanged.connect(self.mainReplot)

        self.checkboxLayout.addWidget(self.neoCheckbox, 0, 0)
        self.checkboxLayout.addWidget(self.gyroBohmCheckbox, 0, 1)
        self.checkboxLayout.addWidget(self.itg12Checkbox, 1, 0)
        self.checkboxLayout.addWidget(self.itg32Checkbox, 1, 1)
        self.checkboxLayout.addWidget(self.driftAlfenCheckbox, 2, 0)
        self.checkboxLayout.addWidget(self.combinedCheckbox, 2, 1)
        self.checkboxLayout.setAlignment(Qt.AlignVCenter)

        self.checkboxFrame.setLayout(self.checkboxLayout)
        self.checkboxFrame.setFrameStyle(QFrame.StyledPanel)
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(15)
        self.checkboxFrame.setGraphicsEffect(shadow)

    def _create_exp_checkboxes(self):
        self.chi1RadioButton = QRadioButton(r"$q^{cond} = Q^{tot}$")
        self.chi2RadioButton = QRadioButton(r"$q^{cond} = Q^{tot} - Q^{conv}$")
        self.chi3RadioButton = QRadioButton(
            r"$q^{cond} = Q^{tot} - Q^{conv} - Q^{heatin}$")
        self.chi4RadioButton = QRadioButton(
            r"$q^{cond} = Q^{tot} - Q^{conv} - Q^{heatin} - Q^{visc}$")
        self.chiShowAllButton = QRadioButton("Show All")
        self.chiShowAllButton.setChecked(True)

        # self.chi1RadioButton = QCheckBox(r"$q^{cond} = Q^{tot}$")
        # self.chi2RadioButton = QCheckBox(r"$q^{cond} = Q^{tot} - Q^{conv}$")
        # self.chi3RadioButton = QCheckBox(r"$q^{cond} = Q^{tot} - Q^{conv} - Q^{heatin}$")
        # self.chi4RadioButton = QCheckBox(r"$q^{cond} = Q^{tot} - Q^{conv} - Q^{heatin} - Q^{visc}$")
        # self.chiShowAllButton = QCheckBox("Show All")

        self.chi1RadioButton.setStyleSheet("color: red")
        self.chi2RadioButton.setStyleSheet("color: green")
        self.chi3RadioButton.setStyleSheet("color: blue")
        self.chi4RadioButton.setStyleSheet("color: black")
        self._enable_exp_checkboxes(False)

        self.chi1RadioButton.toggled.connect(self.mainReplot)
        self.chi2RadioButton.toggled.connect(self.mainReplot)
        self.chi3RadioButton.toggled.connect(self.mainReplot)
        self.chi4RadioButton.toggled.connect(self.mainReplot)
        self.chiShowAllButton.toggled.connect(self.mainReplot)

        self.chiExpLayout.addWidget(self.chi1RadioButton)
        self.chiExpLayout.addWidget(self.chi2RadioButton)
        self.chiExpLayout.addWidget(self.chi3RadioButton)
        self.chiExpLayout.addWidget(self.chi4RadioButton)
        self.chiExpLayout.addWidget(self.chiShowAllButton)
        self.chiExpLayout.setAlignment(Qt.AlignVCenter)

        self.chiExpFrame.setLayout(self.chiExpLayout)
        self.chiExpFrame.setFrameStyle(QFrame.StyledPanel)
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(15)
        self.chiExpFrame.setGraphicsEffect(shadow)

    def _create_toolbar(self):
        # Set the toolbar
        self.toolbar = QToolBar("The Main Toolbar")

        #Set icon size
        self.toolbar.setIconSize(QSize(16, 16))

        # Create the toolbar
        self.toolbar = QToolBar("GTHEAT Toolbar")

        # Set icon size
        self.toolbar.setIconSize(QSize(16, 16))
        self.addToolBar(self.toolbar)

        # Create actions
        self.open_GT3_action = QAction("Open GT3 File", self)
        self.open_GT3_action.setIcon(self.style().standardIcon(
            QStyle.SP_DirOpenIcon))
        self.open_GT3_action.setStatusTip("Open a GT3 File")
        self.open_GT3_action.triggered.connect(self.onOpenGT3Started)

        self.save_fig_action = QAction("Save Figure", self)
        self.save_fig_action.setIcon(self.style().standardIcon(
            QStyle.SP_DialogSaveButton))
        self.save_fig_action.setStatusTip("Save Figure")
        self.save_fig_action.triggered.connect(self.saveFigureDialog)
        self.save_fig_action.setEnabled(False)

        self.set_preferences_action = QAction("Set Preferences", self)
        self.set_preferences_action.setStatusTip("Set Preferences")
        self.set_preferences_action.triggered.connect(self.set_preferences)

        self.open_velocity_graphs_action = QAction("Velocity Graphs", self)
        self.open_velocity_graphs_action.setStatusTip("Velocity Graphs")
        self.open_velocity_graphs_action.triggered.connect(
            self.open_velocity_graphs)
        self.open_velocity_graphs_action.setEnabled(False)

        self.open_temperature_graphs_action = QAction("Temperature Graphs",
                                                      self)
        self.open_temperature_graphs_action.setStatusTip("Temperature Graphs")
        self.open_temperature_graphs_action.triggered.connect(
            self.open_temperature_graphs)
        self.open_temperature_graphs_action.setEnabled(False)

        self.open_scale_length_graphs_action = QAction(
            "Gradient Scale Lengths", self)
        self.open_scale_length_graphs_action.setStatusTip(
            "Gradient Scale Lengths")
        self.open_scale_length_graphs_action.triggered.connect(
            self.open_scale_length_graphs)
        self.open_scale_length_graphs_action.setEnabled(False)

        self.open_flux_graphs_action = QAction("Particle and Heat Fluxes",
                                               self)
        self.open_flux_graphs_action.setStatusTip("Particle and Heat Fluxes")
        self.open_flux_graphs_action.triggered.connect(self.open_flux_graphs)
        self.open_flux_graphs_action.setEnabled(False)

        self.open_electric_field_action = QAction("Electric field")
        self.open_electric_field_action.setStatusTip("Radial electric field")
        self.open_electric_field_action.triggered.connect(
            self.open_electric_field_graphs)
        self.open_electric_field_action.setEnabled(False)

        self.open_collisionality_action = QAction("Collisionality")
        self.open_collisionality_action.setStatusTip("Collisionality")
        self.open_collisionality_action.triggered.connect(
            self.open_collisionality_graphs)
        self.open_collisionality_action.setEnabled(False)

        self.open_density_graph_action = QAction("Densities")
        self.open_density_graph_action.setStatusTip("Density profiles")
        self.open_density_graph_action.triggered.connect(
            self.open_density_graphs)
        self.open_density_graph_action.setEnabled(False)

        exitAct = QAction(QIcon('exit.png'), '&Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(qApp.quit)

        #Add toolbar actions
        self.toolbar.addAction(self.open_GT3_action)
        self.toolbar.addAction(self.save_fig_action)

        menu = self.menuBar()
        menu.setNativeMenuBar(False)

        file_menu = menu.addMenu(u"&File")
        file_menu.addAction(self.open_GT3_action)
        file_menu.addAction(exitAct)

        edit_menu = menu.addMenu(u"&Edit")
        edit_menu.addAction(self.set_preferences_action)

        shot_menu = menu.addMenu(u"&Shot Data")
        shot_menu.addAction(self.open_velocity_graphs_action)
        shot_menu.addAction(self.open_temperature_graphs_action)
        shot_menu.addAction(self.open_scale_length_graphs_action)
        shot_menu.addAction(self.open_flux_graphs_action)
        shot_menu.addAction(self.open_electric_field_action)
        shot_menu.addAction(self.open_density_graph_action)
        shot_menu.addAction(self.open_collisionality_action)

    def open_velocity_graphs(self):

        velocities = [
            GraphContainer(self.chi_i.rho, [
                self.chi_i.shot.rtrans.vpol_D.val,
                self.chi_i.shot.rtrans.vpol_C.val
            ],
                           title="Poloidal Velocity",
                           legend=[r"$V^D_{\theta}$", r"$V^C_{\theta}$"]),
            GraphContainer(self.chi_i.rho, [
                self.chi_i.shot.rtrans.vtor_C_total.val,
                self.chi_i.shot.rtrans.vtor_D_total.val
            ],
                           title="Toroidal Velocity",
                           legend=[r"$V^D_{\phi}$", r"$V^C_{\phi}$"])
        ]
        velocity_graph = GraphPopout(velocities,
                                     grid=len(velocities),
                                     title="Shot Velocities")
        velocity_graph.show()

    def open_density_graphs(self):

        densities = [
            GraphContainer(self.chi_i.rho, [
                self.chi_i.shot.rtrans._n.D.val /
                (1E20), self.chi_i.shot.rtrans._n.e.val / (1E20)
            ],
                           title="Densities",
                           legend=[r"$n_D$", r"$n_e$"])
        ]
        density_graph = GraphPopout(densities,
                                    grid=len(densities),
                                    title="Density (x10^20 m^-3)")
        density_graph.show()

    def open_temperature_graphs(self):

        temperatures = [
            GraphContainer(self.chi_i.rho, [
                self.chi_i.shot.core.T.i.ev.fsa.val,
                self.chi_i.shot.core.T.e.ev.fsa.val
            ],
                           title="Temperatures",
                           legend=[r"$T_i$", r"$T_e$"])
        ]
        temperature_graph = GraphPopout(temperatures,
                                        grid=len(temperatures),
                                        title="Shot Temperatures")
        temperature_graph.show()

    def open_scale_length_graphs(self):

        scale_lengths = [
            GraphContainer(
                self.chi_i.rho,
                [self.chi_i.T.i.J.L.fsa.val, self.chi_i.T.e.J.L.fsa.val],
                title="Scale Lengths",
                legend=[r"$L_{T_i}$", r"$L_{T_e}$"]),
            GraphContainer(
                self.chi_i.rho,
                [self.chi_i.n.i.L.fsa.val, self.chi_i.n.e.L.fsa.val],
                title="Scale Lengths",
                legend=[r"$L_{n_i}$", r"$L_{n_e}$"])
        ]
        scale_length_graph = GraphPopout(scale_lengths,
                                         grid=len(scale_lengths),
                                         title="Gradient Scale Lengths")
        scale_length_graph.show()

    def open_flux_graphs(self):

        fluxes = [
            GraphContainer(self.chi_i.rho,
                           [self.chi_i.shot.rtrans.gamma.D.diff.val / (1E20)],
                           title="Ion Particle Flux",
                           legend=[r"$\Gamma_{j,r}[10E20]$"]),
            GraphContainer(self.chi_i.rho,
                           [self.chi_i.shot.rtrans.Q.D.diff.val],
                           title="Heat Flux",
                           legend=[r"$Q_{r,j}$"])
        ]
        flux_graphs = GraphPopout(fluxes,
                                  grid=len(fluxes),
                                  title="Particle/Heat fluxes")
        flux_graphs.show()

    def open_electric_field_graphs(self):

        field = [
            GraphContainer(self.chi_i.rho, [self.chi_i.shot.core.E_r.fsa],
                           title="Electric Field",
                           legend=[r"$E_r$"])
        ]
        field_graphs = GraphPopout(field,
                                   grid=len(field),
                                   title="Electric Field")
        field_graphs.show()

    def open_collisionality_graphs(self):

        field = [
            GraphContainer(self.chi_i.rho, [self.chi_i.shot.rtrans.nustar],
                           title="Collisionality",
                           legend=[r"$\nu^*$"])
        ]
        field_graphs = GraphPopout(field,
                                   grid=len(field),
                                   title="Collisionality")
        field_graphs.show()

    def saveFigureDialog(self):

        #f = QFileDialog.getOpenFileName(self, str("Save Figure"), os.getcwd(), str("Image Files (*)"))
        f = QFileDialog.getSaveFileName(self, str("Save Figure"), os.getcwd(),
                                        str("PNG (.png)"))
        self.mainGraph._saveFig(f[0])

    def set_preferences(self, triggered):
        settings = self.settings
        preferences_dialog = PreferencesDialog()
        preferences_dialog.setupUi(self)
        if preferences_dialog.exec_():
            print("YAY")
        else:
            print("F**K")