Esempio n. 1
0
class TestApp(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.studFrame = QFrame()
        self._s = Stud()
        self._s.setupUi(self.studFrame)
        self.settFrame = QFrame()
        self._set = Settings()
        self._set.setupUi(self.settFrame)
        self.info = self.ui.infoLine
        self.q1 = self.ui.question
        self.a_dic = {
            1: self.ui.answer1,
            2: self.ui.answer2,
            3: self.ui.answer3,
            4: self.ui.answer4,
            5: self.ui.answer5
        }
        self.ch_dic = {
            1: self.ui.checkBox1,
            2: self.ui.checkBox2,
            3: self.ui.checkBox3,
            4: self.ui.checkBox4,
            5: self.ui.checkBox5
        }
        self.next = self.ui.next
        self.print = self.ui.print
        self.open = self.ui.open
        self.settings = self.ui.settings
        self.exit = self.ui.exit
        self.about = self.ui.about
        self.bar = self.ui.statusbar
        self.btnStud = self._s.buttonBox
        self.lineStud = self._s.student
        self.next.clicked.connect(self.fileOpen)
        self.print.clicked.connect(self.printer)
        self.open.triggered.connect(self.fileOpen)
        self.settings.triggered.connect(self.settFrameShow)
        self.about.triggered.connect(self.aboutMenu)
        self.exit.triggered.connect(sys.exit)
        self.q1.hide()
        self.info.hide()
        self.print.hide()
        for a in self.a_dic.values():
            a.hide()
        for ch in self.ch_dic.values():
            ch.hide()
        self.rep_key = QShortcut(QtGui.QKeySequence("Ctrl+R"), self)
        self.rep_key.activated.connect(self.openRep)
        self.ui.centralwidget.setStyleSheet('background: url(bkgnd.png)')
        self.font1 = QFont("Comic Sans Ms", 20, QFont.DemiBold, QFont.AnyStyle)
        self.font2 = QFont("Arial Rounded MT Bold", 25, QFont.Bold)

    def fileOpen(self):
        # Open test file and create question-answer dictionary
        f_dialog = QFileDialog()
        f_dialog.setFileMode(QFileDialog.AnyFile)
        f_dialog.setNameFilter("Text (*.txt)")
        if f_dialog.exec_():
            self.file_name = f_dialog.selectedFiles()[0]
            self.test = {}
            try:
                with open(self.file_name, 'r', encoding='utf-8') as f:
                    lines = f.readlines()
            except Exception:
                with open(self.file_name, 'r', encoding='cp1251') as f:
                    lines = f.readlines()
                pass
            for line in lines:
                try:
                    if not 'Name' in lines[0]:
                        self.test_name = 'Не найдено название теста'
                    elif 'Name' in line[:5]:
                        self.test_name = line[6:]
                except Exception:
                    pass
            n = 0
            t = []
            test_dic = dict.fromkeys(
                ('Qs', 'A1', 'A2', 'A3', 'A4', 'A5', 'An'), 0)
            for line in lines:
                for k in test_dic.keys():
                    if k in line[:3]:
                        t.append(line)
                        if 'An' in line[:3]:
                            self.test.update({n: t})
                            n += 1
                            t = []
            self.q1.show()
            self.q1.setText("\n\n" + self.test_name)
            self.q1.setStyleSheet("")
            self.q1.setFrameStyle(QFrame.NoFrame)
            self.next.clicked.disconnect()
            self.next.setText('Далее')
            self.next.clicked.connect(self.studSet)
            self.print.hide()
            self.ui.menubar.hide()
            self.ui.centralwidget.setStyleSheet('background: url(bkgnd.png)')
        else:
            self.close()

    def studSet(self):
        # Student name input frame
        self.studFrame.show()
        application.hide()
        self.next.clicked.disconnect()
        self.btnStud.accepted.connect(self.testInit)
        self.btnStud.rejected.connect(self.studFrame.hide)
        self.btnStud.rejected.connect(self.close)

    def testInit(self):
        self.settRead()
        # Define variables
        self.fin = False
        self.q_num_list = []
        self.result = 0
        self.percent = 0
        self.q_count = 0
        self.spent_time = False
        self.student = self.lineStud.text().title()
        try:
            # Check if questions in settings not exceed questions in self.test dictionary
            if self.q_try > len(self.test):
                self.q_try = len(self.test)
            # Vars for messagebar (random and color)
            if self.rand:
                self.ifrand = 'ВКЛ'
            else:
                self.ifrand = 'ОТКЛ'
            if self.color:
                self.ifcolor = 'ВКЛ'
            else:
                self.ifcolor = 'ОТКЛ'
            self.studFrame.hide()
            application.show()
            self.q1.setFont(self.font1)
            self.q1.setText("\n\n\n" + self.student +
                            ", желаю удачи в прохождении теста:\n" +
                            self.test_name)
            self.next.setText("Поехали!")
            self.next.clicked.connect(self.testMain)
        except Exception as e:
            pass

    def testMain(self):
        if not self.spent_time:
            self.start_time = time.time()
            self.timeSpent()
        self.info.hide()
        for a in self.a_dic.values():
            a.hide()
        for ch in self.ch_dic.values():
            ch.hide()
            ch.setChecked(False)
        if self.q_try:
            if not self.rand:
                self.q_num = self.q_count
            else:
                self.q_num = random.choice(list(self.test))
                if self.q_num in self.q_num_list:
                    while self.q_num in self.q_num_list:
                        self.q_num = random.choice(list(self.test))
                self.q_num_list.append(self.q_num)
            try:
                tek = self.test[self.q_num]
                question = tek[0][3:]
                frame = 1
                for k, a in self.a_dic.items():
                    try:
                        tek_a = tek[k]
                        if 'An' in tek_a:
                            pass
                        else:
                            a.setText(tek_a[3:])
                            frame += 1
                    except IndexError:
                        pass
                key = [int(i) for i in tek[-1][3:].split()]
                key.sort()
                for i in range(1, frame):
                    a = self.a_dic[i]
                    a.show()
                    a.setStyleSheet("")
                    ch = self.ch_dic[i]
                    ch.show()
                self.q1.setFont(self.font2)
                self.q1.setText(question)
                if len(key) > 1:
                    self.info.setText('Выберите несколько вариантов ответа')
                elif len(key) <= 1:
                    self.info.setText('Выберите один вариант ответа')
                self.info.show()
                self.q1.setFrameShape(QFrame.WinPanel)
                self.q1.setStyleSheet("background-color:rgb(91, 213, 89)")
                self.ui.centralwidget.setStyleSheet(" ")
                self.next.setText("Далее")
                self.next.clicked.disconnect()
                self.next.clicked.connect(lambda: self.answerCheck(key))
            except KeyError:
                tek = ['*** No more question', '', '', '', '']
                self.finish()
        else:
            self.finish()

    def answerCheck(self, key):
        self.q_count += 1
        self.q_try -= 1
        answer = []
        for k, v in self.ch_dic.items():
            if v.isChecked():
                answer.append(k)
        if key == answer:
            self.result += 1
        else:
            self.q1.setStyleSheet("background-color: rgb(255, 0, 0)")
        if self.color == 1:
            for i in key:
                a = self.a_dic[i]
                a.setStyleSheet("background-color:rgb(91, 213, 89)")
        if self.q_count == 0:
            p = 0
        else:
            p = self.result * 100 / self.q_count
        self.percent = float("%.1f" % p)
        QTimer.singleShot(self.color_time * 1000, self.testMain)

    def finish(self):
        self.fin = True
        for a in self.a_dic.values():
            a.hide()
        for ch in self.ch_dic.values():
            ch.hide()
        self.day = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        if self.percent >= self.mark_5:
            self.mark = '5'
        elif self.percent >= self.mark_4:
            self.mark = '4'
        elif self.percent >= self.mark_3:
            self.mark = '3'
        elif self.percent >= self.mark_2:
            self.mark = '2'
        else:
            self.mark = '1'
        if int(self.mark) > 3:
            self.q1.setStyleSheet("background-color:rgb(91, 213, 89)")
        else:
            self.q1.setStyleSheet("background-color: rgb(255, 0, 0)")
        self.rep = ("Дата: " + self.day + "\nТестируемый: " + self.student +
                    "\nТема: " + self.test_name + "\nПравильных ответов: " +
                    str(self.result) + "\nВсего вопросов: " +
                    str(self.q_count) + "\nЗатрачено времени: " +
                    str(self.spent_time) + " мин."
                    "\nРезультативность: " + str(self.percent) + "%"
                    "\nОценка: " + self.mark + "\n\n")
        with open('report.txt', 'a', encoding='utf-8') as f_rep:
            f_rep.write(self.rep)
        self.q1.setText(self.rep)
        self.next.show()
        self.print.show()
        self.next.clicked.disconnect()
        self.next.setText("Закончить")
        self.next.clicked.connect(self.close)
        self.ui.menubar.show()

    def openRep(self):
        try:
            subprocess.Popen(['notepad.exe', r'report.txt'])
        except Exception as e:
            self.q1.show()
            self.q1.setText(str(e))

    def settFrameShow(self):
        self.settRead()
        try:
            if self.color == 1:
                self._set.colBox.setChecked(True)
                self._set.colTimeLine.setText(str(self.color_time))
            if self.rand == 1:
                self._set.ranBox.setChecked(True)
            self._set.tryLine.setText(str(self.q_try))
            self._set.mark5Line.setText(str(self.mark_5))
            self._set.mark4Line.setText(str(self.mark_4))
            self._set.mark3Line.setText(str(self.mark_3))
            self._set.mark2Line.setText(str(self.mark_2))
            self.settFrame.show()
            self._set.buttonBox.accepted.connect(self.settWrite)
            self._set.buttonBox.rejected.connect(self.settFrame.close)
        except Exception as e:
            pass

    def settWrite(self):
        if self._set.colBox.isChecked():
            self.color = 1
            self.color_time = self._set.colTimeLine.text()
        else:
            self.color = 0
            self.color_time = 0
        if self._set.ranBox.isChecked():
            self.rand = 1
        else:
            self.rand = 0
        self.q_try = self._set.tryLine.text()
        self.mark_5 = self._set.mark5Line.text()
        self.mark_4 = self._set.mark4Line.text()
        self.mark_3 = self._set.mark3Line.text()
        self.mark_2 = self._set.mark2Line.text()
        settings = [
            self.color, self.color_time, self.rand, self.q_try, self.mark_5,
            self.mark_4, self.mark_3, self.mark_2
        ]
        with open("settings.ini", "w", encoding='utf-8') as f:
            for i in settings:
                f.write("%s " % i)
        self.settFrame.close()

    def settRead(self):
        # Settings read from ini file
        try:
            with open('settings.ini', 'r', encoding='utf-8') as f:
                line = f.readline().split()
                line = [int(l) for l in line]
            self.color = line[0]
            self.color_time = line[1]
            self.rand = line[2]
            self.q_try = line[3]
            self.mark_5 = line[4]
            self.mark_4 = line[5]
            self.mark_3 = line[6]
            self.mark_2 = line[7]
        except Exception as e:
            self.settFrame.show()
            self._set.buttonBox.accepted.connect(self.settWrite)
            self._set.buttonBox.rejected.connect(self.settFrame.close)

    def timeSpent(self):
        if not self.fin:
            t = int(time.time()) - int(self.start_time)
            if t >= 60:
                tm = int(t / 60)
                ts = t - tm * 60
            else:
                tm = 0
                ts = t
            if ts < 10:
                self.spent_time = str(tm) + ":0" + str(ts)
            else:
                self.spent_time = str(tm) + ":" + str(ts)
            self.bar.showMessage("Время " + self.spent_time + "  Тест: " +
                                 self.test_name + "  Вопрос №" +
                                 str(self.q_count + 1) + "  Результат: " +
                                 str(self.percent) + "%  Студент " +
                                 self.student + "  Вопросов " +
                                 str(self.q_try) + "  Случайно " +
                                 self.ifrand + "  Контроль " + self.ifcolor)
            QTimer.singleShot(500, self.timeSpent)
        else:
            self.bar.showMessage(" ")

    def printer(self):
        with open('temp.txt', 'w', encoding='utf-8') as f:
            f.write(self.rep)
        os.startfile("temp.txt", "print")
        time.sleep(3)
        os.remove("temp.txt")

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            try:
                self.finish()
            except AttributeError:
                pass
            self.close()

    def aboutMenu(self):
        self.q1.setFont(self.font1)
        self.q1.show()
        self.q1.setText(
            'Программа для тестирования была написана для проведения проверки знаний у персонала ГП "Кыргызаэронавигация"\n'
            'Настройка и использование программы не должны вызвать каких-либо затруднений. Для настройки нажмите "Меню"'
            '-> "Настройки"\nВ случае возникновения вопросов прошу обращаться.\n\nРазработчик: Мамутов А'
        )
Esempio n. 2
0
class Window(QMainWindow):
    '''This class instantiates the main gui window'''
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("ManagerCraft")
        self.setCentralWidget(QWidget())
        self.styleFrame = QFrame(self.centralWidget())
        self.styleFrame.setFixedSize(1024, 500)
        self.styleFrame.setStyleSheet(
            "border-image: url(./graphics/WindowFrame.png);\
background-image: url(./graphics/Frame_R.png); background-repeat: no-repeat;")
        self.setGeometry(100, 100, 1024, 540)
        self.setFixedSize(1024, 540)
        self._createMenu()
        self.ss = QLabel(
            "<b>Be sure you're under the same network as your server or connected via VPN!</b>"
        )
        self.ss.setFixedSize(1024, 20)
        self._createStatusBar()

        font = QFont("Minecrafter", 22)

        self.host = QLineEdit()
        self.path = QLineEdit()
        self.user = QLineEdit()
        self.pas = QLineEdit()
        self.host.setFont(font)
        #self.path.setFont(font)
        self.user.setFont(font)
        self.pas.setFont(font)
        self.pas.setEchoMode(QLineEdit.Password)
        self.host.setFixedSize(250, 50)
        self.path.setFixedSize(350, 35)
        self.user.setFixedSize(250, 50)
        self.pas.setFixedSize(250, 50)

        self.dialog = QDialog(self.centralWidget(),
                              Qt.WindowTitleHint | Qt.WindowSystemMenuHint)
        self.dialog.setModal(True)
        self.dui = UI_Dialog()
        self.dui.setupUi(self.dialog)
        self.frameR = QFrame(self.centralWidget())
        self.frameR.setFixedSize(1024, 540)
        self.frameL = QFrame(self.centralWidget())
        self.frameL.hide()
        self.frameL.setFixedSize(1024, 540)
        self.frameC = QFrame(self.centralWidget())
        self.frameC.hide()
        self.frameC.setFixedSize(1024, 540)
        self.frameS = QFrame(self.centralWidget())
        self.frameS.hide()
        self.frameS.setFixedSize(1024, 540)
        self.err = QLabel(
            "<h2><font color='red'>Error: Invalid Input! Try again!</font></h2>",
            parent=self.frameR)
        self.err.hide()
        self.cui = UI2()
        self.cui.setupUi(self.frameC)
        self._createFirstScreen()
        self.mainMenu = True
        self.tools = None
        self.pwd = None
        self.client = None

    def __return_to(self, prev, frame):
        prev.hide()
        frame.show()

    def __DC(self):
        try:
            self.client.close()
        except AttributeError:
            pass
        self.ss.setStyleSheet("background-color: white")
        self.ss.setText(
            "<b>Server Status:  N/A  |  Be sure you're under the same network as your server or connected via VPN!</b>"
        )
        self.styleFrame.setStyleSheet(
            "border-image: url(./graphics/WindowFrame.png);\
background-image: url(./graphics/Frame_R.png); background-repeat: no-repeat;")
        self.err.hide()
        self.close_dialog()
        self.setWindowTitle("ManagerCraft")
        self.removeToolBar(self.tools)
        self.frameL.close()
        self.frameC.close()
        self.frameS.close()
        self.frameR.show()

    def __check_status(self):
        stdin, stdout, stderr = self.client.exec_command(
            "systemctl status minecraft")
        stat = [i for i in stdout if True][2]
        if "Active: active" in stat:
            self.ss.setStyleSheet("background-color: green")
            self.ss.setText("<b>Server Status:  Online</b>")
            stdin, stdout, stderr = self.client.exec_command(
                'systemctl status ngrok')
            grabIP = [
                re.search(r"(?<=url=tcp://).+\d+$", i).group() for i in stdout
                if re.search(r"(?<=url=tcp://).+\d+$", i)
            ][0]
            self.cui.serverIP.setText(grabIP)
        else:
            self.cui.serverIP.setText("N/A")
            self.ss.setStyleSheet("background-color: red")
            self.ss.setText(
                "<b><font color='white'>Server Status:  Offline</font></b>")

    def __startServer(self):
        stdin, stdout, stderr = self.client.exec_command(
            'sudo systemctl start minecraft ngrok', get_pty=True)
        stdin.write(f'{self.pas.text()}\n')
        stdin.flush()
        self.status.showMessage("Server Is Starting", 20000)
        stdin, stdout, stderr = self.client.exec_command(
            'systemctl status ngrok')
        grabIP = [
            re.search(r"(?<=url=tcp://).+\d+$", i).group() for i in stdout
            if re.search(r"(?<=url=tcp://).+\d+$", i)
        ][0]
        self.cui.serverIP.setText(grabIP)
        QTimer.singleShot(20000, self.__check_status)

    def __stopServer(self):
        stdin, stdout, stderr = self.client.exec_command(
            'sudo systemctl stop minecraft ngrok', get_pty=True)
        stdin.write(f'{self.pas.text()}\n')
        stdin.flush()
        self.status.showMessage("Server Is Stopping", 10000)
        self.cui.serverIP.setText("N/A")
        QTimer.singleShot(10000, self.__check_status)

    def __restartServer(self):
        stdin, stdout, stderr = self.client.exec_command(
            'sudo systemctl restart minecraft', get_pty=True)
        stdin.write(f'{self.pas.text()}\n')
        stdin.flush()
        self.status.showMessage("Server Is Restarting", 10000)
        QTimer.singleShot(10000, self.__check_status)

    def _createMenu(self):
        self.menu = self.menuBar().addMenu("Menu")
        self.menu.addAction("Disconnect", self.__DC)
        self.menu.addAction("Exit", self.close)

    def _createToolBar(self):
        self.tools = QToolBar()
        self.tools.setMovable(False)
        self.addToolBar(Qt.LeftToolBarArea, self.tools)
        self.tools.addAction("CONFIGURATION", self.close)
        self.tools.addAction("STATUS", self.close)

    def _createStatusBar(self):
        self.status = QStatusBar()
        self.status.addWidget(self.ss)
        self.setStatusBar(self.status)

    def _createSecondScreen(self):
        vLayout = QVBoxLayout(self.centralWidget())
        vLayout.setAlignment(Qt.AlignTop)
        vLayout.addWidget(QLabel())
        hLayout = QHBoxLayout()
        hLayout.setSpacing(0)
        hLayout.setAlignment(Qt.AlignHCenter)
        formLayout = QFormLayout(self.centralWidget())
        formLayout.setFormAlignment(Qt.AlignHCenter)
        formLayout.setLabelAlignment(Qt.AlignRight)

        btnGroup = QButtonGroup()
        btnGroup.setExclusive(True)
        title = QLabel()
        tPng = QPixmap("./graphics/ManageCraft.png")
        title.setPixmap(tPng)
        btn1 = QPushButton()
        btn1.setFixedSize(130, 40)
        btn1.setCheckable(True)
        btn1.setChecked(False)
        rcPng = QIcon("./graphics/RemoteBtn.png")
        btn1.setIcon(rcPng)
        btn1.setIconSize(QSize(170, 40))
        btn2 = QPushButton()
        btn2.setFixedSize(130, 40)
        btn2.setCheckable(True)
        btn2.setChecked(True)
        lcPng = QIcon("./graphics/LocalBtnChecked.png")
        btn2.setIcon(lcPng)
        btn2.setIconSize(QSize(170, 40))
        btn3 = QPushButton()
        btn3.setFixedSize(130, 40)
        bPng = QIcon("./graphics/BrowseBtn.png")
        btn3.setIcon(bPng)
        btn3.setIconSize(QSize(200, 40))
        btn1.toggled.connect(self.remote)
        btnGroup.addButton(btn1)
        btn2.toggled.connect(self.local)
        btnGroup.addButton(btn2)
        btn3.clicked.connect(self.browseL)
        btn1.pressed.connect(
            partial(self.btnPressToggle, btn1, "RemoteBtnChecked.png"))
        btn1.released.connect(
            partial(self.btnPressToggle, btn1, "RemoteBtn.png"))
        btn3.pressed.connect(
            partial(self.btnPressToggle, btn3, "BrowseBtnChecked.png"))
        btn3.released.connect(
            partial(self.btnPressToggle, btn3, "BrowseBtn.png"))

        vLayout.addWidget(title, alignment=Qt.AlignCenter)
        hLayout.addWidget(btn1, alignment=Qt.AlignHCenter)
        hLayout.addWidget(btn2, alignment=Qt.AlignHCenter)
        vLayout.addLayout(hLayout)
        vLayout.addWidget(self.path, alignment=Qt.AlignHCenter)
        vLayout.addWidget(btn3, alignment=Qt.AlignCenter)

        self.frameL.setLayout(vLayout)
        self.mainMenu = False
        self.frameL.hide()

    def _createFirstScreen(self):
        vLayout = QVBoxLayout(self.centralWidget())
        vLayout.setAlignment(Qt.AlignTop)
        vLayout.addWidget(QLabel())
        hLayout = QHBoxLayout()
        hLayout.setSpacing(0)
        hLayout.setAlignment(Qt.AlignHCenter)
        formLayout = QFormLayout(self.centralWidget())
        formLayout.setFormAlignment(Qt.AlignHCenter)
        formLayout.setLabelAlignment(Qt.AlignRight)

        btnGroup = QButtonGroup()
        btnGroup.setExclusive(True)
        title = QLabel()
        tPng = QPixmap("./graphics/ManageCraft.png")
        title.setPixmap(tPng)
        btn1 = QPushButton()
        btn1.setFixedSize(130, 40)
        btn1.setCheckable(True)
        btn1.setChecked(True)
        rcPng = QIcon("./graphics/RemoteBtnChecked.png")
        btn1.setIcon(rcPng)
        btn1.setIconSize(QSize(170, 40))
        btn2 = QPushButton()
        btn2.setFixedSize(130, 40)
        btn2.setCheckable(True)
        btn2.setChecked(False)
        lcPng = QIcon("./graphics/LocalBtn.png")
        btn2.setIcon(lcPng)
        btn2.setIconSize(QSize(170, 40))
        btn3 = QPushButton()
        btn3.setFixedSize(155, 45)
        cPng = QIcon("./graphics/ConnectBtn.png")
        btn3.setIcon(cPng)
        btn3.setIconSize(QSize(200, 40))
        btn1.toggled.connect(self.remote)
        btnGroup.addButton(btn1)
        btn2.toggled.connect(self.local)
        btnGroup.addButton(btn2)
        btn3.clicked.connect(partial(self.browseR))
        btn2.pressed.connect(
            partial(self.btnPressToggle, btn2, "LocalBtnChecked.png"))
        btn2.released.connect(
            partial(self.btnPressToggle, btn2, "LocalBtn.png"))
        btn3.pressed.connect(
            partial(self.btnPressToggle, btn3, "ConnectBtnChecked.png"))
        btn3.released.connect(
            partial(self.btnPressToggle, btn3, "ConnectBtn.png"))

        host = QLabel()
        hPng = QPixmap("./graphics/Host.png")
        host.setPixmap(hPng)
        user = QLabel()
        uPng = QPixmap("./graphics/Username.png")
        user.setPixmap(uPng)
        pas = QLabel()
        pPng = QPixmap("./graphics/Password.png")
        pas.setPixmap(pPng)

        formLayout.addRow(host, self.host)
        formLayout.addRow(user, self.user)
        formLayout.addRow(pas, self.pas)
        vLayout.addWidget(title, alignment=Qt.AlignCenter)
        hLayout.addWidget(btn1, alignment=Qt.AlignHCenter)
        hLayout.addWidget(btn2, alignment=Qt.AlignHCenter)
        vLayout.addLayout(hLayout)
        vLayout.addLayout(formLayout)
        vLayout.addWidget(btn3, alignment=Qt.AlignCenter)
        vLayout.addWidget(self.err, alignment=Qt.AlignHCenter)

        self.frameR.setLayout(vLayout)
        self.mainMenu = False
        self._createSecondScreen()

    def remote(self):
        if self.frameR.isVisible():
            pass
        else:
            self.styleFrame.setStyleSheet(
                "border-image: url(./graphics/WindowFrame.png);\
background-image: url(./graphics/Frame_R.png); background-repeat: no-repeat;")
            self.frameL.hide()
            self.frameR.show()

    def local(self):
        if self.frameL.isVisible():
            pass
        else:
            self.styleFrame.setStyleSheet(
                "border-image: url(./graphics/WindowFrame.png);\
background-image: url(./graphics/Frame_L.png); background-repeat: no-repeat;")
            self.frameR.hide()
            self.frameL.show()

    def connect(self):  # Pack to config window
        self.path.setText(self.dui.path.text())
        if self.path.text() != '':
            stdin, stdout, stderr = self.client.exec_command(
                f"cd {self.path.text()}")
            try:
                err = [i for i in stderr if True][0]
                self.err.setText(
                    "<h2><font color='red'>Error: No such file or directory!</font></h2>"
                )
                self.err.show()
            except IndexError:
                self.styleFrame.setStyleSheet(
                    "border-image: url(./graphics/WindowFrame.png);\
background-image: url(./graphics/Frame_2.png); background-repeat: no-repeat;")
                self.cui.startBtn.clicked.connect(self.__startServer)
                self.cui.stopBtn.clicked.connect(self.__stopServer)
                self.cui.restartBtn.clicked.connect(self.__restartServer)
                self.cui.startBtn.pressed.connect(
                    partial(self.btnStyleToggle, self.cui.startBtn,
                            "StartChecked.png"))
                self.cui.startBtn.released.connect(
                    partial(self.btnStyleToggle, self.cui.startBtn,
                            "Start.png"))
                self.cui.stopBtn.pressed.connect(
                    partial(self.btnStyleToggle, self.cui.stopBtn,
                            "StopChecked.png"))
                self.cui.stopBtn.released.connect(
                    partial(self.btnStyleToggle, self.cui.stopBtn, "Stop.png"))
                self.cui.restartBtn.pressed.connect(
                    partial(self.btnStyleToggle, self.cui.restartBtn,
                            "RestartChecked.png"))
                self.cui.restartBtn.released.connect(
                    partial(self.btnStyleToggle, self.cui.restartBtn,
                            "Restart.png"))
                self.err.hide()
                self.setWindowTitle(f"{self.path.text()} - ManageCraft")
                self._createToolBar()
                self.frameR.hide()
                self.frameC.show()
                self.__check_status()
        self.close_dialog()

    def browseL(self):
        getPath = QFileDialog().getExistingDirectory()
        self.path.setText(getPath)
        if self.path.text() != '':
            self.styleFrame.setStyleSheet(
                "border-image: url(./graphics/WindowFrame.png);\
background-image: url(./graphics/Frame_2.png); background-repeat: no-repeat;")
            self.setWindowTitle(f"{self.path.text()} - ManageCraft")
            self._createToolBar()
            self.frameL.hide()
            self.frameC.show()

    def browseR(self):
        if self.host.text() == '' or self.user.text() == '' or self.pas.text(
        ) == '':
            self.err.setText(
                "<h2><font color='red'>Error: Invalid Input! Try again!</font></h2>"
            )
            self.err.show()
        else:
            try:
                self.err.hide()
                client = paramiko.SSHClient()
                client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                client.connect(self.host.text(),
                               port=22,
                               username=self.user.text(),
                               password=self.pas.text())
                self.client = client
                self.dui.btnBox.accepted.connect(self.connect)
                self.dui.btnBox.rejected.connect(self.close_dialog)
                self.plant_tree(self.client)
                self.dialog.show()
                #Don't proceed until connected
            except (socket.gaierror,
                    paramiko.ssh_exception.AuthenticationException):
                self.err.setText(
                    "<h2><font color='red'>Error: Invalid Input! Try again!</font></h2>"
                )
                self.err.show()
            #Don't proceed unless path given
    def next_layer(self,
                   lst):  #Loops through folders and returns dict of subfolders
        d = {}
        for i in lst:
            stdin, stdout, stderr = self.client.exec_command(
                f"cd {i} && ls -d */ && cd ..")
            dirs = [fold.strip('/\n') for fold in stdout if True]
            if len(dirs) > 0:
                d[i] = dirs
            else:
                d[i] = 0
        return d

    def plant_tree(self, client):
        self.dui.treeW.setColumnCount(1)
        self.dui.treeW.setAlternatingRowColors(True)
        self.dui.treeW.itemExpanded.connect(
            partial(self.water_tree, self.dui.treeW))
        self.dui.treeW.itemClicked.connect(
            partial(self.get_path, self.dui.treeW))
        stdin, stdout, stderr = client.exec_command('ls -d */')
        top = [i.strip('/\n') for i in stdout if True]
        folders = self.next_layer(top)
        self.cache = []
        stdin, stdout, stderr = client.exec_command('pwd')
        self.pwd = [i for i in stdout if True][0].strip('\n')
        self.grow_tree(folders)

    def grow_tree(self, folders):
        items = []
        folderIcon = QIcon("./graphics/folder.jpeg")
        for folder in folders:
            item = QTreeWidgetItem([folder])
            item.setIcon(0, folderIcon)
            if folders[folder] != 0:
                childs = []
                for sub in folders[folder]:
                    s = QTreeWidgetItem([sub])
                    s.setIcon(0, folderIcon)
                    childs.append(s)
                item.addChildren(childs)
            items.append(item)
        self.dui.treeW.addTopLevelItems(items)

    def bloom_tree(self, branchItem, folders):
        folderIcon = QIcon("./graphics/folder.jpeg")
        it = QTreeWidgetItemIterator(branchItem,
                                     flags=QTreeWidgetItemIterator.NoChildren)
        while it.value():
            item = it.value()
            for folder in folders:
                if folder == self.get_roots(item) and folder not in self.cache:
                    self.cache.append(folder)
                    childs = []
                    if folders[folder] != 0:
                        for sub in folders[folder]:
                            s = QTreeWidgetItem([sub])
                            s.setIcon(0, folderIcon)
                            childs.append(s)
                        item.addChildren(childs)
            it += 1

    def water_tree(self, tree):
        it = QTreeWidgetItemIterator(tree,
                                     flags=QTreeWidgetItemIterator.HasChildren)
        while it.value():
            item = it.value()
            tempath = self.get_roots(item)
            if item.isExpanded():
                cs = item.childCount()
                childs = [
                    f"{tempath}/{item.child(idx).text(0)}" for idx in range(cs)
                    if True
                ]
                folders = self.next_layer(childs)
                self.bloom_tree(item, folders)
            it += 1

    def get_roots(self, item):  # Trace back parents of selected item
        it = QTreeWidgetItemIterator(self.dui.treeW,
                                     flags=QTreeWidgetItemIterator.All)
        while it.value():
            if it.value() == item:
                if item.parent() != None:
                    return self.get_roots(item.parent()) + '/' + item.text(0)
                else:
                    return item.text(0)
            it += 1

    def get_path(self, tree):
        path = self.get_roots(tree.selectedItems()[0])
        self.dui.path.setText(f"{self.pwd}/{path}")

    def close_dialog(self):
        self.dui.path.setText('')
        self.dui.treeW.clear()

    def btnPressToggle(self, btn, png):
        Png = QIcon(f"./graphics/{png}")
        btn.setIcon(Png)
        btn.setIconSize(QSize(200, 40))

    def btnStyleToggle(self, btn, png):
        btn.setStyleSheet(f"border-image: url(./graphics/{png})")
Esempio n. 3
0
class ViewsController(QMainWindow):
    """This class will handle all the views of the application.

    Responsible for showing the differnet views in a specific order depending on the input of the user. If the
    application is launched with a profile (configuration file), the main view of the application will be shown;
    otherwise, the title and the configuration views will be shown prior to the main view.
    """

    home_singal = pyqtSignal()
    robot_select_signal = pyqtSignal()

    def __init__(self, parent, configuration, controller=None):
        """Constructor of the class.

        Arguments:
            parent {ui.gui.views_controller.ParentWindow} -- Parent of this.
            configuration {utils.configuration.Config} -- Configuration instance of the application

        Keyword Arguments:
            controller {utils.controller.Controller} -- Controller of the application (default: {None})
        """
        QMainWindow.__init__(self)
        self.parent = parent
        self.controller = controller
        self.configuration = configuration
        self.main_view = None
        self.thread_gui = ThreadGUI(self)
        self.thread_gui.daemon = True

        # self.home_singal.connect(self.show_title)
        # self.robot_select_signal.connect(self.show_robot_selection)

    def show_title(self):
        """Shows the title view"""
        title = TitleWindow(self.parent)
        title.switch_window.connect(self.show_robot_selection)
        self.parent.main_layout.addWidget(title)
        self.fadein_animation()

    def show_robot_selection(self):
        """Shows the robot selection view"""
        from views.robot_selection import RobotSelection

        delete_widgets_from(self.parent.main_layout)
        robot_selector = RobotSelection(self.parent)
        robot_selector.switch_window.connect(self.show_world_selection)
        self.parent.main_layout.addWidget(robot_selector, 0)
        self.fadein_animation()

    def show_world_selection(self):
        """Shows the world selection view"""
        from views.world_selection import WorldSelection

        delete_widgets_from(self.parent.main_layout)
        world_selector = WorldSelection(self.parent.robot_selection,
                                        self.configuration, self.parent)
        world_selector.switch_window.connect(self.show_layout_selection)
        self.parent.main_layout.addWidget(world_selector)
        self.fadein_animation()

    def show_layout_selection(self):
        """Show the layout configuration view"""
        delete_widgets_from(self.parent.main_layout)
        self.layout_selector = LayoutSelection(self.configuration, self.parent)
        self.layout_selector.switch_window.connect(self.show_main_view_proxy)
        self.parent.main_layout.addWidget(self.layout_selector)
        self.fadein_animation()

    def show_main_view_proxy(self):
        """Helper function to show the main view. Will close the parent window to create  a new one"""
        # self.show_main_view(False)
        self.parent.close()

    def show_main_view(self, from_main):
        """Shows the main window depending on where the application comes from.

        If the from_main flag is true, the configuration comes from the previous GUI views. Otherwise, the configuration
        comes from a configuration file. Eitherway, the main view will be shown with the proper configuration.

        Arguments:
            from_main {bool} -- tells if the configuration comes from either configuration file or GUI.
        """
        if not from_main:
            layout_configuration = self.layout_selector.get_config()
            delete_widgets_from(self.parent.main_layout)
        else:
            layout_configuration = None
        self.main_view = MainView(layout_configuration, self.configuration,
                                  self.controller, self.parent)
        self.parent.main_layout.addWidget(self.main_view)
        self.fadein_animation()
        self.start_thread()

    def start_thread(self):
        """Start the GUI refresing loop"""
        self.thread_gui.start()

    def fadein_animation(self):
        """Start a fadein animation for views transitions"""
        self.w = QFrame(self.parent)
        # self.parent.main_layout.addWidget(self.w, 0)
        self.w.setFixedSize(WIDTH, HEIGHT)
        self.w.setStyleSheet('background-color: rgba(51,51,51,1)')
        self.w.show()

        effect = QGraphicsOpacityEffect()
        self.w.setGraphicsEffect(effect)

        self.animation = QPropertyAnimation(effect, b"opacity")
        self.animation.setDuration(500)
        self.animation.setStartValue(1)
        self.animation.setEndValue(0)

        self.animation.start(QPropertyAnimation.DeleteWhenStopped)
        self.animation.finished.connect(self.fade_animation)

    def fade_animation(self):
        """Safe kill the animation"""
        self.w.close()
        del self.w
        del self.animation

    def update_gui(self):
        """Update the GUI. Called from the refresing loop thread"""
        while not self.parent.closing:
            if self.main_view:
                self.main_view.update_gui()
            time.sleep(0.1)
Esempio n. 4
0
class Tablewidget(QTableWidget):
    def __init__(self,parent):
        super().__init__()
        self.setParent(parent)
        self.frontandnextFlag = []
        self.pat = re.compile(r"<font style='background-color:red;'>(.*?)</font>")
        self.searchbox = QFrame(self)
        self.searchbox.setGeometry(10,50,330,30)
        # self.searchbox.setFrameRect(QRect(10,10,10,10))
        self.searchbox.setStyleSheet("border-radius:2px;background-color:rgb(200,200,200)")
        self.searchbox.setHidden(True)

        self.searchtextbox = QLineEdit(self.searchbox)
        self.searchtextbox.setGeometry(0,0,210,30)
        self.searchtextbox.setStyleSheet("border:none")

        #文本显示框
        self.textwindow = QTextEdit(self)
        self.textwindow.setGeometry(0,0, self.width() - 100, self.height() - 100)
        self.textwindow.setVisible(False)
        self.textwindow_text = None
        #搜索窗口
        self.search = QPushButton("", self.searchbox)
        self.search.setIcon(QIcon("./pic/search.ico"))
        self.search.setGeometry(210, 0, 30, 30)
        self.search.setStyleSheet("border:none")
        self.search.clicked.connect(self.searchdata)

        self.front  =   QPushButton("",self.searchbox)
        self.front.setIcon(QIcon("./pic/front.ico"))
        self.front.setGeometry(240,0,30,30)
        self.front.setStyleSheet("border:none")
        self.front.clicked.connect(lambda: self.frontandnextpress(-1))

        self.next   =   QPushButton("", self.searchbox)
        self.next.setIcon(QIcon("./pic/next.ico"))
        self.next.setGeometry(270,0,30,30)
        self.next.setStyleSheet("border:none")
        self.next.clicked.connect(lambda: self.frontandnextpress(1))

        self.clo = QPushButton("", self.searchbox)
        self.clo.setIcon(QIcon("./pic/close.ico"))
        self.clo.setGeometry(300, 0, 30, 30)
        self.clo.setStyleSheet("border:none")
        self.clo.clicked.connect(self.searchboxclo)

        self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        # 设置垂直方向滑块像素移动
        self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        # 设置水平方向滑块像素移动
        self.setEditTriggers(QAbstractItemView.NoEditTriggers | QAbstractItemView.DoubleClicked)
        # 设置表格不可编辑
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        # 设置启用右键策略

    def showdata(self, data):
        self.setRowCount(len(data[0]) - 1)
        self.setColumnCount(len(data))
        for i in range(0, len(data)):  # 总列数,显示所有数据
            self.setHorizontalHeaderItem(i, QTableWidgetItem(data[i][0]))
            for j in range(1, len(data[0])):  # 总数据行数
                ss = QTableWidgetItem(data[i][j])
                self.setItem(j - 1, i, ss)
                ss.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter)  # 设置所有单元格对齐方式

    def keyPressEvent(self, QkeyEvent):
        if QkeyEvent.key() == Qt.Key_F:
            if QApplication.keyboardModifiers() == Qt.ControlModifier:
                self.searchbox.show()
                self.searchbox.setHidden(False)
                self.searchtextbox.setFocus()
        elif QkeyEvent.key() == Qt.Key_Escape:
            if self.searchbox.isHidden():
                self.textwindow.setHidden(True)
            else:
                self.searchbox.setHidden(True)
                self.textwindow.setHidden(True)
        elif QkeyEvent.key() == Qt.Key_F2:
            self.textwindow.setGeometry(0,0, self.width() - 100, self.height() - 100)
            detail = JSONEncoder().encode(self.textwindow_text)
            detail = json.loads(detail)
            self.textwindow.setText(json.dumps(detail, indent=5, ensure_ascii=False))
            self.textwindow.setHidden(False)


    def searchdata(self):
        self.frontandnextFlag = []
        global  pressFlag
        pressFlag = -1
        findtext = ""
        # if self.searchtextbox.text() == "":
        #     return
        # else:
        try:
            findtext = self.searchtextbox.text().split()[0]
        except IndexError:
            findtext = "$@##$$@!!"  #如果为空,标记特殊寻找字符,找不到将Qlabel替换为字符串
        for a in range(self.rowCount()):
            for b in range(self.columnCount()):
                if isinstance(type(self.item(a,b)),type(None)) and isinstance(type(self.cellWidget(a,b)),type(None)):
                    pass
                else:

                    if isinstance(type(self.cellWidget(a,b)),type(QLabel)):
                        if "<font style" in self.cellWidget(a,b).text():
                            d = self.cancelCssFormat(self.cellWidget(a,b).text())
                            celltext = self.cellWidget(a,b).text().replace(
                                "<font style='background-color:red;'>{}</font>".format(d),
                                d)
                            if findtext in celltext:
                                self.cellWidget(a,b).setText(self.setStrkeyColor(celltext,findtext))
                                self.frontandnextFlag.append([a,b])
                            else:
                                self.removeCellWidget(a,b)
                                celltext = celltext.replace("<br>", "\n")
                                self.setItem(a,b,QTableWidgetItem(celltext))
                        else:
                            celltext = self.cellWidget(a,b).text()
                            celltext = celltext.replace("<br>", "\n")
                            self.removeCellWidget(a,b)
                            self.setItem(a,b,QTableWidgetItem(celltext))
                    elif isinstance(type(self.item(a, b)), type(QTableWidgetItem)):
                        if findtext in self.item(a,b).text():
                            celltext = self.item(a,b).text().replace("\n","<br>")
                            celltext = self.setStrkeyColor(celltext,findtext)
                            lab = QLabel(celltext,self)
                            self.setCellWidget(a,b,lab)
                            self.setItem(a,b,QTableWidgetItem(""))
                            self.frontandnextFlag.append([a, b])
                            # print(a,b,type(self.cellWidget(a,b)),type(self.item(a,b)),"\n",lab.text())
                        else:
                            pass
                    else:
                        pass

    def setStrkeyColor(self,strdata,key):
        needstr = strdata.replace(key,"<font style='background-color:red;'>{}</font>".format(key))
        return needstr

    def cancelCssFormat(self,strdata):
        return self.pat.search(strdata).group(1)

    def stecellbackcolor(self,a,b,color=QColor(200,200,200)):
        self.item(a,b).setBackground(QColor(color))

    def searchboxclo(self):
        self.searchtextbox.clear()
        self.searchbox.close()

    def frontandnextpress(self,k):
        global pressFlag
        pressFlag += k
        if pressFlag >= 0 and pressFlag < len(self.frontandnextFlag):
            self.setCurrentCell(self.frontandnextFlag[pressFlag][0],self.frontandnextFlag[pressFlag][1])
        else:
            pressFlag = -1