Пример #1
0
class VideoWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.image = QGraphicsView()
        color = QColor("black")
        self.image.setBackgroundBrush(QBrush(color))
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.image)
        self.connected = False

    def connect(self, port, ip="localhost"):
        if self.connected:
            return
        self.socket = QDataSocket(tcp_ip=ip, tcp_port=port)
        self.socket_thread = QThread()
        self.socket.moveToThread(self.socket_thread)
        self.socket_thread.started.connect(self.socket.start)
        self.socket.new_data.connect(self.update_image)
        self.socket_thread.start()
        self.connected = True

    def update_image(self, data):
        image = data[0]['data']
        assert (np.max(image) <= 255)
        image8 = image.astype(np.uint8, order='C', casting='unsafe')
        height, width, colors = image8.shape
        bytesPerLine = 3 * width

        image = QImage(image8.data, width, height, bytesPerLine, QImage.Format_RGB888)
        image = image.rgbSwapped()

        pixmap = QPixmap(image)
        scene = QGraphicsScene()
        scene.addPixmap(pixmap.scaled(self.image.width(), self.image.height(), Qt.KeepAspectRatio))
        self.image.setScene(scene)
Пример #2
0
    def initUI(self):

        self.scene = GraphicsScene(self)
        self.scene._image = QImage('1513411692.png')
        view = QGraphicsView(self.scene, self)
        self.scene.setSceneRect(0, 0, view.width(), view.height())

        addLine = QPushButton('AddLine')
        addLine.clicked.connect(self.addLine)

        hbox = QHBoxLayout(self)
        hbox.addWidget(view)

        vbox = QVBoxLayout(self)
        vbox.addWidget(addLine)

        hbox.addLayout(vbox)

        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.width, self.height)
        self.setFixedSize(self.width, self.height)
        self.setLayout(hbox)
        self.show()
Пример #3
0
    def run():
        app = QApplication(sys.argv)

        scene = QGraphicsScene()

        # adding scene background
        scene.setBackgroundBrush(QBrush(QImage('./imgs/background.png')))

        player = Player()

        # add the item to the scene
        scene.addItem(player)

        # make player focusable
        player.setFlag(QGraphicsItem.ItemIsFocusable)
        player.setFocus()

        # add a view, widget(invisible)
        view = QGraphicsView(scene)
        view.setFixedSize(800, 600)
        # horizontal and vertical scroll bar has benn disabled
        view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        scene.setSceneRect(0, 0, 800, 600)
        player.setPos(view.width() / 2 - player.pixmap().width() / 2, view.height() - player.pixmap().height())
        view.show()

        global score
        score = Score()
        scene.addItem(score)

        global health
        health = Health()
        scene.addItem(health)

        # spawn enemies
        timer = QTimer()

        def spawn():
            enemy = Enemy()
            scene.addItem(enemy)
        timer.timeout.connect(spawn)
        timer.start(1000)

        # play background music
        url = QUrl.fromLocalFile("./sounds/intro.ogg")
        media = M.QMediaContent(url)
        playlist = M.QMediaPlaylist()
        playlist.addMedia(media)
        playlist.setPlaybackMode(M.QMediaPlaylist.Loop)
        music = M.QMediaPlayer()
        music.setPlaylist(playlist)
        music.setVolume(10)
        music.play()
        # media = M.QMediaContent(url)
        # music = M.QMediaPlayer()
        # music.setMedia(media)
        # music.setVolume(20)
        # music.play()

        sys.exit(app.exec_())
Пример #4
0
class BattleView(QObject):
    def __init__(self, battle_window, parent=None):
        super().__init__(parent)
        self.battleWindow = battle_window  # MainBattleWindow container_widget

        if len(self.battleWindow.config.errors) != 0:
            # noinspection PyArgumentList
            QMessageBox.critical(battle_window, 'Configuration Error',
                                 self.battleWindow.config.get_error_str())
            exit(-1)

        # main elements
        self.centralWidget = QWidget(self.battleWindow)
        self.gridLayout = QGridLayout(self.centralWidget)

        # misc side elements
        self.graphicsView_coatOfArm = CustomScene()
        self.graphicsView_currentUnit = CustomScene()
        self.graphicsView_targetedUnit = CustomScene()

        for button in self.graphicsView_coatOfArm, self.graphicsView_currentUnit, self.graphicsView_targetedUnit:
            button.enter_functions.append(self.set_label_hint)
            button.leave_functions.append(self.clear_label_hint)

        # buttons
        self.autoCombatButton = CustomButton(self.centralWidget)
        self.helpButton = CustomButton(self.centralWidget)
        self.retreatButton = CustomButton(self.centralWidget)
        self.endUnitTurnButton = CustomButton(self.centralWidget)
        self.nextTargetButton = CustomButton(self.centralWidget)

        for button in self.autoCombatButton, self.helpButton, self.retreatButton, self.nextTargetButton, self.endUnitTurnButton:
            button.enter_functions.append(self.set_label_hint)
            button.leave_functions.append(self.clear_label_hint)
            button.click_functions.append(self.click_button)

        # info containers
        self.dateLabel = QLabel(
            self.centralWidget)  # display current turn in battle
        self.hintLabel = QLabel(
            self.centralWidget)  # display hint when hovering over an elemend

        # the actual battle scene
        self.mainScene = MainQGraphicsScene()
        self.graphicsView_main = QGraphicsView(self.mainScene)
        self.gridLayout.addWidget(self.graphicsView_main, 1, 0, 12, 1)

    def setup_ui(self):
        self.battleWindow.setWindowTitle(
            self.battleWindow.config.get_text('battle.window.title') + ' v' +
            str(self.battleWindow.config.version))
        background = self.battleWindow.config.theme_selected.get_background_pixmap(
        )
        palette = QPalette()
        palette.setBrush(QPalette.Background, QBrush(background))
        self.battleWindow.setMinimumSize(constants.get_min_resolution_qsize())
        self.battleWindow.setAutoFillBackground(True)
        self.gridLayout.setVerticalSpacing(0)

        self.setup_hint_label()  # Labels
        self.setup_turn_label()  # Labels
        self.setup_space()  # Space item

        self.setup_help_button()  # Help Push Button
        self.setup_next_target_button()  # Next Target Button
        self.setup_end_unit_button()  # End Unit Button
        self.setup_retreat_button()  # Retreat Button
        self.setup_auto_combat_button()  # Automatic battle button

        self.setup_targeted_unit_view()  # Targeted Unit view
        self.setup_current_unit_view()  # Current Unit View
        self.setup_coat_of_arms_view()  # Coat of Arm view

        self.setup_map()  # Main view
        self.battleWindow.setPalette(palette)
        self.battleWindow.setCentralWidget(self.centralWidget)

        # noinspection PyArgumentList
        QMetaObject.connectSlotsByName(self.battleWindow)

    def setup_map(self):
        self.mainScene = MainQGraphicsScene()
        self.graphicsView_main.setScene(self.mainScene)
        self.mainScene.set_battle_view(self.battleView)
        width = 2 * self.graphicsView_main.height() / math.sqrt(3)
        height = self.graphicsView_main.height()
        if width > self.graphicsView_main.width():
            width = self.graphicsView_main.width()
            height = self.graphicsView_main.width() * math.sqrt(3) / 2
        item = self.mainScene.addRect(0, 0, width - 15, height - 15)
        item.hide()
        self.battleView.draw_battle_map(self.mainScene)

    def resize_event(self):
        self.setup_map()

    # misc elements
    def setup_hint_label(self):
        size_policy = constants.default_size_policy(self.hintLabel,
                                                    QSizePolicy.Preferred,
                                                    QSizePolicy.Fixed)
        self.hintLabel.setSizePolicy(size_policy)
        self.hintLabel.setFont(constants.default_font())
        self.hintLabel.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                    | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.hintLabel, 0, 0, 1, 1)

    def setup_turn_label(self):
        size_policy = constants.default_size_policy(self.dateLabel,
                                                    QSizePolicy.Preferred,
                                                    QSizePolicy.Fixed)
        self.dateLabel.setSizePolicy(size_policy)
        self.dateLabel.setFont(constants.default_font())
        self.dateLabel.setText('Turn ' + str(self.battleView.turn))
        self.dateLabel.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.dateLabel, 0, 0, 1, 1)

    def setup_space(self):
        # Space between help Button and flag view
        spacer_item = QSpacerItem(20, 10, QSizePolicy.Minimum,
                                  QSizePolicy.MinimumExpanding)
        self.gridLayout.addItem(spacer_item, 2, 1, 1, 1)
        # Space between flag view and next target Button
        spacer_item1 = QSpacerItem(20, 10, QSizePolicy.Minimum,
                                   QSizePolicy.MinimumExpanding)
        self.gridLayout.addItem(spacer_item1, 4, 1, 1, 1)
        # Space between retreat Button and targetted unit view
        spacer_item2 = QSpacerItem(20, 10, QSizePolicy.Minimum,
                                   QSizePolicy.Fixed)
        self.gridLayout.addItem(spacer_item2, 8, 1, 1, 1)
        # Space between current unit view and auto Button
        spacer_item3 = QSpacerItem(20, 10, QSizePolicy.Minimum,
                                   QSizePolicy.MinimumExpanding)
        self.gridLayout.addItem(spacer_item3, 11, 1, 1, 1)

    def setup_coat_of_arms_view(self):
        size = QSize(90, 120)
        self.battleView.draw_coat_of_arms(self.graphicsView_coatOfArm.scene(),
                                          size)
        self.graphicsView_coatOfArm.setVerticalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        size_policy = constants.default_size_policy(
            self.graphicsView_coatOfArm, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.graphicsView_coatOfArm.setSizePolicy(size_policy)
        self.graphicsView_coatOfArm.setMinimumSize(size)
        self.graphicsView_coatOfArm.setMaximumSize(size)
        self.graphicsView_coatOfArm.setStyleSheet(
            "border-style: none;background: transparent")
        self.graphicsView_coatOfArm.setCacheMode(QGraphicsView.CacheBackground)
        self.gridLayout.addWidget(self.graphicsView_coatOfArm, 3, 1, 1, 1)

    # unit views
    def setup_targeted_unit_view(self):
        size = QSize(60, 60)
        army = self.get_computer_army()
        defending = (army == self.battleView.defender)
        self.battleView.draw_targetted_unit(
            defending, self.graphicsView_targetedUnit.scene(), size)
        size_policy = constants.default_size_policy(
            self.graphicsView_targetedUnit, QSizePolicy.Fixed,
            QSizePolicy.Fixed)
        self.graphicsView_targetedUnit.setSizePolicy(size_policy)
        self.graphicsView_targetedUnit.setMinimumSize(size)
        self.graphicsView_targetedUnit.setMaximumSize(size)
        self.gridLayout.addWidget(self.graphicsView_targetedUnit, 9, 1, 1, 1,
                                  Qt.AlignCenter)

    def setup_current_unit_view(self):
        size = QSize(60, 60)
        army = self.get_human_army()
        defending = (army == self.battleView.defender)
        self.battleView.draw_current_unit(
            defending, self.graphicsView_currentUnit.scene(), size)
        size_policy = constants.default_size_policy(
            self.graphicsView_currentUnit, QSizePolicy.Fixed,
            QSizePolicy.Fixed)
        self.graphicsView_currentUnit.setSizePolicy(size_policy)
        self.graphicsView_currentUnit.setMinimumSize(size)
        self.graphicsView_currentUnit.setMaximumSize(size)
        self.gridLayout.addWidget(self.graphicsView_currentUnit, 10, 1, 1, 1,
                                  Qt.AlignCenter)

    def get_human_army(self):
        if self.battleView.attacker.nation.computer:
            return self.battleView.defender
        return self.battleView.attacker

    def get_computer_army(self):
        if self.battleView.attacker.nation.computer:
            return self.battleView.attacker
        return self.battleView.defender

    # buttons
    def setup_next_target_button(self):
        size_policy = constants.default_size_policy(self.nextTargetButton,
                                                    QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)
        self.nextTargetButton.setSizePolicy(size_policy)
        self.nextTargetButton.setMinimumSize(QSize(45, 45))
        self.nextTargetButton.setMaximumSize(QSize(45, 45))
        self.nextTargetButton.setText("")
        icon = QIcon()
        icon.addPixmap(
            QPixmap(self.battleWindow.config.theme_selected.
                    get_target_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.nextTargetButton.setIcon(icon)
        self.nextTargetButton.setIconSize(QSize(40, 40))
        self.gridLayout.addWidget(self.nextTargetButton, 5, 1, 1, 1,
                                  Qt.AlignCenter)

    def setup_end_unit_button(self):
        size_policy = constants.default_size_policy(self.endUnitTurnButton,
                                                    QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)
        self.endUnitTurnButton.setSizePolicy(size_policy)
        self.endUnitTurnButton.setMinimumSize(QSize(45, 45))
        self.endUnitTurnButton.setMaximumSize(QSize(45, 45))
        self.endUnitTurnButton.setText("")
        icon1 = QIcon()
        icon1.addPixmap(
            self.battleWindow.config.theme_selected.get_end_button_pixmap(),
            QIcon.Normal, QIcon.Off)
        self.endUnitTurnButton.setIcon(icon1)
        self.endUnitTurnButton.setIconSize(QSize(40, 40))
        self.gridLayout.addWidget(self.endUnitTurnButton, 6, 1, 1, 1,
                                  Qt.AlignCenter)

    def setup_retreat_button(self):
        size_policy = constants.default_size_policy(self.retreatButton,
                                                    QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)
        self.retreatButton.setSizePolicy(size_policy)
        self.retreatButton.setMinimumSize(QSize(45, 45))
        self.retreatButton.setMaximumSize(QSize(45, 45))
        self.retreatButton.setToolTip("")
        self.retreatButton.setWhatsThis("")
        self.retreatButton.setText("")
        icon2 = QIcon()
        icon2.addPixmap(
            QPixmap(self.battleWindow.config.theme_selected.
                    get_retreat_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.retreatButton.setIcon(icon2)
        self.retreatButton.setIconSize(QSize(42, 40))
        self.gridLayout.addWidget(self.retreatButton, 7, 1, 1, 1,
                                  Qt.AlignCenter)

    def setup_help_button(self):
        size_policy = constants.default_size_policy(self.helpButton,
                                                    QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)
        self.helpButton.setSizePolicy(size_policy)
        self.helpButton.setMinimumSize(QSize(80, 80))
        self.helpButton.setMaximumSize(QSize(80, 80))
        self.helpButton.setText("")
        icon3 = QIcon()
        icon3.addPixmap(
            QPixmap(self.battleWindow.config.theme_selected.
                    get_help_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.helpButton.setIcon(icon3)
        self.helpButton.setIconSize(QSize(75, 75))
        self.gridLayout.addWidget(self.helpButton, 0, 1, 2, 1)

    def setup_auto_combat_button(self):
        size_policy = constants.default_size_policy(self.autoCombatButton,
                                                    QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)
        self.autoCombatButton.setSizePolicy(size_policy)
        self.autoCombatButton.setMinimumSize(QSize(90, 90))
        self.autoCombatButton.setMaximumSize(QSize(90, 90))
        self.autoCombatButton.setText("")
        icon4 = QIcon()
        icon4.addPixmap(
            QPixmap(self.battleWindow.config.theme_selected.
                    get_autocombat_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.autoCombatButton.setIcon(icon4)
        self.autoCombatButton.setIconSize(QSize(80, 80))
        self.gridLayout.addWidget(self.autoCombatButton, 12, 1, 1, 1)

    # element interactions
    def clear_label_hint(self, generic_element):
        self.hintLabel.setText('')

    def set_label_hint(self, generic_element):
        text = ''
        if generic_element in self.battleView.map.fields:
            # TODO - not hooked up
            text = str(generic_element)
        elif generic_element == self.graphicsView_currentUnit:
            text = str(self.battleView.currentUnit)
        elif generic_element == self.graphicsView_targetedUnit:
            text = str(self.battleView.targettedUnit)
        elif generic_element == self.autoCombatButton:
            text = self.battleWindow.config.get_text('auto.play.label')
        elif generic_element == self.helpButton:
            text = self.battleWindow.config.get_text(
                'help.tacticalbattle.label')
        elif generic_element == self.retreatButton:
            text = self.battleWindow.config.get_text('retreat.all.label')
        elif generic_element == self.endUnitTurnButton:
            text = self.battleWindow.config.get_text('end.unit.label')
        elif generic_element == self.nextTargetButton:
            text = self.battleWindow.config.get_text('next.target.label')
        if text != '':
            self.hintLabel.setText(text)

    def click_button(self, button_element):
        if button_element == self.autoCombatButton:
            self.battleView.autoCombat = True
        elif button_element == self.helpButton:
            print('click helpButton')
        elif button_element == self.retreatButton:
            self.get_human_army().retreat = True
        elif button_element == self.endUnitTurnButton:
            print('click endUnitTurnButton')
        elif button_element == self.nextTargetButton:
            print('click nextTargetButton')
Пример #5
0
class Ui_Form(object):
    def __init__(self, obj):
        super().__init__()
        self.setupUi(obj)
        self.retranslateUi(obj)
        self.graphicsView = QGraphicsView(obj)
        self.graphicsView.setGeometry(QtCore.QRect(10, 10, 791, 441))
        self.graphicsView.setObjectName("graphicsView")
        self.scene = QtWidgets.QGraphicsScene()
        self.graphicsView.setScene(self.scene)

        pen = QtGui.QPen(QtCore.Qt.GlobalColor.gray)
        for i in range(-1 * self.graphicsView.height() // 2 + 10,
                       self.graphicsView.height() // 2 - 10):
            r1 = QtCore.QRectF(QtCore.QPointF(0, i), QtCore.QSizeF(1, 1))
            self.scene.addRect(r1, pen)

        for i in range(-1 * self.graphicsView.width() // 2 + 10,
                       self.graphicsView.width() // 2 - 10):
            r2 = QtCore.QRectF(QtCore.QPointF(i, 0), QtCore.QSizeF(1, 1))
            self.scene.addRect(r2, pen)

        self.coordsContainer = []
        self.centersContainer = []
        self.clastersContainer = []
        self.distance = None

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(815, 678)

        self.startPushButton = QPushButton(Form)
        self.startPushButton.clicked.connect(
            self.startPushButton_button_clicked)
        self.startPushButton.setGeometry(QtCore.QRect(260, 620, 261, 41))
        self.startPushButton.setObjectName("startPushButton")

        self.coordsTextBox = QtWidgets.QPlainTextEdit(Form)
        self.coordsTextBox.setGeometry(QtCore.QRect(260, 470, 261, 81))
        self.coordsTextBox.setObjectName("coordsTextBox")

        self.CentersTextBox = QtWidgets.QPlainTextEdit(Form)
        self.CentersTextBox.setGeometry(QtCore.QRect(540, 470, 261, 81))
        self.CentersTextBox.setObjectName("CentersTextBox")

        self.addCordsPushButton = QPushButton(Form)
        self.addCordsPushButton.clicked.connect(
            self.addCordsPushButton_button_clicked)
        self.addCordsPushButton.setGeometry(QtCore.QRect(260, 570, 541, 31))
        self.addCordsPushButton.setObjectName("addCordsPushButton")

        self.groupBox = QtWidgets.QGroupBox(Form)
        self.groupBox.setGeometry(QtCore.QRect(10, 460, 241, 91))
        self.groupBox.setObjectName("groupBox")

        self.euclidRadioButton = QRadioButton(self.groupBox)
        self.euclidRadioButton.toggled.connect(self.euclidRadioButton_clicked)
        self.euclidRadioButton.setGeometry(QtCore.QRect(10, 20, 221, 31))
        self.euclidRadioButton.setObjectName("euclidRadioButton")

        self.chebishevRadioButton = QRadioButton(self.groupBox)
        self.chebishevRadioButton.toggled.connect(
            self.chebishevRadioButton_clicked)
        self.chebishevRadioButton.setGeometry(QtCore.QRect(10, 50, 221, 41))
        self.chebishevRadioButton.setObjectName("chebishevRadioButton")

        self.stepPushButton = QPushButton(Form)
        self.stepPushButton.clicked.connect(self.stepPushButton_button_clicked)
        self.stepPushButton.setGeometry(QtCore.QRect(540, 620, 261, 41))
        self.stepPushButton.setObjectName("stepPushButton")

        self.restartPushButton = QPushButton(Form)
        self.restartPushButton.clicked.connect(
            self.restartPushButton_button_clicked)
        self.restartPushButton.setGeometry(QtCore.QRect(10, 620, 241, 41))
        self.restartPushButton.setObjectName("restartPushButton")

        self.testPushButton = QPushButton(Form)
        self.testPushButton.clicked.connect(self.testPushButton_button_clicked)
        self.testPushButton.setGeometry(QtCore.QRect(10, 570, 241, 31))
        self.testPushButton.setObjectName("testPushButton")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.startPushButton.setText(_translate("Form", "START"))
        self.addCordsPushButton.setText(_translate("Form", "ADD COORDINATES"))
        self.groupBox.setTitle(_translate("Form", "Distance"))
        self.euclidRadioButton.setText(_translate("Form", "Euclid"))
        self.chebishevRadioButton.setText(_translate("Form", "Chebishev"))
        self.stepPushButton.setText(_translate("Form", "STEP"))
        self.restartPushButton.setText(_translate("Form", "RESTART"))
        self.testPushButton.setText(_translate("Form", "Set Test Dataset"))

    def drawLineToDot(self):
        pen = QtGui.QPen(QtCore.Qt.GlobalColor.blue)
        brush = QtGui.QBrush(QtCore.Qt.GlobalColor.blue)
        pen.setWidth(2)
        pen.setColor(QtCore.Qt.GlobalColor.blue)

        for i in range(len(self.clastersContainer)):
            for j in self.clastersContainer[i]:
                self.scene.addLine(
                    QtCore.QLineF(4 * j[0], -4 * j[1],
                                  4 * self.centersContainer[i][0],
                                  -4 * self.centersContainer[i][1]), pen)

    def stringParser(self, coords, centers):
        coords_l = None
        centers_l = None
        try:
            coords_string_array = coords.split(';')
            centers_string_array = centers.split(';')
            coords_l = []
            centers_l = []

            for i in coords_string_array:
                l = [float(k) for k in i.strip('()').split(',')]
                coords_l.append(l)

            for i in centers_string_array:
                l = [float(k) for k in i.strip('()').split(',')]
                centers_l.append(l)
        except:
            self.CentersTextBox.clear()
            self.coordsTextBox.clear()
            msg = QtWidgets.QMessageBox()
            msg.setIcon(QtWidgets.QMessageBox.Critical)
            msg.setText("Format Error")
            msg.setInformativeText('Follow the format!')
            msg.setWindowTitle("Error")
            msg.setStyleSheet("QLabel{font-size: 20px;}")
            msg.exec_()
            pass
        return coords_l, centers_l

    def add_coordinates_to_GraphView(self):
        pen = QtGui.QPen(QtCore.Qt.GlobalColor.black)
        brush = QtGui.QBrush(QtCore.Qt.GlobalColor.black)
        side = 4
        for i in self.coordsContainer:
            self.scene.addEllipse(i[0] * side - 3, -1 * i[1] * side - 3, 7, 7,
                                  pen, brush)

        pen = QtGui.QPen(QtCore.Qt.GlobalColor.red)
        brush = QtGui.QBrush(QtCore.Qt.GlobalColor.red)

        for i in self.centersContainer:
            self.scene.addEllipse(i[0] * side - 3, -1 * i[1] * side - 3, 7, 7,
                                  pen, brush)

    def addCordsPushButton_button_clicked(self):
        coordinates = self.coordsTextBox.toPlainText()
        centers = self.CentersTextBox.toPlainText()
        if coordinates == '' or centers == '':
            msg = QtWidgets.QMessageBox()
            msg.setIcon(QtWidgets.QMessageBox.Critical)
            msg.setText("Data Empty")
            msg.setInformativeText('Please, enter coords')
            msg.setWindowTitle("Error")
            msg.setStyleSheet("QLabel{font-size: 20px;}")
            msg.exec_()
            return

        coordinates_l, centers_l = self.stringParser(coordinates, centers)

        if coordinates_l is not None and centers_l is not None:
            co = self.coordsContainer.copy()
            ce = self.centersContainer.copy()

            co += coordinates_l.copy()
            ce += centers_l.copy()

            co.sort()
            ce.sort()

            co_new = list(num for num, _ in itertools.groupby(co))
            ce_new = list(num for num, _ in itertools.groupby(ce))

            self.centersContainer = ce_new.copy()
            self.coordsContainer = co_new.copy()

            print(self.centersContainer)
            print(self.coordsContainer)

            self.add_coordinates_to_GraphView()

    def startPushButton_button_clicked(self):
        if self.coordsContainer == [] or self.centersContainer == []:
            msg = QtWidgets.QMessageBox()
            msg.setIcon(QtWidgets.QMessageBox.Critical)
            msg.setText("Data Empty")
            msg.setInformativeText('Please, enter coords')
            msg.setWindowTitle("Error")
            msg.setStyleSheet("QLabel{font-size: 20px;}")
            msg.exec_()
            return
        self.chebishevRadioButton.setEnabled(False)
        self.euclidRadioButton.setEnabled(False)
        self.addCordsPushButton.setEnabled(False)
        self.coordsTextBox.setEnabled(False)
        self.CentersTextBox.setEnabled(False)
        self.startPushButton.setEnabled(False)
        self.testPushButton.setEnabled(False)

        if self.distance == 'E':

            for _ in range(len(self.centersContainer)):
                self.clastersContainer.append([])

            for i in self.coordsContainer:
                range_l = []
                for c in self.centersContainer:
                    range_l.append(
                        math.sqrt((i[0] - c[0])**2 + (i[1] - c[1])**2))

                minindex = range_l.index(min(range_l))
                self.clastersContainer[minindex].append(i)
            self.drawLineToDot()
        elif self.distance == 'H':
            for _ in range(len(self.centersContainer)):
                self.clastersContainer.append([])

            for i in self.coordsContainer:
                range_l = []
                for c in self.centersContainer:
                    range_l.append(max(abs(i[0] - c[0]), abs(i[1] - c[1])))

                minindex = range_l.index(min(range_l))
                self.clastersContainer[minindex].append(i)
            self.drawLineToDot()

    def stepPushButton_button_clicked(self):
        if self.centersContainer is None or self.coordsContainer is None:
            msg = QtWidgets.QMessageBox()
            msg.setIcon(QtWidgets.QMessageBox.Critical)
            msg.setText("Empty Error")
            msg.setInformativeText('Not enough dots!')
            msg.setWindowTitle("Error")
            msg.setStyleSheet("QLabel{font-size: 20px;}")
            msg.exec_()
            return

        claster_backup = self.clastersContainer.copy()
        new_centers = []
        for i in self.clastersContainer:
            new_x, new_y = 0, 0
            for k in i:
                new_x += k[0]
                new_y += k[1]
            new_x /= len(i)
            new_y /= len(i)
            new_centers.append([new_x, new_y])

        self.centersContainer = new_centers.copy()
        self.redrow(False)
        self.add_coordinates_to_GraphView()
        self.clastersContainer.clear()
        for _ in range(len(self.centersContainer)):
            self.clastersContainer.append([])

        for i in self.coordsContainer:
            range_l = []
            for c in new_centers:
                range_l.append(math.sqrt((i[0] - c[0])**2 + (i[1] - c[1])**2))

            minindex = range_l.index(min(range_l))
            self.clastersContainer[minindex].append(i)
        self.drawLineToDot()
        new_back_clasters = self.clastersContainer.copy()

        if claster_backup == new_back_clasters:
            self.stepPushButton.setEnabled(False)

    def redrow(self, full):
        self.scene.clear()
        pen = QtGui.QPen(QtCore.Qt.GlobalColor.gray)
        for i in range(-1 * self.graphicsView.height() // 2 + 10,
                       self.graphicsView.height() // 2 - 10):
            r1 = QtCore.QRectF(QtCore.QPointF(0, i), QtCore.QSizeF(1, 1))
            self.scene.addRect(r1, pen)

        for i in range(-1 * self.graphicsView.width() // 2 + 10,
                       self.graphicsView.width() // 2 - 10):
            r2 = QtCore.QRectF(QtCore.QPointF(i, 0), QtCore.QSizeF(1, 1))
            self.scene.addRect(r2, pen)
        if not full:

            pen2 = QtGui.QPen(QtCore.Qt.GlobalColor.black)
            brush2 = QtGui.QBrush(QtCore.Qt.GlobalColor.black)

            side = 4
            for i in self.coordsContainer:
                self.scene.addEllipse(i[0] * side - 3, -1 * i[1] * side - 3, 7,
                                      7, pen2, brush2)

    def restartPushButton_button_clicked(self):
        self.chebishevRadioButton.setEnabled(True)
        self.euclidRadioButton.setEnabled(True)
        self.addCordsPushButton.setEnabled(True)
        self.coordsTextBox.setEnabled(True)
        self.CentersTextBox.setEnabled(True)
        self.testPushButton.setEnabled(True)
        self.startPushButton.setEnabled(True)
        self.stepPushButton.setEnabled(True)
        self.redrow(True)

        self.coordsContainer.clear()
        self.centersContainer.clear()
        self.clastersContainer.clear()

    def testPushButton_button_clicked(self):
        self.coordsTextBox.setPlainText(TEST_COORDS)
        if self.distance == 'E':
            self.CentersTextBox.setPlainText(EUCLID_TEST_CENTERS)
        elif self.distance == 'H':
            self.CentersTextBox.setPlainText(CHEBISHEV_TEST_CENTERS)
        else:
            self.coordsTextBox.clear()
            msg = QtWidgets.QMessageBox()
            msg.setIcon(QtWidgets.QMessageBox.Critical)
            msg.setText("Distance not set")
            msg.setInformativeText('Please, pick the distance')
            msg.setWindowTitle("Error")
            msg.setStyleSheet("QLabel{font-size: 20px;}")
            msg.exec_()
            pass

    def euclidRadioButton_clicked(self):
        if self.euclidRadioButton.isChecked():
            self.distance = 'E'

    def chebishevRadioButton_clicked(self):
        if self.chebishevRadioButton.isChecked():
            self.distance = 'H'
Пример #6
0
class MainWindow(QMainWindow):
    class MainScene(QGraphicsScene):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.parent = parent
            self.prev_active_rect = None
            self.active_elements = []

        def mouseMoveEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
            try:
                good = False
                for _event, event_object in self.parent.events:
                    if _event.x1 <= event.scenePos().x() <= _event.x2 \
                            and _event.y1 <= event.scenePos().y() <= _event.y2:
                        if self.prev_active_rect is not None:
                            self.prev_active_rect.setBrush(
                                QBrush(QColor.fromRgb(250, 240, 240)))
                            self.prev_active_rect = None
                        event_object.setBrush(QBrush(Qt.green))
                        self.prev_active_rect = event_object
                        good = True
                if not good and self.prev_active_rect is not None:
                    self.prev_active_rect.setBrush(
                        QBrush(QColor.fromRgb(250, 240, 240)))
                    self.prev_active_rect = None
            except Exception as e:
                print(e)

        def mousePressEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
            try:
                for element in self.active_elements:
                    element.setBrush(QBrush(QColor.fromRgb(240, 240, 250)))
            except Exception as exception:
                print('error with a brush in mousePressEvent in MainScene:',
                      exception)
            try:
                if event.button() == 2:
                    current_x, current_y = event.scenePos().x(
                    ), event.scenePos().y()

                    for rect, object_rect in self.parent.rectangles:
                        try:
                            if rect.x1 <= current_x <= rect.x2 and \
                                    rect.y1 <= current_y <= rect.y2:
                                try:
                                    context_menu = QMenu()

                                    history = context_menu.addAction('history')
                                    action = context_menu.exec(QCursor().pos())

                                    if action == history:
                                        rect.widget = QWidget()
                                        rect.widget.setWindowTitle(
                                            'Biography of {}'.format(
                                                rect.name))
                                        layout = QHBoxLayout()
                                        label = QLabel()
                                        label.setText(rect.description)
                                        layout.addWidget(label)
                                        rect.widget.setLayout(layout)
                                        rect.widget.setGeometry(
                                            QCursor().pos().x(),
                                            QCursor().pos().y(), 500, 200)
                                        rect.widget.show()

                                except Exception as exception:
                                    print(exception)

                        except Exception as exception:
                            print(exception)
                elif event.button() == 1:
                    current_x, current_y = event.scenePos().x(
                    ), event.scenePos().y()
                    for _event, event_object in self.parent.events:
                        if _event.x1 <= current_x <= _event.x2 and _event.y1 <= current_y <= _event.y2:
                            for _rect, object_rect in self.parent.rectangles:
                                year_from = int(_rect.years.split()[0])
                                year_to = int(_rect.years.split()[2])
                                if year_from <= int(_event.years) <= year_to:
                                    object_rect.setBrush(
                                        QBrush(QColor.fromRgb(200, 200, 240)))
                                    self.active_elements.append(object_rect)
                    pass

            except Exception as e:
                print(e)
            print('finished')

    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
        import sys
        sys.exit(0)

    def __init__(self):
        super().__init__()
        self.setWindowTitle('Genealogy tree')
        self.setGeometry(500, 50, 1000, 900)
        self.view = QTableView()

        layout = QHBoxLayout()

        w = QWidget(self)
        w.setLayout(layout)

        self.scene = self.MainScene(self)

        self.graphics_view = QGraphicsView(self.scene)
        self.graphics_view.setMouseTracking(True)
        self.graphics_view.setFixedSize(900, 900)
        self.setMouseTracking(True)
        self.events = []

        layout.addWidget(self.graphics_view)

        database_layout = QVBoxLayout()
        layout.addLayout(database_layout)

        font = QFont('Times')
        font.setPixelSize(20)

        change_tree_structure_button = QPushButton(
            'change structure of the tree')
        change_tree_structure_button.setFixedSize(300, 150)
        change_tree_structure_button.setFont(font)

        change_events_structure_button = QPushButton(
            'change structure of events')
        change_events_structure_button.setFixedSize(300, 150)
        change_events_structure_button.setFont(font)

        rebuild_tree_button = QPushButton('rebuild tree')
        rebuild_tree_button.setFixedSize(300, 150)
        rebuild_tree_button.setFont(font)

        database_layout.addWidget(change_tree_structure_button)
        database_layout.addWidget(change_events_structure_button)
        database_layout.addWidget(rebuild_tree_button)

        change_events_structure_button.clicked.connect(
            self.change_events_structure)
        change_tree_structure_button.clicked.connect(
            self.change_tree_structure)
        rebuild_tree_button.clicked.connect(self.rebuild_tree)

        self.setCentralWidget(w)

        self.scale = 1
        self.db_widget = None
        self.add_element_widget = None
        self.remove_element_widget = None
        self.add_connection_widget = None
        self.remove_connection_widget = None
        self.db_widget_events = None
        self.add_event_widget = None
        self.remove_event_widget = None

    def change_tree_structure(self):
        self.db_widget = QWidget()
        self.db_widget.setGeometry(1000, 200, 400, 100)
        self.db_widget.setWindowTitle('Change structure of the tree')

        layout = QVBoxLayout()

        add_element_in_data_base = QPushButton('add note')
        remove_element_from_data_base = QPushButton('del note')
        add_connection_in_data_base = QPushButton('add connection')
        remove_connection_in_data_base = QPushButton('del connection')

        layout.addWidget(add_element_in_data_base)
        layout.addWidget(remove_element_from_data_base)
        layout.addWidget(add_connection_in_data_base)
        layout.addWidget(remove_connection_in_data_base)

        add_element_in_data_base.clicked.connect(self.add_element_in_data_base)
        remove_element_from_data_base.clicked.connect(
            self.remove_element_from_data_base)
        add_connection_in_data_base.clicked.connect(
            self.add_connection_in_data_base)
        remove_connection_in_data_base.clicked.connect(
            self.remove_connection_in_data_base)

        self.db_widget.setLayout(layout)
        self.db_widget.show()

    def change_events_structure(self):
        self.db_widget_events = QWidget()
        self.db_widget_events.setGeometry(1000, 200, 400, 100)
        self.db_widget_events.setWindowTitle('Change structure of events')

        layout = QVBoxLayout()

        add_element_in_data_base = QPushButton('add note')
        remove_element_from_data_base = QPushButton('del note')

        layout.addWidget(add_element_in_data_base)
        layout.addWidget(remove_element_from_data_base)

        add_element_in_data_base.clicked.connect(self.add_event_in_data_base)
        remove_element_from_data_base.clicked.connect(
            self.remove_event_from_data_base)

        self.db_widget_events.setLayout(layout)
        self.db_widget_events.show()

    def add_event_in_data_base(self):
        add_event_widget = QWidget()
        add_event_widget.setGeometry(1100, 250, 700, 200)
        add_event_widget.setWindowTitle('Add new event')
        layout = QVBoxLayout()
        first_layout = QHBoxLayout()
        second_layout = QHBoxLayout()
        layout.addLayout(first_layout)
        layout.addLayout(second_layout)
        apply_button = QPushButton('apply')

        apply_button.clicked.connect(self.apply_button_operation_add_event)
        layout.addWidget(apply_button)
        for title in ['title', 'description', 'year']:
            first_layout.addWidget(QLabel(title))
            second_layout.addWidget(QTextEdit())
        add_event_widget.setLayout(layout)
        add_event_widget.show()
        self.add_event_widget = add_event_widget

    def apply_button_operation_add_event(self):
        title = self.add_event_widget.layout().itemAt(1).layout().itemAt(
            0).widget().toPlainText()
        description = self.add_event_widget.layout().itemAt(1).layout().itemAt(
            1).widget().toPlainText()
        year = self.add_event_widget.layout().itemAt(1).layout().itemAt(
            2).widget().toPlainText()

        if title and description and year:
            human_and_time_database.TimeEvent.create(title=title,
                                                     description=description,
                                                     date=year)
            self.add_event_widget.close()
        else:
            message = QErrorMessage(self)
            message.setWindowTitle('Input data error')
            message.showMessage('All fields must be filled')

    def remove_event_from_data_base(self):
        try:
            remove_event_widget = QWidget()
            remove_event_widget.setGeometry(1100, 250, 700, 200)
            remove_event_widget.setWindowTitle('Del event')
            layout = QVBoxLayout()
            first_layout = QHBoxLayout()
            second_layout = QHBoxLayout()
            layout.addLayout(first_layout)
            layout.addLayout(second_layout)
            apply_button = QPushButton('apply')
            print('here')
            apply_button.clicked.connect(self.apply_button_operation_del_event)
            print('here')
            layout.addWidget(apply_button)
            print('here')
            for title in ['title']:
                first_layout.addWidget(QLabel(title))
                second_layout.addWidget(QTextEdit())
            print('here')
            remove_event_widget.setLayout(layout)
            remove_event_widget.show()
            print('here')
            self.remove_event_widget = remove_event_widget
            print('here')
        except Exception as e:
            print('here', e)

    def apply_button_operation_del_event(self):
        try:
            title = self.remove_event_widget.layout().itemAt(
                1).layout().itemAt(0).widget().toPlainText()
            if title:
                query = human_and_time_database.TimeEvent.select().where(
                    human_and_time_database.TimeEvent.title == title).limit(1)
                if len(list(query)) == 1:
                    human_and_time_database.TimeEvent.delete().where(
                        (human_and_time_database.TimeEvent.title ==
                         query[0].title)).execute()
                    self.remove_event_widget.close()
                else:
                    message = QErrorMessage(self)
                    message.setWindowTitle('Input data error')
                    message.showMessage('No such node in the tree')
            else:
                message = QErrorMessage(self)
                message.setWindowTitle('Input data error')
                message.showMessage('All fields must be filled')
        except Exception as e:
            print('apply_button_operation_del_element: ', e)

    def add_element_in_data_base(self):
        add_element_widget = QWidget()
        add_element_widget.setGeometry(1100, 250, 700, 200)
        add_element_widget.setWindowTitle('Add element')
        layout = QVBoxLayout()
        first_layout = QHBoxLayout()
        second_layout = QHBoxLayout()
        layout.addLayout(first_layout)
        layout.addLayout(second_layout)
        apply_button = QPushButton('apply')

        apply_button.clicked.connect(self.apply_button_operation_add_element)
        layout.addWidget(apply_button)
        for title in ['name', 'biography', 'year of born', 'year of death']:
            first_layout.addWidget(QLabel(title))
            second_layout.addWidget(QTextEdit())
        add_element_widget.setLayout(layout)
        add_element_widget.show()
        self.add_element_widget = add_element_widget

    def apply_button_operation_add_element(self):
        name = self.add_element_widget.layout().itemAt(1).layout().itemAt(
            0).widget().toPlainText()
        biography = self.add_element_widget.layout().itemAt(1).layout().itemAt(
            1).widget().toPlainText()
        year_of_born = self.add_element_widget.layout().itemAt(
            1).layout().itemAt(2).widget().toPlainText()
        year_of_death = self.add_element_widget.layout().itemAt(
            1).layout().itemAt(3).widget().toPlainText()

        if name and biography and year_of_death and year_of_death:
            human_and_time_database.HumanModel.create(
                name=name,
                biography=biography,
                year_of_born=year_of_born,
                year_of_death=year_of_death)
            self.add_element_widget.close()
        else:
            message = QErrorMessage(self)
            message.setWindowTitle('Input data error')
            message.showMessage('All fields must be filled')

    def remove_element_from_data_base(self):
        try:
            remove_element_widget = QWidget()
            remove_element_widget.setGeometry(1100, 250, 700, 200)
            remove_element_widget.setWindowTitle('Del element')
            layout = QVBoxLayout()
            first_layout = QHBoxLayout()
            second_layout = QHBoxLayout()
            layout.addLayout(first_layout)
            layout.addLayout(second_layout)
            apply_button = QPushButton('apply')

            apply_button.clicked.connect(
                self.apply_button_operation_del_element)
            layout.addWidget(apply_button)
            for title in ['name']:
                first_layout.addWidget(QLabel(title))
                second_layout.addWidget(QTextEdit())
            remove_element_widget.setLayout(layout)
            remove_element_widget.show()
            self.remove_element_widget = remove_element_widget

        except Exception as e:
            print(e)

    def apply_button_operation_del_element(self):
        try:
            name = self.remove_element_widget.layout().itemAt(
                1).layout().itemAt(0).widget().toPlainText()
            if name:
                query = human_and_time_database.HumanModel.select().where(
                    human_and_time_database.HumanModel.name == name).limit(1)
                if len(list(query)) == 1:
                    human = query[0]

                    new_rows = []
                    for row in human_and_time_database.RelationTable.select():
                        if human.id in [row.spouse, row.parent1, row.parent2]:
                            current_human = row.human
                            current_spouse = None if row.spouse == human.id else row.spouse
                            current_parent1 = None if row.parent1 == human.id else row.parent1
                            current_parent2 = None if row.parent2 == human.id else row.parent2
                            new_rows.append((current_human, current_spouse,
                                             current_parent1, current_parent2))

                    human_and_time_database.RelationTable.delete().where(
                        (human_and_time_database.RelationTable.human ==
                         human.id)
                        | (human_and_time_database.RelationTable.spouse ==
                           human.id)
                        | (human_and_time_database.RelationTable.parent1 ==
                           human.id)
                        | (human_and_time_database.RelationTable.parent2 ==
                           human.id)).execute()

                    for h, s, p1, p2 in new_rows:
                        human_and_time_database.RelationTable.create(
                            human=h, spouse=s, parent1=p1, parent2=p2)

                    human_and_time_database.HumanModel.delete().where(
                        human_and_time_database.HumanModel.name ==
                        name).execute()

                    self.remove_element_widget.close()
                else:
                    message = QErrorMessage(self)
                    message.setWindowTitle('Input data error')
                    message.showMessage('No such node in the tree')
            else:
                message = QErrorMessage(self)
                message.setWindowTitle('Input data error')
                message.showMessage('All fields must be filled')
        except Exception as e:
            print('apply_button_operation_del_element: ', e)

    def add_connection_in_data_base(self):
        add_connection_widget = QWidget()
        add_connection_widget.setGeometry(1100, 250, 700, 200)
        add_connection_widget.setWindowTitle('Add connection')
        layout = QVBoxLayout()
        first_layout = QHBoxLayout()
        second_layout = QHBoxLayout()
        layout.addLayout(first_layout)
        layout.addLayout(second_layout)
        apply_button = QPushButton('apply')

        apply_button.clicked.connect(
            self.apply_button_operation_add_connection)
        layout.addWidget(apply_button)
        for title in ['name 1', 'name 2']:
            first_layout.addWidget(QLabel(title))
            second_layout.addWidget(QTextEdit())

        third_layout = QVBoxLayout()
        second_layout.addLayout(third_layout)
        first_layout.addWidget(QLabel(''))
        first_layout.addWidget(QLabel('Type of connection'))

        first_button = QRadioButton('spouse - spouse connection')
        first_button.setChecked(True)
        second_button = QRadioButton('parent - child connection')

        third_layout.addWidget(first_button)
        third_layout.addWidget(second_button)

        add_connection_widget.setLayout(layout)
        add_connection_widget.show()
        self.add_connection_widget = add_connection_widget

    def apply_button_operation_add_connection(self):
        name1 = self.add_connection_widget.layout().itemAt(1).layout().itemAt(
            0).widget().toPlainText()
        name2 = self.add_connection_widget.layout().itemAt(1).layout().itemAt(
            1).widget().toPlainText()
        spouse_connection = self.add_connection_widget.layout().itemAt(
            1).layout().itemAt(2).layout().itemAt(0).widget().isChecked()
        try:
            if name1 and name2:
                human_1 = human_and_time_database.HumanModel.select().where(
                    human_and_time_database.HumanModel.name == name1)
                human_2 = human_and_time_database.HumanModel.select().where(
                    human_and_time_database.HumanModel.name == name2)

                if len(human_1) != 1 or len(human_2) != 1:
                    message = QErrorMessage(self)
                    message.setWindowTitle('Input data error')
                    message.showMessage('No human with set name in the tree')
                    return
                human_1 = human_1[0]
                human_2 = human_2[0]

                human_id1 = human_1.id
                human_id2 = human_2.id
                if human_id1 == human_id2:
                    message = QErrorMessage(self)
                    message.setWindowTitle('Input data error')
                    message.showMessage(
                        'Cant create a connection between human and himself')
                    return
                if spouse_connection:
                    all_connections = human_and_time_database.RelationTable.select(
                    )

                    graph = dict()
                    for connection in all_connections:
                        human = connection.human
                        spouse = connection.spouse
                        parent1 = connection.parent1
                        parent2 = connection.parent2
                        graph[human] = (spouse, parent1, parent2)

                    if human_id1 not in graph:
                        graph[human_id1] = (None, None, None)

                    if human_id2 not in graph:
                        graph[human_id2] = (None, None, None)

                    if graph[human_id1][0] == human_id2:
                        message = QErrorMessage(self)
                        message.setWindowTitle('Input data error')
                        message.showMessage('Connection already exists')
                        return

                    if graph[human_id1][0] is not None or graph[human_id2][
                            0] is not None:
                        message = QErrorMessage(self)
                        message.setWindowTitle('Input data error')
                        message.showMessage(
                            'Another connection already exists with at least one of humans'
                        )
                        return

                    queue = [human_id1]
                    i = 0
                    used = set()
                    while i < len(queue):
                        v = queue[i]
                        if v is None or v in used:
                            i += 1
                            continue
                        used.add(v)
                        if v == human_id2:
                            message = QErrorMessage(self)
                            message.setWindowTitle('Input data error')
                            message.showMessage(
                                'Cyclic dependence! The connection cannot be built'
                            )
                            return

                        queue.append(graph[v][0])
                        queue.append(graph[v][1])
                        queue.append(graph[v][2])

                    queue = [human_id2]
                    i = 0
                    used = set()
                    while i < len(queue):
                        v = queue[i]
                        if v is None or v in used:
                            i += 1
                            continue
                        used.add(v)
                        if v == human_id1:
                            message = QErrorMessage(self)
                            message.setWindowTitle('Input data error')
                            message.showMessage(
                                'Cyclic dependence! The connection cannot be built'
                            )
                            return

                        queue.append(graph[v][0])
                        queue.append(graph[v][1])
                        queue.append(graph[v][2])

                    human_1 = human_id1
                    human_1_spouse = human_id2
                    human_1_parent1 = graph[human_id1][1]
                    human_1_parent2 = graph[human_id1][2]

                    human_2 = human_id2
                    human_2_spouse = human_id1
                    human_2_parent1 = graph[human_id2][1]
                    human_2_parent2 = graph[human_id2][2]

                    human_and_time_database.RelationTable.delete().where((
                        human_and_time_database.RelationTable.human == human_1
                    ) | (human_and_time_database.RelationTable.human == human_2
                         )).execute()

                    human_and_time_database.RelationTable.create(
                        human=human_1,
                        spouse=human_1_spouse,
                        parent1=human_1_parent1,
                        parent2=human_1_parent2)

                    human_and_time_database.RelationTable.create(
                        human=human_2,
                        spouse=human_2_spouse,
                        parent1=human_2_parent1,
                        parent2=human_2_parent2)

                    self.add_connection_widget.close()
                else:
                    all_connections = human_and_time_database.RelationTable.select(
                    )

                    graph = dict()
                    for connection in all_connections:
                        human = connection.human
                        spouse = connection.spouse
                        parent1 = connection.parent1
                        parent2 = connection.parent2
                        graph[human] = (spouse, parent1, parent2)

                    if human_id1 not in graph:
                        graph[human_id1] = (None, None, None)

                    if human_id2 not in graph:
                        graph[human_id2] = (None, None, None)

                    if graph[human_id2][1] == human_id1 or graph[human_id2][
                            2] == human_id1:
                        message = QErrorMessage(self)
                        message.setWindowTitle('Input data error')
                        message.showMessage('Connection already exists')
                        return

                    if graph[human_id2][1] is not None and graph[human_id2][
                            2] is not None:
                        message = QErrorMessage(self)
                        message.setWindowTitle('Input data error')
                        message.showMessage(
                            'The child already has two parents')
                        return

                    queue = [human_id1]
                    i = 0
                    used = set()
                    while i < len(queue):
                        v = queue[i]
                        if v is None or v in used:
                            i += 1
                            continue
                        used.add(v)
                        if v == human_id2:
                            message = QErrorMessage(self)
                            message.setWindowTitle('Input data error')
                            message.showMessage(
                                'Cyclic dependence! The connection cannot be built'
                            )
                            return

                        queue.append(graph[v][0])
                        queue.append(graph[v][1])
                        queue.append(graph[v][2])

                    queue = [human_id2]
                    i = 0
                    used = set()
                    while i < len(queue):
                        v = queue[i]
                        if v is None or v in used:
                            i += 1
                            continue
                        used.add(v)
                        if v == human_id1:
                            message = QErrorMessage(self)
                            message.setWindowTitle('Input data error')
                            message.showMessage(
                                'Cyclic dependence! The connection cannot be built'
                            )
                            return

                        queue.append(graph[v][0])
                        queue.append(graph[v][1])
                        queue.append(graph[v][2])

                    human_1 = human_id1
                    human_1_spouse = graph[human_id1][0]
                    human_1_parent1 = graph[human_id1][1]
                    human_1_parent2 = graph[human_id1][2]

                    human_2 = human_id2
                    human_2_spouse = graph[human_id2][0]
                    human_2_parent1 = graph[human_id2][1]
                    human_2_parent2 = graph[human_id2][2]
                    if human_2_parent1 is None:
                        human_2_parent1 = human_1
                    else:
                        human_2_parent2 = human_1

                    human_and_time_database.RelationTable.delete().where((
                        human_and_time_database.RelationTable.human == human_1
                    ) | (human_and_time_database.RelationTable.human == human_2
                         )).execute()

                    human_and_time_database.RelationTable.create(
                        human=human_1,
                        spouse=human_1_spouse,
                        parent1=human_1_parent1,
                        parent2=human_1_parent2)

                    human_and_time_database.RelationTable.create(
                        human=human_2,
                        spouse=human_2_spouse,
                        parent1=human_2_parent1,
                        parent2=human_2_parent2)

                    self.add_connection_widget.close()

            else:
                message = QErrorMessage(self)
                message.setWindowTitle('Input data error')
                message.showMessage('All fields must be filled')

        except Exception as e:
            print(e)

    def remove_connection_in_data_base(self):
        remove_connection_widget = QWidget()
        remove_connection_widget.setGeometry(1100, 250, 700, 200)
        remove_connection_widget.setWindowTitle('Add connection')
        layout = QVBoxLayout()
        first_layout = QHBoxLayout()
        second_layout = QHBoxLayout()
        layout.addLayout(first_layout)
        layout.addLayout(second_layout)
        apply_button = QPushButton('apply')

        apply_button.clicked.connect(
            self.apply_button_operation_remove_connection)
        layout.addWidget(apply_button)
        for title in ['name 1', 'name 2']:
            first_layout.addWidget(QLabel(title))
            second_layout.addWidget(QTextEdit())

        third_layout = QVBoxLayout()
        second_layout.addLayout(third_layout)
        first_layout.addWidget(QLabel(''))
        first_layout.addWidget(QLabel('Type of connection'))

        first_button = QRadioButton('spouse - spouse connection')
        first_button.setChecked(True)

        second_button = QRadioButton('parent - child connection')

        third_layout.addWidget(first_button)
        third_layout.addWidget(second_button)

        remove_connection_widget.setLayout(layout)
        remove_connection_widget.show()

        self.remove_connection_widget = remove_connection_widget

    def apply_button_operation_remove_connection(self):
        name1 = self.remove_connection_widget.layout().itemAt(
            1).layout().itemAt(0).widget().toPlainText()
        name2 = self.remove_connection_widget.layout().itemAt(
            1).layout().itemAt(1).widget().toPlainText()
        spouse_connection = self.remove_connection_widget.layout().itemAt(
            1).layout().itemAt(2).layout().itemAt(0).widget().isChecked()

        try:
            if name1 and name2:
                human_1 = human_and_time_database.HumanModel.select().where(
                    human_and_time_database.HumanModel.name == name1)
                human_2 = human_and_time_database.HumanModel.select().where(
                    human_and_time_database.HumanModel.name == name2)

                if len(human_1) != 1 or len(human_2) != 1:
                    message = QErrorMessage(self)
                    message.setWindowTitle('Input data error')
                    message.showMessage('No human with set name in the tree')
                    return
                human_1 = human_1[0]
                human_2 = human_2[0]

                human_id1 = human_1.id
                human_id2 = human_2.id
                if human_id1 == human_id2:
                    message = QErrorMessage(self)
                    message.setWindowTitle('Input data error')
                    message.showMessage(
                        'No connection between human and himself')
                    return
                if spouse_connection:
                    all_connections = human_and_time_database.RelationTable.select(
                    )

                    graph = dict()
                    for connection in all_connections:
                        human = connection.human
                        spouse = connection.spouse
                        parent1 = connection.parent1
                        parent2 = connection.parent2
                        graph[human] = (spouse, parent1, parent2)

                    if human_id1 not in graph:
                        graph[human_id1] = (None, None, None)

                    if human_id2 not in graph:
                        graph[human_id2] = (None, None, None)

                    if graph[human_id1][0] != human_id2:
                        message = QErrorMessage(self)
                        message.setWindowTitle('Input data error')
                        message.showMessage('No connection')
                        return

                    human_1 = human_id1
                    human_1_spouse = None
                    human_1_parent1 = graph[human_id1][1]
                    human_1_parent2 = graph[human_id1][2]

                    human_2 = human_id2
                    human_2_spouse = None
                    human_2_parent1 = graph[human_id2][1]
                    human_2_parent2 = graph[human_id2][2]

                    human_and_time_database.RelationTable.delete().where((
                        human_and_time_database.RelationTable.human == human_1
                    ) | (human_and_time_database.RelationTable.human == human_2
                         )).execute()

                    human_and_time_database.RelationTable.create(
                        human=human_1,
                        spouse=human_1_spouse,
                        parent1=human_1_parent1,
                        parent2=human_1_parent2)

                    human_and_time_database.RelationTable.create(
                        human=human_2,
                        spouse=human_2_spouse,
                        parent1=human_2_parent1,
                        parent2=human_2_parent2)

                    self.remove_connection_widget.close()
                else:
                    all_connections = human_and_time_database.RelationTable.select(
                    )

                    graph = dict()
                    for connection in all_connections:
                        human = connection.human
                        spouse = connection.spouse
                        parent1 = connection.parent1
                        parent2 = connection.parent2
                        graph[human] = (spouse, parent1, parent2)

                    if human_id1 not in graph:
                        graph[human_id1] = (None, None, None)

                    if human_id2 not in graph:
                        graph[human_id2] = (None, None, None)

                    if graph[human_id2][1] != human_id1 and graph[human_id2][
                            2] != human_id1:
                        message = QErrorMessage(self)
                        message.setWindowTitle('Input data error')
                        message.showMessage('No connection')
                        return

                    human_1 = human_id1
                    human_1_spouse = graph[human_id1][0]
                    human_1_parent1 = graph[human_id1][1]
                    human_1_parent2 = graph[human_id1][2]

                    human_2 = human_id2
                    human_2_spouse = graph[human_id2][0]
                    human_2_parent1 = graph[human_id2][1]
                    human_2_parent2 = graph[human_id2][2]

                    if human_2_parent1 == human_1:
                        human_2_parent1 = None
                    else:
                        human_2_parent2 = None

                    human_and_time_database.RelationTable.delete().where((
                        human_and_time_database.RelationTable.human == human_1
                    ) | (human_and_time_database.RelationTable.human == human_2
                         )).execute()

                    human_and_time_database.RelationTable.create(
                        human=human_1,
                        spouse=human_1_spouse,
                        parent1=human_1_parent1,
                        parent2=human_1_parent2)

                    human_and_time_database.RelationTable.create(
                        human=human_2,
                        spouse=human_2_spouse,
                        parent1=human_2_parent1,
                        parent2=human_2_parent2)

                    self.remove_connection_widget.close()

            else:
                message = QErrorMessage(self)
                message.setWindowTitle('Input data error')
                message.showMessage('All fields must be filled')

        except Exception as e:
            print(e)

    def rebuild_tree(self):
        try:
            human_and_time_database.build_tree_from_database(self)
        except Exception as e:
            print(e)

    def keyPressEvent(self, a0: QtGui.QKeyEvent) -> None:
        if a0.key() == 43:  # plus -> zoom in
            self.graphics_view.scale(6 / 5, 6 / 5)
            self.scale *= 6 / 5
        elif a0.key() == 45:  # minus -> zoom out
            self.graphics_view.scale(5 / 6, 5 / 6)
            self.scale *= 5 / 6
        elif a0.key() == 61:  # equal -> reset zoom
            self.graphics_view.scale(1 / self.scale, 1 / self.scale)
            self.scale = 1

    def draw_rectangle(self,
                       rect,
                       pen=QPen(Qt.black, 8, Qt.SolidLine),
                       brush=QBrush(QColor.fromRgb(240, 240, 255))):
        object_rect = self.scene.addRect(rect.x1, rect.y1, rect.x2 - rect.x1,
                                         rect.y2 - rect.y1, pen, brush)

        self.rectangles.append((rect, object_rect))

        text_name = QGraphicsTextItem(rect.name)
        text_years = QGraphicsTextItem(rect.years)
        text_name.setPos(rect.x1 + 15, rect.y1 + 15)
        text_years.setPos(rect.x1 + 15, rect.y1 + 70)
        font = QFont()
        font.setBold(False)
        font.setPixelSize(35)
        text_name.setFont(font)
        text_years.setFont(font)

        self.scene.addItem(text_name)
        self.scene.addItem(text_years)

    def relax(self):
        kx = self.graphics_view.size().width() / max(
            1,
            self.graphics_view.sceneRect().width())
        ky = self.graphics_view.height() / max(
            1,
            self.graphics_view.sceneRect().height())
        k = min(kx, ky) * 2
        self.graphics_view.scale(k, k)

    def draw_line(self, line):
        color = Qt.black
        pen = QPen(color, 8, Qt.SolidLine)
        self.lines.append(line)
        self.scene.addPath(line, pen)

    def draw_event(self,
                   event,
                   min_x,
                   max_x,
                   min_y,
                   max_y,
                   pen=QPen(Qt.black, 3, Qt.SolidLine),
                   brush=QBrush(QColor.fromRgb(250, 240, 240))):

        object_event = self.scene.addRect(event.x1, event.y1,
                                          event.x2 - event.x1,
                                          event.y2 - event.y1, pen, brush)

        text = event.description.split()
        pre = 0
        result_text = event.name + '\n\n'
        for word in text:
            if pre + len(word) > 50:
                pre = 0
                result_text += '\n'
            pre += len(word) + 1
            result_text += word + ' '

        object_event.setToolTip(result_text)
        self.events.append((event, object_event))

        text_event = QGraphicsTextItem(str(event.years))
        text_event.setPos(event.x1 + 5, event.y1 + 5)
        font = QFont()
        font.setBold(False)
        font.setPixelSize(25)
        text_event.setFont(font)
        text_event.setFont(font)
        self.scene.addItem(text_event)
Пример #7
0
class IdpRecording(QWidget):
    def __init__(self):
        super().__init__()
        # -------------------- First class --------------------
        self.main_page = QHBoxLayout(self)
        self.setLayout(self.main_page)

        # -------------------- Second class --------------------
        # 1. input block (vertical)
        # 2. instruction block (horizontal)
        self.input_block = init_container(parent=self.main_page,
                                          vertical=True,
                                          style=None)

        self.instruction_block = init_container(parent=self.main_page,
                                                vertical=False,
                                                style="background-color: white;",
                                                size=config.instruction_block_size)
        # -------------------- third class --------------------
        #   1. Input block
        #       1-1. Interval last
        #       1-2. Repeats
        #       1-3. Classes
        #       1-4. Subject name
        #       1-5. Training data directory
        #       1-6. Buttons + help

        self.interval_last_block, self.interval_slider_view = init_slider_bar_box(self.input_block,
                                                                                  label=config.operation_interval_label,
                                                                                  max_value=config.recording_interval)

        self.repeats_block, self.repeat_slider_view = init_slider_bar_box(self.input_block,
                                                                          label=config.operation_repeats_label,
                                                                          max_value=config.repeat_times)

        self.classes_block, self.classes_textbox = init_inputBox(self.input_block,
                                                                 label=config.operation_classes_label,
                                                                 label_bold=False,
                                                                 default_input=config.indexPen_classes_default)

        self.subject_name_block, self.subject_names_textbox = init_inputBox(self.input_block,
                                                                            label=config.operation_subject_name_label,
                                                                            label_bold=False,
                                                                            default_input=
                                                                            config.indexPen_subjectName_default)

        self.training_dir_block, self.training_dir_textbox = init_inputBox(self.input_block,
                                                                           label=config.trainingDataPath_label,
                                                                           label_bold=False,
                                                                           default_input=
                                                                           config.indexPen_trainingDataDir_default)

        # -------------------- fourth class --------------------
        #   1-6. Buttons + help (horizontally distributed)
        #       1-6-1. Buttons
        #       1-6-2. Help (message box)

        self.buttons_block = init_container(self.input_block, vertical=False)
        self.help_block = init_container(self.input_block)

        # -------------------- fifth class --------------------
        #       1-6-1. Buttons
        #           1-6-1-1. Interrupt
        #           1-6-1-2. Start/end test
        #           1-6-1-3. Start Recording

        self.interrupt_btn = init_button(parent=self.buttons_block,
                                         label=config.interrupt_btn_label,
                                         function=self.interrupt_btn_action)

        self.test_btn = init_button(parent=self.buttons_block,
                                    label=config.test_btn_start_label,
                                    function=self.test_btn_action)

        self.recording_btn = init_button(parent=self.buttons_block,
                                         label=config.record_btn_start_label,
                                         function=self.recording_btn_action)

        self.help_btn = init_button(parent=self.buttons_block,
                                    label=config.help_btn_label,
                                    function=help_btn_action)

        # -------------------- third class --------------------
        #   1. Instruction block (horizontal)
        #       1-1. circles block (vertical)
        #       1-2. text block (vertical)

        self.counter_block = init_container(parent=self.instruction_block, vertical=True,
                                            size=config.counter_block_size)
        self.ist_text_block = init_container(parent=self.instruction_block, vertical=True,
                                             size=config.ist_text_block_size)
        # -------------------- fourth class --------------------
        #       1-1. circles block (vertical)
        #           1-1-1. circles_view
        #               1-1-1-1. circles_scene
        #                   1-1-1-1. 4 circles drawn to the scene

        self.metronome_scene = QGraphicsScene()
        self.metronome_view = QGraphicsView(self.metronome_scene)
        # positions of the four circles
        # stored for redraw
        self.x1, self.x2, self.x3, self.x4, self.y1, self.y2, self.y3, self.y4, self.circle_scene_width, \
        self.circle_scene_height = self.setup_canvas()
        # show the circles
        self.paint(first_circle_colored=False)

        # -------------------- fourth class --------------------
        #       1-2. text block (vertical)
        #           ------- preparation -------
        #           1-1-1. "You will be writing:
 "
        #                  char_set ::= A sequence of text the user will write
        #                  "Press Enter To Continue"
        #
        #           ------- forecast ------
        #           1-1-1. Label1: Forecast
        #
        #           ------- record ------
        #           1-1-1. Label1: "Write"
        #                  character to write
        #                  "...next" + next character to write

        # will be initialized when the user presses enter/return after preparation
        self.countdown_block, self.countdown_label = None, None
        # will be initialized when the forecast animation is over
        self.lb_char_to_write, self.lb_char_next = None, None

        self.show()

        # ============================= others ==========================

        # get input values
        self.interval = self.interval_slider_view.slider.value()
        self.repeat_times = self.repeat_slider_view.slider.value()
        # stored in a list
        self.classes = self.get_classes()
        self.subject_name = self.get_subject_name()
        self.training_dir = self.get_training_data_dir()
        self.char_set = generate_char_set(self.classes, self.repeat_times)

        # ======================= indicators, counters ==========================
        self.state = ['idle']  # see the docstring of self.update_state for details

        # tracking if the user pressed the return key to start recording
        self.is_dir_valid = False
        self.cur_countdown, self.tempo_counter = 0, 0

        self.reset_instruction()

        # =========================== timers =============================
        self.timer = QtCore.QTimer()
        self.timer.setTimerType(QtCore.Qt.PreciseTimer)
        self.timer.setInterval(self.interval * 1000)
        self.timer.timeout.connect(self.ticks)
        self.timer.start()
        # self.count = 0
        # self.start_time = time.time()


    def update_state(self, action):
        """
        update the current state based on action
        The working states, as oppose to 'idle' include that of 'pending', 'testing', 'countingDown', 'writing'
        @param action: str: issued with the following functions with the corresponding value:
            * self.keyPressEvent(): 'enter_pressed'
            * self.countdown_tick(): 'countdown_over'
            * self.test_btn_action(): 'start_test'
            * self.update_state: 'countdown_over'  @@for restarting writing when in test mode
        @note: you will see that there's a slight pause at the start of writing and the instruction says writing '...',
                this is an expected behavior as we are not updating the states in a clock, but rather posting to the
                state changes in function class. It's not a bug, it's a feature!
        """
        if action == 'test_pressed':
            if 'idle' in self.state:  # start the test mode
                self.idle_to_pending()
                self.state = ['testing', 'pending']
            else:  # back to idle
                self.update_state('interrupt')  # this is equivalent to issuing an interrupt action
        # break pending state and start count down
        elif action == 'enter_pressed':
            if 'pending' in self.state:
                self.state.remove('pending')
                self.state.append('countingDown')
                self.pending_to_countdown()
        elif action == 'countdown_over':
            if 'countingDown' in self.state:  # countingDown may not be in the states if looping in test mode
                self.state.remove('countingDown')
            self.state.append('writing')
            self.countdown_to_writing()
        elif action == 'writing_over':
            self.state.remove('writing')
            if 'testing' in self.state:  # restart writing if in test mode
                self.update_state('countdown_over')
            elif '':
                pass  # TODO implement writing over when in recording mode
            else:
                raise Exception('Unknown State change')
        elif action == 'interrupt':
            self.working_to_idle()  # working includes that
            self.state = ['idle']
        else:
            raise Exception('Unknown State change')
        self.resolve_state()

    def resolve_state(self):
        if 'testing' in self.state:
            self.test_btn.setText(config.test_btn_end_label)
            self.recording_btn.setDisabled(True)
        else:
            self.test_btn.setText(config.test_btn_start_label)
            self.recording_btn.setDisabled(False)

    def idle_to_pending(self):
        self.get_experiment_config()
        self.char_set = generate_char_set(self.classes, self.repeat_times)
        init_preparation_block(parent=self.ist_text_block, text=self.char_set)

    def working_to_idle(self):
        self.reset_instruction()

    def pending_to_countdown(self):
        # clear the preparation text block
        self.reset_instruction()
        # create the forecast block
        self.countdown_block, self.countdown_label = init_countdown_block(self.ist_text_block,
                                                                          label="   ",
                                                                          font=36,
                                                                          bold=True)

    def countdown_to_writing(self):
        clear_layout(self.ist_text_block)
        self.reset_instruction()
        self.lb_char_to_write, self.lb_char_next = init_instruction_text_block(self.ist_text_block)

    def keyPressEvent(self, key_event):
        print(key_event)
        if is_enter_key_event(key_event):
            self.update_state('enter_pressed')

    @pg.QtCore.pyqtSlot()
    def ticks(self):
        """
        check the current state
        ticks every 'refresh' milliseconds
        """
        # duration = time.time() - self.start_time
        # self.count += 1
        if 'pending' in self.state:
            pass
        elif 'countingDown' in self.state:
            self.countdown_tick()
        elif 'writing' in self.state:
            self.metronome_tick()
        pass

    @pg.QtCore.pyqtSlot()
    def countdown_tick(self):
        # after the text block shows all countdown texts, stop updating, do nothing and return
        if self.cur_countdown == len(config.countdown_animation_text):
            self.cur_countdown += 1
            return
        # wait for a given interval and start the input timer
        elif self.cur_countdown > len(config.countdown_animation_text):  # end of counting down
            self.update_state('countdown_over')
        else:
            self.countdown_label.setText(config.countdown_animation_text[self.cur_countdown])
            self.cur_countdown += 1

    def metronome_tick(self):
        # tempo: dah, dih, dih,dih
        self.repaint(circle=self.tempo_counter % 4 + 1)
        if not self.tempo_counter % 4:
            dah()
            char_count = int(self.tempo_counter / 4)
            if char_count < len(self.char_set):
                # draw a new one
                cur_char = self.char_set[char_count]
                next_char = 'no Next' if (char_count + 1) == len(self.char_set) else self.char_set[char_count + 1]
                self.lb_char_to_write.setText(cur_char)
                self.lb_char_next.setText(config.instruction_next_text + next_char)
            # finish a recording loop
            else:
                self.update_state('writing_over')
                # must return here to avoid further incrementing the tempo counter, it is reset within update_state()
                return
        else:
            dih()

        self.tempo_counter += 1

    def setup_canvas(self):

        self.counter_block.addWidget(self.metronome_view)
        self.metronome_view.resize(config.unit_size, config.WINDOW_HEIGHT / 3)
        position = self.metronome_view.pos()

        self.metronome_scene.setSceneRect(position.x(), position.y(), self.metronome_view.width(),
                                          self.metronome_view.height())

        # size of the scene
        width = self.metronome_scene.width()
        height = self.metronome_scene.height()

        # positions of circles
        x1, y1 = position.x() + width / 3, position.y()
        x2, y2 = position.x() + width / 3, position.y() + 3 * (height / 10)
        x3, y3 = position.x() + width / 3, position.y() + 6 * (height / 10)
        x4, y4 = position.x() + width / 3, position.y() + 9 * (height / 10)

        return x1, x2, x3, x4, y1, y2, y3, y4, width, height

    def repaint(self, circle=1):

        x = self.x1
        y = self.y1

        if circle == 1:
            # remove all current circles
            for item in self.metronome_scene.items():
                self.metronome_scene.removeItem(item)
            # paint them light gray
            self.paint()

        else:
            if circle == 2:
                x = self.x2
                y = self.y2
            elif circle == 3:
                x = self.x3
                y = self.y3
            elif circle == 4:
                x = self.x4
                y = self.y4

        # locate the circle
        circle = self.metronome_scene.itemAt(x, y, QTransform())
        # remove the original circle
        if circle:
            self.metronome_scene.removeItem(circle)

        # repaint a blue one
        pen = QPen(Qt.black, 5, Qt.SolidLine)
        brush = QBrush(Qt.blue, Qt.SolidPattern)
        self.metronome_scene.addEllipse(x, y,
                                        self.circle_scene_width / 3, self.circle_scene_width / 3,
                                        pen, brush)

    def paint(self, first_circle_colored=False):

        pen = QPen(Qt.black, 5, Qt.SolidLine)
        brush = QBrush(Qt.lightGray, Qt.SolidPattern)

        self.metronome_scene.addEllipse(self.x2, self.y2,
                                        self.circle_scene_width / 3, self.circle_scene_width / 3,
                                        pen, brush)
        self.metronome_scene.addEllipse(self.x3, self.y3,
                                        self.circle_scene_width / 3, self.circle_scene_width / 3,
                                        pen, brush)
        self.metronome_scene.addEllipse(self.x4, self.y4,
                                        self.circle_scene_width / 3, self.circle_scene_width / 3,
                                        pen, brush)

        if first_circle_colored:
            brush = QBrush(Qt.blue, Qt.SolidPattern)

        self.metronome_scene.addEllipse(self.x1, self.y1,
                                        self.circle_scene_width / 3, self.circle_scene_width / 3,
                                        pen, brush)

    def get_experiment_config(self):
        self.interval = self.interval_slider_view.slider.value()
        self.repeat_times = self.repeat_slider_view.slider.value()
        self.classes = self.get_classes()
        self.subject_name = self.get_subject_name()
        self.training_dir = self.get_training_data_dir()

    def get_training_data_dir(self):
        _user_input = self.training_dir_textbox.text()
        if not _user_input:
            _user_input = config.indexPen_trainingDataDir_default

        return _user_input

    def get_subject_name(self):
        _user_input = self.subject_names_textbox.text()
        if not _user_input:
            _user_input = config.indexPen_subjectName_default
        return _user_input

    def get_classes(self):
        _user_input = self.classes_textbox.text()
        if not _user_input:
            _user_input = config.indexPen_classes_default

        # change to a list
        classes = _user_input.split(" ")
        return classes

    def interrupt_btn_action(self):
        self.update_state('interrupt')

    def test_btn_action(self):
        self.update_state('test_pressed')

    def recording_btn_action(self):
        # TODO implement this action
        pass
        # if self.is_recording:
        #     self.reset()
        #
        # # if not recording yet
        # elif not self.is_recording:
        #
        #     self.get_experiment_config()
        #     # try starting recording
        #     # check the data path first
        #     self.is_dir_valid = self.check_dir_valid()
        #
        #     if self.is_dir_valid:
        #         # if valid data path, show preparation page
        #         # start recording
        #         self.is_recording = True
        #         self.prepare()
        #         self.recording_btn.setText(config.record_btn_end_label)
        #         self.countdown_timer.start()
        #
        #         msg = QMessageBox()
        #         msg.setIcon(QMessageBox.Information)
        #         msg.setText("Recording")
        #         msg.exec()

    def check_dir_valid(self):
        print(self.training_dir)
        if os.path.exists(self.training_dir):
            return True
        else:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)
            msg.setText(config.datapath_invalid_message)
            msg.exec()
            return False

    def reset_instruction(self):
        clear_layout(self.ist_text_block)
        for item in self.metronome_scene.items():
            self.metronome_scene.removeItem(item)
        self.paint()
        self.lb_char_next, self.lb_char_to_write = None, None
        self.cur_countdown, self.tempo_counter = 0, 0
Пример #8
0
class Example(QWidget):
    def paintEvent(self, e):
        self.qp.begin(self)
        self.draw()
        self.qp.end()

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

        self.elements = []
        """
        self.elements: QGraphicsObject[]
        """

        self.scene = QGraphicsScene()
        self.graphicsView = QGraphicsView(self.scene)

        hbox = QHBoxLayout()
        hbox.addWidget(self.graphicsView)
        # hbox.addWidget(self.wid)
        vbox = QVBoxLayout()
        vbox.addStretch(1)
        vbox.addLayout(hbox)
        self.setLayout(vbox)

        self.setGeometry(300, 300, 500, 500)
        self.setWindowTitle('My first app')

        font = QFont('Ubuntu', 20, QFont.Normal)
        self.scene.setFont(font)

        self.qp = QPainter(self.graphicsView)

        self.lcd = QLCDNumber(self.graphicsView)

        self.slider = QSlider(self.graphicsView)
        self.slider.setOrientation(Qt.Horizontal)
        self.slider.setGeometry(0,
                                self.graphicsView.height() - 30,
                                self.graphicsView.width(), 30)
        self.slider.valueChanged.connect(self.changer)

        self.elements.append(self.scene.addText('@!#'))

        self.show()

    def changer(self, e: int):
        self.lcd.display(e)
        # self.wid.testDraw(e)
        # self.graphicsView.
        font = QFont('Ubuntu', e * 2 + 16, QFont.Bold)
        self.elements[0].setFont(font)  # dynamic change

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Q:
            exit(0)
            # print(event.key())

    def draw(self):

        self.graphicsView.setGeometry(0, 0, self.width(), self.height())

        self.lcd.move(self.graphicsView.width() - self.lcd.width() - 4, 3)

        # self.qp.qp.drawLine(0, 0, 100, 200)
        # self.qp.drawText(80, 80, "@!#")
        # self.qp.qp.drawArc(50, 50, 20, 20, 100, 4000)
        # self.qp.qp.drawPie(50, 50, 20, 20, 100, 4000)
        # self.qp.qp.drawRect(1,2, self.graphicsView.width() - 4, self.graphicsView.height() - 3)
        self.slider.setGeometry(0,
                                self.graphicsView.height() - 30,
                                self.graphicsView.width(), 30)
Пример #9
0
    # Show the scene
    # First the view widget gets the event, which sends it to the scene
    # The scene sends the event to the item in focus
    view = QGraphicsView(scene)
    view.setBackgroundBrush(QBrush(QImage("./res/images/background.png")))
    view.setAttribute(Qt.WA_DeleteOnClose)
    view.setViewport(QGLWidget())
    view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
    view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
    view.setFixedSize(800, 600)
    scene.setSceneRect(0, 0, 800, 600)

    # set the end condition
    health.dead.connect(functools.partial(gameOver, app, view, scene))
    # set the player position
    player.setPos(view.width() / 2, view.height() - player.pixmap().height())

    # play the background music
    url = QUrl.fromLocalFile("./res/sounds/background.wav")
    media = M.QMediaContent(url)
    playlist = M.QMediaPlaylist()
    playlist.addMedia(media)
    playlist.setPlaybackMode(M.QMediaPlaylist.Loop)
    music = M.QMediaPlayer()
    music.setPlaylist(playlist)
    music.setVolume(10)
    music.play()
    view.show()
    sys.exit(app.exec_())
Пример #10
0
class BattleView(QObject):
    def __init__(self, battle_window, parent=None):
        super().__init__(parent)
        self.battleWindow = battle_window  # MainBattleWindow container_widget

        if len(self.battleWindow.config.errors) != 0:
            # noinspection PyArgumentList
            QMessageBox.critical(battle_window, 'Configuration Error', self.battleWindow.config.get_error_str())
            exit(-1)

        # main elements
        self.centralWidget = QWidget(self.battleWindow)
        self.gridLayout = QGridLayout(self.centralWidget)

        # misc side elements
        self.graphicsView_coatOfArm = CustomScene()
        self.graphicsView_currentUnit = CustomScene()
        self.graphicsView_targetedUnit = CustomScene()

        for button in self.graphicsView_coatOfArm, self.graphicsView_currentUnit, self.graphicsView_targetedUnit:
            button.enter_functions.append(self.set_label_hint)
            button.leave_functions.append(self.clear_label_hint)

        # buttons
        self.autoCombatButton = CustomButton(self.centralWidget)
        self.helpButton = CustomButton(self.centralWidget)
        self.retreatButton = CustomButton(self.centralWidget)
        self.endUnitTurnButton = CustomButton(self.centralWidget)
        self.nextTargetButton = CustomButton(self.centralWidget)

        for button in self.autoCombatButton, self.helpButton, self.retreatButton, self.nextTargetButton, self.endUnitTurnButton:
            button.enter_functions.append(self.set_label_hint)
            button.leave_functions.append(self.clear_label_hint)
            button.click_functions.append(self.click_button)

        # info containers
        self.dateLabel = QLabel(self.centralWidget)  # display current turn in battle
        self.hintLabel = QLabel(self.centralWidget)  # display hint when hovering over an elemend

        # the actual battle scene
        self.mainScene = MainQGraphicsScene()
        self.graphicsView_main = QGraphicsView(self.mainScene)
        self.gridLayout.addWidget(self.graphicsView_main, 1, 0, 12, 1)

    def setup_ui(self):
        self.battleWindow.setWindowTitle(self.battleWindow.config.get_text('battle.window.title') + ' v' + str(self.battleWindow.config.version))
        background = self.battleWindow.config.theme_selected.get_background_pixmap()
        palette = QPalette()
        palette.setBrush(QPalette.Background, QBrush(background))
        self.battleWindow.setMinimumSize(constants.get_min_resolution_qsize())
        self.battleWindow.setAutoFillBackground(True)
        self.gridLayout.setVerticalSpacing(0)

        self.setup_hint_label()  # Labels
        self.setup_turn_label()  # Labels
        self.setup_space()  # Space item

        self.setup_help_button()  # Help Push Button
        self.setup_next_target_button()  # Next Target Button
        self.setup_end_unit_button()  # End Unit Button
        self.setup_retreat_button()  # Retreat Button
        self.setup_auto_combat_button()  # Automatic battle button

        self.setup_targeted_unit_view()  # Targeted Unit view
        self.setup_current_unit_view()  # Current Unit View
        self.setup_coat_of_arms_view()  # Coat of Arm view

        self.setup_map()  # Main view
        self.battleWindow.setPalette(palette)
        self.battleWindow.setCentralWidget(self.centralWidget)

        # noinspection PyArgumentList
        QMetaObject.connectSlotsByName(self.battleWindow)

    def setup_map(self):
        self.mainScene = MainQGraphicsScene()
        self.graphicsView_main.setScene(self.mainScene)
        self.mainScene.set_battle_view(self.battleView)
        width = 2 * self.graphicsView_main.height() / math.sqrt(3)
        height = self.graphicsView_main.height()
        if width > self.graphicsView_main.width():
            width = self.graphicsView_main.width()
            height = self.graphicsView_main.width() * math.sqrt(3) / 2
        item = self.mainScene.addRect(0, 0, width - 15, height - 15)
        item.hide()
        self.battleView.draw_battle_map(self.mainScene)

    def resize_event(self):
        self.setup_map()

    # misc elements
    def setup_hint_label(self):
        size_policy = constants.default_size_policy(self.hintLabel, QSizePolicy.Preferred, QSizePolicy.Fixed)
        self.hintLabel.setSizePolicy(size_policy)
        self.hintLabel.setFont(constants.default_font())
        self.hintLabel.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.hintLabel, 0, 0, 1, 1)

    def setup_turn_label(self):
        size_policy = constants.default_size_policy(self.dateLabel, QSizePolicy.Preferred, QSizePolicy.Fixed)
        self.dateLabel.setSizePolicy(size_policy)
        self.dateLabel.setFont(constants.default_font())
        self.dateLabel.setText('Turn ' + str(self.battleView.turn))
        self.dateLabel.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.dateLabel, 0, 0, 1, 1)

    def setup_space(self):
        # Space between help Button and flag view
        spacer_item = QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
        self.gridLayout.addItem(spacer_item, 2, 1, 1, 1)
        # Space between flag view and next target Button
        spacer_item1 = QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
        self.gridLayout.addItem(spacer_item1, 4, 1, 1, 1)
        # Space between retreat Button and targetted unit view
        spacer_item2 = QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.gridLayout.addItem(spacer_item2, 8, 1, 1, 1)
        # Space between current unit view and auto Button
        spacer_item3 = QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
        self.gridLayout.addItem(spacer_item3, 11, 1, 1, 1)

    def setup_coat_of_arms_view(self):
        size = QSize(90, 120)
        self.battleView.draw_coat_of_arms(self.graphicsView_coatOfArm.scene(), size)
        self.graphicsView_coatOfArm.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        size_policy = constants.default_size_policy(self.graphicsView_coatOfArm, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.graphicsView_coatOfArm.setSizePolicy(size_policy)
        self.graphicsView_coatOfArm.setMinimumSize(size)
        self.graphicsView_coatOfArm.setMaximumSize(size)
        self.graphicsView_coatOfArm.setStyleSheet("border-style: none;background: transparent")
        self.graphicsView_coatOfArm.setCacheMode(QGraphicsView.CacheBackground)
        self.gridLayout.addWidget(self.graphicsView_coatOfArm, 3, 1, 1, 1)

    # unit views
    def setup_targeted_unit_view(self):
        size = QSize(60, 60)
        army = self.get_computer_army()
        defending = (army == self.battleView.defender)
        self.battleView.draw_targetted_unit(defending, self.graphicsView_targetedUnit.scene(), size)
        size_policy = constants.default_size_policy(self.graphicsView_targetedUnit, QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)
        self.graphicsView_targetedUnit.setSizePolicy(size_policy)
        self.graphicsView_targetedUnit.setMinimumSize(size)
        self.graphicsView_targetedUnit.setMaximumSize(size)
        self.gridLayout.addWidget(self.graphicsView_targetedUnit, 9, 1, 1, 1, Qt.AlignCenter)

    def setup_current_unit_view(self):
        size = QSize(60, 60)
        army = self.get_human_army()
        defending = (army == self.battleView.defender)
        self.battleView.draw_current_unit(defending, self.graphicsView_currentUnit.scene(), size)
        size_policy = constants.default_size_policy(self.graphicsView_currentUnit, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.graphicsView_currentUnit.setSizePolicy(size_policy)
        self.graphicsView_currentUnit.setMinimumSize(size)
        self.graphicsView_currentUnit.setMaximumSize(size)
        self.gridLayout.addWidget(self.graphicsView_currentUnit, 10, 1, 1, 1, Qt.AlignCenter)

    def get_human_army(self):
        if self.battleView.attacker.nation.computer:
            return self.battleView.defender
        return self.battleView.attacker

    def get_computer_army(self):
        if self.battleView.attacker.nation.computer:
            return self.battleView.attacker
        return self.battleView.defender

    # buttons
    def setup_next_target_button(self):
        size_policy = constants.default_size_policy(self.nextTargetButton, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.nextTargetButton.setSizePolicy(size_policy)
        self.nextTargetButton.setMinimumSize(QSize(45, 45))
        self.nextTargetButton.setMaximumSize(QSize(45, 45))
        self.nextTargetButton.setText("")
        icon = QIcon()
        icon.addPixmap(QPixmap(self.battleWindow.config.theme_selected.get_target_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.nextTargetButton.setIcon(icon)
        self.nextTargetButton.setIconSize(QSize(40, 40))
        self.gridLayout.addWidget(self.nextTargetButton, 5, 1, 1, 1, Qt.AlignCenter)

    def setup_end_unit_button(self):
        size_policy = constants.default_size_policy(self.endUnitTurnButton, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.endUnitTurnButton.setSizePolicy(size_policy)
        self.endUnitTurnButton.setMinimumSize(QSize(45, 45))
        self.endUnitTurnButton.setMaximumSize(QSize(45, 45))
        self.endUnitTurnButton.setText("")
        icon1 = QIcon()
        icon1.addPixmap(self.battleWindow.config.theme_selected.get_end_button_pixmap(), QIcon.Normal, QIcon.Off)
        self.endUnitTurnButton.setIcon(icon1)
        self.endUnitTurnButton.setIconSize(QSize(40, 40))
        self.gridLayout.addWidget(self.endUnitTurnButton, 6, 1, 1, 1, Qt.AlignCenter)

    def setup_retreat_button(self):
        size_policy = constants.default_size_policy(self.retreatButton, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.retreatButton.setSizePolicy(size_policy)
        self.retreatButton.setMinimumSize(QSize(45, 45))
        self.retreatButton.setMaximumSize(QSize(45, 45))
        self.retreatButton.setToolTip("")
        self.retreatButton.setWhatsThis("")
        self.retreatButton.setText("")
        icon2 = QIcon()
        icon2.addPixmap(QPixmap(self.battleWindow.config.theme_selected.get_retreat_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.retreatButton.setIcon(icon2)
        self.retreatButton.setIconSize(QSize(42, 40))
        self.gridLayout.addWidget(self.retreatButton, 7, 1, 1, 1, Qt.AlignCenter)

    def setup_help_button(self):
        size_policy = constants.default_size_policy(self.helpButton, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.helpButton.setSizePolicy(size_policy)
        self.helpButton.setMinimumSize(QSize(80, 80))
        self.helpButton.setMaximumSize(QSize(80, 80))
        self.helpButton.setText("")
        icon3 = QIcon()
        icon3.addPixmap(QPixmap(self.battleWindow.config.theme_selected.get_help_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.helpButton.setIcon(icon3)
        self.helpButton.setIconSize(QSize(75, 75))
        self.gridLayout.addWidget(self.helpButton, 0, 1, 2, 1)

    def setup_auto_combat_button(self):
        size_policy = constants.default_size_policy(self.autoCombatButton, QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.autoCombatButton.setSizePolicy(size_policy)
        self.autoCombatButton.setMinimumSize(QSize(90, 90))
        self.autoCombatButton.setMaximumSize(QSize(90, 90))
        self.autoCombatButton.setText("")
        icon4 = QIcon()
        icon4.addPixmap(QPixmap(self.battleWindow.config.theme_selected.get_autocombat_button_pixmap()), QIcon.Normal, QIcon.Off)
        self.autoCombatButton.setIcon(icon4)
        self.autoCombatButton.setIconSize(QSize(80, 80))
        self.gridLayout.addWidget(self.autoCombatButton, 12, 1, 1, 1)

    # element interactions
    def clear_label_hint(self, generic_element):
        self.hintLabel.setText('')

    def set_label_hint(self, generic_element):
        text = ''
        if generic_element in self.battleView.map.fields:
            # TODO - not hooked up
            text = str(generic_element)
        elif generic_element == self.graphicsView_currentUnit:
            text = str(self.battleView.currentUnit)
        elif generic_element == self.graphicsView_targetedUnit:
            text = str(self.battleView.targettedUnit)
        elif generic_element == self.autoCombatButton:
            text = self.battleWindow.config.get_text('auto.play.label')
        elif generic_element == self.helpButton:
            text = self.battleWindow.config.get_text('help.tacticalbattle.label')
        elif generic_element == self.retreatButton:
            text = self.battleWindow.config.get_text('retreat.all.label')
        elif generic_element == self.endUnitTurnButton:
            text = self.battleWindow.config.get_text('end.unit.label')
        elif generic_element == self.nextTargetButton:
            text = self.battleWindow.config.get_text('next.target.label')
        if text != '':
            self.hintLabel.setText(text)

    def click_button(self, button_element):
        if button_element == self.autoCombatButton:
            self.battleView.autoCombat = True
        elif button_element == self.helpButton:
            print('click helpButton')
        elif button_element == self.retreatButton:
            self.get_human_army().retreat = True
        elif button_element == self.endUnitTurnButton:
            print('click endUnitTurnButton')
        elif button_element == self.nextTargetButton:
            print('click nextTargetButton')
Пример #11
0
class QCliWidget(QWidget):

    interpreter = Interpreter()
    display_widget = None
    vkbd = None
    beamer = None

    result_from_queue = False

    set_tab_text = pyqtSignal(str)

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

        self.unicode_fonts = UnicodeFonts()

        self.grid = QGridLayout()
        self.grid.setContentsMargins(0, 0, 0, 6)
        self.setLayout(self.grid)

        self.display_widget = QTextEditEnhanced()
        self.display_widget.setText(
            "type in the command 'man' down in the command line for getting started ..."
        )
        self.display_widget.setReadOnly(True)

        self.addDisplayWidget()

        line = QInputLine()
        line.setPlaceholderText(
            "This is the command line. See 'man commandline' for details.")
        line.return_pressed.connect(self.commandEntered)
        self.grid.addWidget(line, 1, 0)

        vkbdButton = QPushButton(self)
        vkbdButton.clicked.connect(partial(self.vkbdButtonClicked, line))
        vkbdButton.setIcon(QIcon.fromTheme('input-keyboard'))
        self.grid.addWidget(vkbdButton, 1, 1)

        zoomOutButton = QPushButton(self)
        zoomOutButton.setIcon(QIcon.fromTheme('zoom-out'))
        zoomOutButton.clicked.connect(self.onZoomOutClicked)
        self.grid.addWidget(zoomOutButton, 1, 2)

        zoomResetButton = QPushButton(self)
        zoomResetButton.setIcon(QIcon.fromTheme('zoom-original'))
        zoomResetButton.clicked.connect(self.onZoomResetClicked)
        self.grid.addWidget(zoomResetButton, 1, 3)

        zoomInButton = QPushButton(self)
        zoomInButton.setIcon(QIcon.fromTheme('zoom-in'))
        zoomInButton.clicked.connect(self.onZoomInClicked)
        self.grid.addWidget(zoomInButton, 1, 4)

        self.applyStylesheet()

    def applyStylesheet(self):
        config = ConfigFile(None, None)
        path = config.readVar('global', 'stylesheet')
        stylesheet = ''
        try:
            with open(path) as css:
                for line in css:
                    stylesheet += line

            self.display_widget.setStyleSheet(stylesheet)
        except FileNotFoundError:
            pass

    def addDisplayWidget(self):
        self.view = QGraphicsView()
        self.scene = QGraphicsScene()

        self.scene.addWidget(self.display_widget)
        self.view.setScene(self.scene)
        self.view.setStyleSheet("QGraphicsView { border-style: none; }")

        self.grid.addWidget(self.view, 0, 0, 1, 0)

        self.resizeDisplayWidget()

        self.applyStylesheet()

    def resizeDisplayWidget(self):
        # the magick numbers are for keeping the size of the view allways small enough not to spawn an outer set of scrollbars:
        x = self.view.width() - 2.1
        y = self.view.height() - 2.1
        self.x, self.y = x, y

        mapped_rect = self.view.mapToScene(QRect(0, 0, x, y)).boundingRect()

        self.display_widget.setFixedSize(mapped_rect.width(),
                                         mapped_rect.height())
        self.scene.setSceneRect(0, 0, mapped_rect.width(),
                                mapped_rect.height())

    def resizeEvent(self, event):
        self.resizeDisplayWidget()

    def vkbdButtonClicked(self, lineEdit):
        self.vkbd = QVirtualKeyboardWindow()
        self.vkbd.setLineEdit(lineEdit)

    def commandEntered(self, command):
        # to keep the display_widget in the correct size
        self.resize(self.x, self.y)

        print("command:", command)
        if '|' in command:
            command, pipe = command.split('|')
            self.handleCommand(command)

            pipe = pipe.strip()
            if pipe == 'beamer':
                if self.beamer:
                    self.beamer.destroy()
                    print('destroyed!!!')

                self.beamer = QBeamerWindow()

                from PyQt5.QtWidgets import QLabel, QPushButton
                widget = QLabel('blaaaa')

                self.beamer.setWidget(self.display_widget)
                #self.beamer.setText('test')
                self.beamer.routeToScreen()
                self.beamer.showFullScreen()
        else:
            #self.handleCommand(command)
            self.set_tab_text.emit(command)

            #self.activityIndicator()

            q = queue.Queue()

            self.interpreter_thread = HandleCommandThread(command, q)
            self.interpreter_thread.processResult.connect(self.processResult)
            self.interpreter_thread.clearDisplayWidget.connect(
                self.clearDisplayWidget)
            self.interpreter_thread.makeSnapshot.connect(self.makeSnapshot)
            self.interpreter_thread.stopQueueListener.connect(
                self.stopQueueListener)
            self.interpreter_thread.start()

            self.queue_thread = GetQueueItemsThread(q)
            self.queue_thread.processQueueItem.connect(self.processQueueItem)
            self.queue_thread.start()

    def stopQueueListener(self):
        self.queue_thread.stop()

    def processQueueItem(self, item):
        self.result_from_queue = True

        item = item.getItem()

        json_dict = json.loads(item)
        if json_dict['category'] == 'progressbar':
            last_type = type(self.display_widget)
            if not last_type == QProgressBar:
                self.display_widget.deleteLater()
                self.display_widget = QProgressBar()

            self.display_widget.setMinimum(json_dict['minimum'])
            self.display_widget.setMaximum(json_dict['maximum'])
            self.display_widget.setValue(json_dict['value'])

            if not last_type == QProgressBar:
                self.addDisplayWidget()

        else:
            result_object = Result()
            result_object.payload = item.getItem()
            self.resultInTextEdit(result_object)

    def processResult(self, result):
        if self.result_from_queue:
            self.result_from_queue = False

        else:
            #if result is None:
            #self.showErrorMessage('no result found')

            if hasattr(result, 'payload') and result.payload:
                if hasattr(result, 'category') and result.category == "table":
                    try:
                        result.payload[0]
                    except IndexError:
                        pass  # datastructure does not fit to display type 'table'
                    else:
                        self.resultInTable(result)

                elif hasattr(
                        result,
                        'category') and result.category == "multimedia_table":
                    self.resultInMultimediaTable(result)

                elif hasattr(result, 'category') and result.category == "list":
                    self.resultInTextEdit(result)

                elif hasattr(result, 'category') and result.category == "text":
                    self.resultInTextEdit(result)

                elif hasattr(result,
                             'category') and result.category == "string":
                    self.resultInTextEdit(result)

                elif hasattr(result,
                             'category') and result.category == "itemized":
                    self.resultInItemizedWidget(result)

                elif hasattr(result,
                             'category') and result.category == "image":
                    self.resultInImageWidget(result)

                elif hasattr(result, 'category') and result.category == "html":
                    #self.resultInHTMLWidget(result)
                    self.resultInTextEdit(result)

                elif hasattr(result,
                             'category') and result.category == 'diagram':
                    self.resultInDiagram(result)

                elif hasattr(result,
                             'category') and result.category == 'bloodline':
                    self.resultInBloodlineDiagram(result)

                elif hasattr(result,
                             'category') and result.category == 'command':
                    self.showMapWidget()

            elif hasattr(result, 'error') and result.error:
                self.showErrorMessage(result.error)

            else:
                result = Result()
                result.payload = 'empty result set'
                self.resultInTextEdit(result)

    def activityIndicator(self):
        self.display_widget.deleteLater()

        label = QLabel()
        movie = QMovie('./assets/images/activity_indicator.gif')
        movie.start()
        label.setMovie(movie)

        self.display_widget = QWidget()
        layout = QVBoxLayout()
        self.display_widget.setLayout(layout)
        layout.addWidget(label, Qt.AlignCenter)

        self.addDisplayWidget()

    def clearDisplayWidget(self):
        self.display_widget.deleteLater()
        self.display_widget = QTextEditEnhanced()
        self.display_widget.setReadOnly(True)
        self.addDisplayWidget()

    def makeSnapshot(self):
        image = QImage(self.display_widget.size(), QImage.Format_ARGB32)
        painter = QPainter(image)

        if painter.isActive():
            self.render(painter)

        painter.end()

        default_dir = path.join(path.expanduser('~'))
        filename = QFileDialog.getSaveFileName(self, 'Save Snapshot',
                                               default_dir)

        image.save(filename[0])

    def resultInTable(self, result):
        self.display_widget.deleteLater()
        self.display_widget = QTableWidget()
        self.display_widget.setRowCount(len(result.payload))
        self.display_widget.setColumnCount(len(result.payload[0]))

        try:
            self.display_widget.setHorizontalHeaderLabels(result.header)
        except TypeError:
            pass
        try:
            self.display_widget.setVerticalHeaderLabels(result.header_left)
        except TypeError:
            pass

        for row, line in enumerate(result.payload):
            for column, item in enumerate(line):
                table_item = QTableWidgetItem(str(item))
                table_item.setFlags(Qt.ItemIsEnabled)
                self.unicode_fonts.applyFontToQWidget(str(item), table_item)
                self.display_widget.setItem(row, column, table_item)

        self.display_widget.resizeColumnsToContents()
        self.addDisplayWidget()

    def resultInMultimediaTable(self, result):
        self.display_widget.deleteLater()

        max_length = 0
        for line in result.payload:
            if len(line) > max_length:
                max_length = len(line)

        self.display_widget = QTableWidget()
        self.display_widget.setRowCount(len(result.payload))
        self.display_widget.setColumnCount(max_length)

        audio_count = 0
        config = ConfigFile(None, None)
        deckpath = config.readPath("vocable", "deckpath")
        for row, line in enumerate(result.payload):
            deckname = line[0]
            for column, item in enumerate(line):
                if self.isImage(str(item)):
                    pixmap = QPixmap()
                    pixmap.load(path.join(deckpath, deckname, str(item)))
                    pixmap = pixmap.scaled(QSize(60, 30), Qt.KeepAspectRatio)
                    image_widget = QLabel()
                    image_widget.setPixmap(pixmap)
                    self.display_widget.setCellWidget(row, column,
                                                      image_widget)
                elif self.isAudio(str(item)):
                    splitted = item.split(',')
                    if audio_count < len(splitted):
                        audio_count = len(splitted)
                    audio_widget = QAudioItems(path.join(deckpath, deckname),
                                               self.display_widget, 7,
                                               max_length)
                    audio_widget.appendPlayButtonsList(splitted, row)
                else:
                    table_item = QTableWidgetItem(str(item))
                    table_item.setFlags(Qt.ItemIsEnabled)
                    #self.unicode_fonts.applyFontToQWidget(str(item), table_item)
                    self.display_widget.setItem(row, column, table_item)

        self.display_widget.setColumnCount(max_length + audio_count)
        self.display_widget.resizeColumnsToContents()
        self.addDisplayWidget()

    def resultInTextEdit(self, result):
        self.display_widget.deleteLater()
        self.display_widget = QTextEditEnhanced()

        self.unicode_fonts.applyFontAndSizeToQWidget(result.toString(),
                                                     self.display_widget)

        self.display_widget.setAcceptRichText(True)

        self.display_widget.setText(result.toString())
        self.display_widget.setReadOnly(True)
        self.display_widget.setTextInteractionFlags(
            self.display_widget.textInteractionFlags()
            | Qt.TextSelectableByKeyboard)
        self.addDisplayWidget()

    def resultInHTMLWidget(self, result):
        self.display_widget.deleteLater()
        self.display_widget = QWebView()

        self.display_widget.setHtml(result.payload)
        self.addDisplayWidget()

    def resultInItemizedWidget(self, result):
        self.display_widget.deleteLater()
        self.display_widget = QItemizedWidget(result.payload)
        self.addDisplayWidget()

    def resultInImageWidget(self, result):
        self.display_widget.deleteLater()

        self.display_widget = QCustomizedGraphicsView()

        import PIL
        if type(result.payload) == PIL.Image.Image:
            from PIL.ImageQt import ImageQt
            qimage = ImageQt(result.payload)
            pixmap = QPixmap.fromImage(qimage)

        #pixmap = QPixmap("/tmp/tmprp3q0gi9.PNG")
        #pixmap.fromImage(image)

        item = self.display_widget.scene().addPixmap(pixmap)
        item.setPos(0, 0)
        self.addDisplayWidget()

    def resultInDiagram(self, result):
        self.display_widget.deleteLater()

        curve = QLineSeries()
        pen = curve.pen()
        pen.setColor(Qt.red)
        pen.setWidthF(2)
        curve.setPen(pen)

        for data in result.payload:
            if type(data['y']) == str:
                data['y'] = 0
            curve.append(data['x'], data['y'], 10)

        chart = QChart()
        chart.setTitle(result.name)
        chart.legend().hide()
        chart.addSeries(curve)
        chart.createDefaultAxes()

        view = QChartViewEnhanced(chart)
        view.setRenderHint(QPainter.Antialiasing)
        self.display_widget = view
        self.addDisplayWidget()

    def resultInBloodlineDiagram(self, result):
        self.display_widget.deleteLater()
        self.display_widget = QBloodlineWidget(result.payload)
        self.addDisplayWidget()

    def showMapWidget(self):
        self.display_widget.deleteLater()

        self.display_widget = QMapWidget()
        self.display_widget.showPosition()

        self.addDisplayWidget()

    def showErrorMessage(self, message):
        self.display_widget.deleteLater()
        self.display_widget = QTextEditEnhanced()
        self.display_widget.setText(message)
        self.display_widget.setReadOnly(True)
        self.addDisplayWidget()

    def onZoomInClicked(self):
        if type(self.display_widget) == QTextEditEnhanced:
            self.display_widget.zoomIn()
        elif type(self.display_widget) == QChartViewEnhanced:
            self.display_widget.chart().zoomIn()
        else:
            self.view.scale(SCALE_FACTOR, SCALE_FACTOR)
            self.resizeDisplayWidget()

    def onZoomOutClicked(self):
        if type(self.display_widget) == QTextEditEnhanced:
            self.display_widget.zoomOut()
        elif type(self.display_widget) == QChartViewEnhanced:
            self.display_widget.chart().zoomOut()
        else:
            self.view.scale(1 / SCALE_FACTOR, 1 / SCALE_FACTOR)
            self.resizeDisplayWidget()

    def onZoomResetClicked(self):
        if type(self.display_widget) == QTextEditEnhanced:
            self.display_widget.zoomReset()
        elif type(self.display_widget) == QChartViewEnhanced:
            self.display_widget.chart().zoomReset()
        else:
            self.view.resetTransform()
            self.resizeDisplayWidget()

    def keyPressEvent(self, event):
        if (event.modifiers() & Qt.ControlModifier):
            if event.key() == Qt.Key_Plus:
                self.onZoomInClicked()

            elif event.key() == Qt.Key_Minus:
                self.onZoomOutClicked()

    def isImage(self, data):
        suffixes = ['.png', '.jpg', '.jpe', '.jpeg', '.svg', '.bmp']
        for suffix in suffixes:
            if data.lower().endswith(suffix):
                return True
        return False

    def isAudio(self, data):
        suffixes = ['.ogg', '.wav', '.mp3', '.aiff', '.wma']
        for suffix in suffixes:
            if data.lower().endswith(suffix):
                return True
        return False
Пример #12
0
class ViewWindow(QMainWindow):  # QWidget):
    def __init__(self):
        super().__init__()
        self.pilorig = None
        self.savedImg = None
        self.controlPanel = None
        self.dirName, self.fileName = '', ''
        self.dirFileNames = []
        self.fileIdx = -1
        self.ctrl = None  # transformation control widget
        self.locator = None  # locator rectangle widget
        self.locator1 = None  # locator 1st point
        self.locator2 = None  # locator 2nd point
        self.scale = (1, 1)
        self.show_histogram = False
        # usage of QGraphicsScene and QGraphicsView is taken from
        # https://stackoverflow.com/questions/50851587/undo-functionality-for-qpainter-drawellipse-function
        self.gv = None
        self.scene = None
        self.scaledPixmap = None
        self.histogram = []
        self.initUI()

    def initUI(self):
        self.setWindowTitle("PyQT Tuts!")
        transforms.editWindow = self

        bar = self.menuBar()
        makeMenu(bar, FILE_MENU, self)
        menu = bar.actions()[2].menu()
        menu.addSeparator()
        addAction(menu, self, 'Show &Histogram', self.toggleHistogram,
                  'Ctrl+H', 'Show/hide histogram')

        menu = bar.actions()[1].menu()
        menu.addSeparator()
        for item in transforms.getTransforms():
            addAction(menu, self, item[0], item[2], item[3],
                      item[4])  # item[1] (Icon is ignored, todo: add support)

        menu = bar.actions()[0].menu()
        menu.addSeparator()
        addAction(menu, self, '&Next', self.onNextBtn, 'Ctrl+N', 'Next image')
        addAction(menu, self, '&Prev', self.onPrevBtn, 'Ctrl+P', 'Prev image')
        addAction(menu, self, '&Save', self.onSaveImg, 'Ctrl+S', 'Save image')

        layout1 = QVBoxLayout()

        self.gv = QGraphicsView()
        self.scene = QGraphicsScene()
        self.gv.setScene(self.scene)
        self.gv.installEventFilter(self)
        layout1.addWidget(self.gv)

        panel = QWidget(self)
        self.controlPanel = QHBoxLayout()
        panel.setLayout(self.controlPanel)
        layout1.addWidget(panel)

        center = QWidget()
        center.setLayout(layout1)
        self.setCentralWidget(center)

    def toggleHistogram(self):
        self.show_histogram = not self.show_histogram
        self.make_histogram()

    def eventFilter(self, obj, event):
        if obj == self.gv and event.type() == QEvent.MouseButtonPress:
            p = self.gv.mapToScene(event.pos())
            self.setLocation(p)
        return QWidget.eventFilter(self, obj, event)

    def setLocation(self, pos):
        if self.locator2 is not None:
            self.locator1 = None
            self.locator2 = None
        if self.locator1:
            self.locator2 = (pos.x(), pos.y())
            self.drawLocator()
        else:
            self.locator1 = (pos.x(), pos.y())

    def drawLocator(self):
        if self.locator:
            self.scene.removeItem(self.locator)
            self.locator = None
        pen = QPen(Qt.red, 3)
        self.locator = self.scene.addRect(self.locator1[0], self.locator1[1],
                                          self.locator2[0] - self.locator1[0],
                                          self.locator2[1] - self.locator1[1],
                                          pen)
        print('locator', self.locator1, self.locator2)
        self.gv.update()  # self.label.update() #QApplication.processEvents()

    def resizeEvent(self, event):
        QWidget.resizeEvent(self, event)
        self.sizeImage()

    def openImage(self, fileName):
        self.setWindowTitle(fileName)
        self.dirName = os.path.dirname(fileName)
        self.fileName = os.path.basename(fileName)
        self.dirFileNames = list(imgFiles(self.dirName))
        self.fileIdx = self.dirFileNames.index(self.fileName)
        if fileName:
            self.pilorig = PIL.Image.open(fileName)
            self.sizeImage()

    def fullFileName(self):
        if self.fileName:
            return os.path.join(self.dirName, self.fileName)
        else:
            return None

    def showImage(self, fileName):
        self.openImage(fileName)
        self.show()

    def updateImage(self, pilImage):
        self.pilorig = pilImage
        self.sizeImage()

    def sizeImage(self):
        orig = pil2pixmap(self.pilorig)
        if self.pilorig:
            if self.scaledPixmap:
                self.scene.removeItem(self.scaledPixmap)
                self.scaledPixmap = None
            if self.locator:
                self.scene.removeItem(self.locator)
                self.locator = None

            pixmap = orig.scaled(self.gv.width(),
                                 self.gv.height(),
                                 Qt.KeepAspectRatio,
                                 transformMode=Qt.SmoothTransformation)
            self.scaledPixmap = self.scene.addPixmap(pixmap)

            self.scale = (orig.size().width() / pixmap.size().width(),
                          orig.size().height() / pixmap.size().height())
            self.make_histogram()

    def absLocatorRect(self):
        return [
            self.locator1[0] * self.scale[0], self.locator1[1] * self.scale[1],
            self.locator2[0] * self.scale[0], self.locator2[1] * self.scale[1]
        ]

    def nextFileName(self):
        if self.fileIdx < len(self.dirFileNames) - 1:
            return os.path.join(self.dirName,
                                self.dirFileNames[self.fileIdx + 1])
        else:
            return None

    def prevFileName(self):
        if self.fileIdx > 0:
            return os.path.join(self.dirName,
                                self.dirFileNames[self.fileIdx - 1])
        else:
            return None

    def onNextBtn(self):
        fn = self.nextFileName()
        if fn:
            self.openImage(os.path.join(self.dirName, fn))

    #@staticmethod
    def onPrevBtn(self):
        fn = self.prevFileName()
        if fn:
            self.openImage(os.path.join(self.dirName, fn))

    def onSaveImg(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(
            self,
            "Save as ...",
            os.path.join(self.dirName, self.fileName),
            "All Files (*);;Jpeg Files(*.jpg)",
            options=options)
        if fileName:
            print(fileName)
            self.pilorig.save(fileName)

    def make_histogram(self):  # should it be a ShowWin class method?
        #self.canvas.delete('histogram')
        for it in self.histogram:
            self.scene.removeItem(it)
        del self.histogram[:]
        if not self.show_histogram:
            return

        img = self.pilorig
        if not img:
            return
        h = img.convert("L").histogram()
        maxVal = 1
        for i in range(0, len(h)):
            if h[i] > maxVal:
                maxVal = h[i]
        _X = float(img.size[1])
        x = 100 if _X > 100 else _X

        penGray = QPen(Qt.gray, 3)
        penRed = QPen(Qt.red, 3)

        for i in range(0, len(h)):
            if h[i] == maxVal:
                pen = penRed
            else:
                pen = penGray
            self.histogram.append(
                self.scene.addLine(i, x, i, x - x * h[i] / maxVal, pen))

        self.histogram.append(self.scene.addRect(0, 0, len(h), x, penGray))
        self.gv.update()

    # support transformation plugins
    def controlImg(self, checkCtrl=True):
        if checkCtrl and not self.ctrl:
            return None
        else:
            return self.savedImg

    def setCtrl(self, ctrl):
        if ctrl and self.ctrl:
            return  # do not allow two control panels
        if self.ctrl and not ctrl:
            self.ctrl.setParent(None)
        self.ctrl = ctrl
        if ctrl:
            self.controlPanel.addWidget(ctrl)
            self.savedImg = self.pilorig

    def unsetCtrl(self):
        if self.ctrl:
            self.ctrl.setParent(None)
            self.ctrl = None
Пример #13
0
class WindowTime(QMainWindow):
    '''This class handles the main window.'''
    def __init__(self):
        super().__init__()

        self.menubar = self.menuBar()

        self.status = self.statusBar()

        exitAction = QAction('Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)

        fileMenu = self.menubar.addMenu('&File')
        fileMenu.addAction(exitAction)

        self.zoomlevel = 2
        # self.pixmaps = {2: QPixmap('yeg-2.png'), 3: QPixmap('yeg-3.png'),
        # 				4: QPixmap('yeg-4.png'), 5: QPixmap('yeg-5.png'), 6: QPixmap('yeg-6.png')}
        #
        # self.sizes = {1: 512, 2: 1024, 3: 2048, 4: 4096, 5: 8192, 6: 16384}
        self.pixmaps = {
            2: QPixmap(os.path.join(__location__, 'yeg-2.png')),
            3: QPixmap(os.path.join(__location__, 'yeg-3.png')),
            4: QPixmap(os.path.join(__location__, 'yeg-4.png')),
            5: QPixmap(os.path.join(__location__, 'yeg-5.png'))
        }

        self.sizes = {1: 512, 2: 1024, 3: 2048, 4: 4096, 5: 8192}
        self.pressed = False
        self.start = 0
        self.dest = 0
        self.center = (0, 0)
        self.howmanycars = 0
        self.customer_id = 0
        self.initUI()

        self.show()

    def initUI(self):
        #The QToolTip class provides tool tips (balloon help) for any widget.
        QToolTip.setFont(QFont('SansSerif', 10))

        w = QWidget()
        #The QGridLayout class lays out widgets in a grid.
        grid = QGridLayout()
        #setLayout(self, Qlayout) Sets the layout manager for this widget to layout.
        #The QLayout argument has it's ownership transferred to Qt.
        w.setLayout(grid)
        #The QLabel widget provides a text or image display.
        labelZoom = QLabel('Zoom here pls')
        labelPassengers = QLabel('How many Passengers')

        #The QPushButton widget provides a command button. Takes in arguments
        #For text label
        btnZoomIn = QPushButton('+')
        btnZoomIn.setToolTip('Zoom In')
        btnZoomIn.clicked.connect(self.zoomIn)
        btnZoomOut = QPushButton('-')
        btnZoomOut.setToolTip('Zoom Out')
        btnZoomOut.clicked.connect(self.zoomOut)

        spinBox = QSpinBox()
        spinBox.setMaximum(5)
        spinBox.setMinimum(1)

        self.mapScene = GraphicsScene()
        self.mapScene.setSceneRect(0, 0, self.sizes[self.zoomlevel],
                                   self.sizes[self.zoomlevel])
        self.mapScene.addPixmap(self.pixmaps[self.zoomlevel])
        #ellipse = mapScene.addEllipse(50,100,50,50)
        self.mapView = QGraphicsView()
        self.mapView.setScene(self.mapScene)
        #Set it so user can drag map via cursor
        self.mapView.setDragMode(QGraphicsView.ScrollHandDrag)
        #Hide the scroll bar
        self.mapView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.mapView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        grid.addWidget(labelZoom, 0, 4)
        grid.addWidget(self.mapView, 0, 0, 4, 4)
        grid.addWidget(btnZoomIn, 1, 4)
        grid.addWidget(btnZoomOut, 2, 4)
        grid.addWidget(labelPassengers, 3, 4)
        grid.addWidget(spinBox, 4, 4)

        #How everything will look on the screen
        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('Uber Pool')
        self.setCentralWidget(w)

        #CHANGED: This
    def setCenter(self):
        center = self.mapView.mapToScene(self.mapView.width() // 2,
                                         self.mapView.height() // 2)
        self.center = (ConversionFunctions.x_to_longitude(
            self.zoomlevel, center.x()),
                       ConversionFunctions.y_to_latitude(
                           self.zoomlevel, center.y()))

    def zoomIn(self):
        if self.zoomlevel < 5:
            self.pressed = False
            self.setCenter()
            self.zoomlevel += 1
            self.updateSceneZoom()

    def zoomOut(self):
        if self.zoomlevel > 2:
            self.pressed = False
            self.setCenter()
            self.zoomlevel -= 1
            self.updateSceneZoom()

    #updates the scence once the zoom button has been pressed. The scene is
    #updated on the center of the last scene
    def updateSceneZoom(self):
        self.mapScene.clear()
        self.mapScene.addPixmap(self.pixmaps[self.zoomlevel])
        self.mapScene.setSceneRect(0, 0, self.sizes[self.zoomlevel],
                                   self.sizes[self.zoomlevel])
        (x, y) = (ConversionFunctions.longitude_to_x(self.zoomlevel,
                                                     self.center[0]),
                  ConversionFunctions.latitude_to_y(self.zoomlevel,
                                                    self.center[1]))
        self.mapView.centerOn(x, y)

    #returns the x,y position of the cursor on the map
    def handleClick(self, pos):
        return (pos.x(), pos.y())
        # #Grab the x,y coords
        # (x, y) = (pos.x(), pos.y())
        # #Convert them into lat,lon
        # lon = x_to_longitude(self.zoomlevel, x)
        # lat = y_to_latitude(self.zoomlevel, y)
        #
        # #Determine whether start location has already been decided
        # if self.pressed == False:
        # 	self.start = Vertex(lat, lon)
        # 	self.pressed = True
        # 	self.drawBubble(self.start)
        # else:
        # 	#Once dest has been decided, find shortest path and draw it
        # 	self.dest = Vertex(lat, lon)
        # 	self.pressed = False
        # 	self.drawBubble(self.dest)
        # 	self.controller.passRequest(self.start, self.dest, 1)

    def drawCar(self):
        #Draws the map in place
        self.setCenter()
        self.mapScene.clear()
        self.mapScene.addPixmap(self.pixmaps[self.zoomlevel])
        self.mapScene.setSceneRect(0, 0, self.sizes[self.zoomlevel],
                                   self.sizes[self.zoomlevel])
        (lat, lon) = self.center
        x = ConversionFunctions.longitude_to_x(self.zoomlevel, lon)
        y = ConversionFunctions.latitude_to_y(self.zoomlevel, lat)
        self.mapView.centerOn(x, y)
        #advance_taxi
        UberTaxi.advance_taxi(taxi_directory, cust_directory, g)
        for taxi in taxi_directory.values():
            #gets coords from vertex
            lon = server.coordinates[taxi.loc][1]
            lat = server.coordinates[taxi.loc][0]
            #stored in lat, lon, and then converted
            newx = ConversionFunctions.longitude_to_x(self.zoomlevel, lon)
            newy = ConversionFunctions.latitude_to_y(self.zoomlevel, lat)
            #draws path and car
            self.mapScene.addRect(newx, newy, 15, 10)
            self.mapScene.addEllipse(newx - 2, newy + 10, 6, 6)
            self.mapScene.addEllipse(newx + 11, newy + 10, 6, 6)
            self.drawPath(taxi.path)

    def drawPath(self, path):
        linePen = QPen()
        linePen.setWidth(3)  #Set the width of the line to be noticeable
        for i in range(len(path) - 1):
            lon1 = server.coordinates[path[i]][1]
            lat1 = server.coordinates[path[i]][0]
            lon2 = server.coordinates[path[i + 1]][1]
            lat2 = server.coordinates[path[i + 1]][0]

            self.mapScene.addLine(
                ConversionFunctions.longitude_to_x(self.zoomlevel, lon1),
                ConversionFunctions.latitude_to_y(self.zoomlevel, lat1),
                ConversionFunctions.longitude_to_x(self.zoomlevel, lon2),
                ConversionFunctions.latitude_to_y(self.zoomlevel, lat2),
                linePen)
Пример #14
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.lastyear = int(time.strftime('%Y', time.localtime(time.time()))) - 1
        self.in_parameters = {u'datetime': str(self.lastyear) + u'年',
                              u'target_area': u'绍兴市',
                              u'density_cell': u'10',
                              u'density_class': 10,
                              u'day_cell': u'15',
                              u'day_class': 10,
                              u'out_type': u'tiff'}
        self.setupUi()

    def setupUi(self):
        self.setObjectName("MainWindow")
        self.setFixedSize(1040, 915)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        icon = QIcon()
        icon.addPixmap(QPixmap('./resource/weather-thunder.png'),QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.centralwidget = QWidget(self)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setObjectName("centralwidget")
        self.layoutWidget = QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QRect(32, 10, 979, 851))
        self.layoutWidget.setObjectName("layoutWidget")
        self.verticalLayout_5 =QVBoxLayout(self.layoutWidget)
        self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.datetime_label = QLabel(self.layoutWidget)
        self.datetime_label.setObjectName("datetime_label")
        self.horizontalLayout.addWidget(self.datetime_label)
        self.datetime = QDateEdit(self.layoutWidget)
        self.datetime.setDateTime(QDateTime(QDate(self.lastyear, 1, 1), QTime(0, 0, 0)))
        self.datetime.setObjectName("datetime")
        self.horizontalLayout.addWidget(self.datetime)
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.target_area_label = QLabel(self.layoutWidget)
        self.target_area_label.setObjectName("target_area_label")
        self.horizontalLayout.addWidget(self.target_area_label)
        self.target_area = QComboBox(self.layoutWidget)
        self.target_area.setObjectName("target_area")
        self.target_area.addItem("")
        self.target_area.addItem("")
        self.target_area.addItem("")
        self.target_area.addItem("")
        self.target_area.addItem("")
        self.target_area.addItem("")
        self.horizontalLayout.addWidget(self.target_area)
        spacerItem2 = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.verticalLayout_5.addLayout(self.horizontalLayout)
        self.tabWidget = QTabWidget(self.layoutWidget)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
        self.tabWidget.setSizePolicy(sizePolicy)
        self.tabWidget.setObjectName("tabWidget")
        self.density_tab = QWidget()
        self.density_tab.setObjectName("density_tab")
        self.verticalLayout_3 =QVBoxLayout(self.density_tab)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.verticalLayout_2 =QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.density_cell_label = QLabel(self.density_tab)
        self.density_cell_label.setObjectName("density_cell_label")
        self.horizontalLayout_2.addWidget(self.density_cell_label)
        self.density_cell = QSpinBox(self.density_tab)
        self.density_cell.setProperty("value", 10)
        self.density_cell.setObjectName("density_cell")
        self.horizontalLayout_2.addWidget(self.density_cell)
        spacerItem3 = QSpacerItem(40, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem3)
        self.density_class_label = QLabel(self.density_tab)
        self.density_class_label.setObjectName("density_class_label")
        self.horizontalLayout_2.addWidget(self.density_class_label)
        self.density_class = QSpinBox(self.density_tab)
        self.density_class.setProperty("value", 10)
        self.density_class.setObjectName("density_class")
        self.horizontalLayout_2.addWidget(self.density_class)
        spacerItem4 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem4)
        self.density_mxd = QPushButton(self.density_tab)
        self.density_mxd.setObjectName("density_mxd")
        self.horizontalLayout_2.addWidget(self.density_mxd)
        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
        self.density_view = QGraphicsView(self.density_tab)
        self.density_view.setObjectName("density_view")
        self.verticalLayout_2.addWidget(self.density_view)
        self.verticalLayout_3.addLayout(self.verticalLayout_2)
        self.tabWidget.addTab(self.density_tab, "")
        self.day_tab = QWidget()
        self.day_tab.setObjectName("day_tab")
        self.verticalLayout_4 =QVBoxLayout(self.day_tab)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.verticalLayout =QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_3 =QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.day_cell_label = QLabel(self.day_tab)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.day_cell_label.sizePolicy().hasHeightForWidth())
        self.day_cell_label.setSizePolicy(sizePolicy)
        self.day_cell_label.setObjectName("day_cell_label")
        self.horizontalLayout_3.addWidget(self.day_cell_label)
        self.day_cell = QSpinBox(self.day_tab)
        self.day_cell.setProperty("value", 15)
        self.day_cell.setObjectName("day_cell")
        self.horizontalLayout_3.addWidget(self.day_cell)
        spacerItem5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem5)
        self.day_class_label = QLabel(self.day_tab)
        self.day_class_label.setObjectName("day_class_label")
        self.horizontalLayout_3.addWidget(self.day_class_label)
        self.day_class = QSpinBox(self.day_tab)
        self.day_class.setProperty("value", 10)
        self.day_class.setObjectName("day_class")
        self.horizontalLayout_3.addWidget(self.day_class)
        spacerItem6 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem6)
        self.day_mxd = QPushButton(self.day_tab)
        self.day_mxd.setObjectName("day_mxd")
        self.horizontalLayout_3.addWidget(self.day_mxd)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.day_view = QGraphicsView(self.day_tab)
        self.day_view.setObjectName("day_view")
        self.verticalLayout.addWidget(self.day_view)
        self.verticalLayout_4.addLayout(self.verticalLayout)
        self.tabWidget.addTab(self.day_tab, "")
        self.verticalLayout_5.addWidget(self.tabWidget)
        self.horizontalLayout_4 =QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.progressBar = QProgressBar(self.layoutWidget)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth())
        self.progressBar.setSizePolicy(sizePolicy)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.horizontalLayout_4.addWidget(self.progressBar)
        self.execute_button = QPushButton(self.layoutWidget)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.execute_button.sizePolicy().hasHeightForWidth())
        self.execute_button.setSizePolicy(sizePolicy)
        self.execute_button.setObjectName("execute_button")
        self.horizontalLayout_4.addWidget(self.execute_button)
        self.verticalLayout_5.addLayout(self.horizontalLayout_4)
        self.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 1040, 26))
        self.menubar.setObjectName("menubar")
        self.file_menu = QMenu(self.menubar)
        self.file_menu.setObjectName("file_menu")
        self.help_menu = QMenu(self.menubar)
        self.help_menu.setObjectName("help_menu")
        self.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)
        self.action_add_data = QAction(self)
        self.action_add_data.setObjectName("action_add_data")
        self.action_help = QAction(self)
        self.action_help.setObjectName("action_help")
        self.action_about = QAction(self)
        self.action_about.setObjectName("action_about")
        self.action_save_pic = QAction(self)
        self.action_save_pic.setObjectName("action_save_pic")
        self.file_menu.addAction(self.action_add_data)
        self.file_menu.addAction(self.action_save_pic)
        self.help_menu.addAction(self.action_help)
        self.help_menu.addAction(self.action_about)
        self.menubar.addAction(self.file_menu.menuAction())
        self.menubar.addAction(self.help_menu.menuAction())

        self.retranslateUi()
        self.tabWidget.setCurrentIndex(0)
        QMetaObject.connectSlotsByName(self)
        self.center()
        self.show()

        self.target_area.activated[str].connect(self.updateTargetArea)
        self.datetime.dateChanged.connect(self.updateDatetime)
        self.density_cell.valueChanged.connect(self.updateDensityCell)
        self.density_class.valueChanged.connect(self.updateDensityClass)
        self.day_cell.valueChanged.connect(self.updateDayCell)
        self.day_class.valueChanged.connect(self.updateDayClass)

        self.action_add_data.triggered.connect(self.addData)
        self.action_save_pic.triggered.connect(self.savePic)
        self.action_about.triggered.connect(self.showAbout)
        self.action_help.triggered.connect(self.showHelp)
        self.execute_button.clicked.connect(self.execute)
        self.density_mxd.clicked.connect(self.openMxdDensity)
        self.day_mxd.clicked.connect(self.openMxdDay)


        self.density_mxd.setDisabled(True)
        self.day_mxd.setDisabled(True)
        self.action_save_pic.setDisabled(True)

    def execute(self):
        dir = u"E:/Documents/工作/雷电公报/闪电定位原始文本数据/" + self.in_parameters[u'datetime']

        if os.path.exists(dir):
            datafiles = os.listdir(dir)
            datafiles = map(lambda x:os.path.join(dir,x),datafiles)
            self.in_parameters[u'origin_data_path'] = datafiles

        if not self.in_parameters.has_key(u'origin_data_path'):
            message = u"请加载%s的数据" % self.in_parameters[u'datetime']
            msgBox = QMessageBox()
            msgBox.setText(message)
            msgBox.setIcon(QMessageBox.Information)
            icon = QIcon()
            icon.addPixmap(QPixmap('./resource/weather-thunder.png'), QIcon.Normal, QIcon.Off)
            msgBox.setWindowIcon(icon)
            msgBox.setWindowTitle(" ")
            msgBox.exec_()
            return

        self.execute_button.setDisabled(True)
        self.execute_button.setText(u'正在制图中……')
        self.progressBar.setMaximum(0)
        self.progressBar.setMinimum(0)

        self.action_add_data.setDisabled(True)
        self.target_area.setDisabled(True)
        self.datetime.setDisabled(True)
        self.density_cell.setDisabled(True)
        self.density_class.setDisabled(True)
        self.day_cell.setDisabled(True)
        self.day_class.setDisabled(True)

        # for outfile in self.in_parameters[u'origin_data_path']:
        #     infile =
        #     try:
        #         with open(infile, 'w+') as in_f:
        #             for line in in_f:
        #                 line = line.replace(u":",":")
        #                 in_f.write(line)
        #     except Exception,inst:
        #         print infile

        self.process_thread = WorkThread()
        self.process_thread.trigger.connect(self.finished)
        self.process_thread.beginRun(self.in_parameters)

    def finished(self):

        #绘制闪电密度图
        ##清除上一次的QGraphicsView对象,防止其记录上一次图片结果,影响显示效果
        self.density_view.setAttribute(Qt.WA_DeleteOnClose)
        self.verticalLayout_2.removeWidget(self.density_view)
        size = self.density_view.size()
        self.density_view.close()

        self.density_view = QGraphicsView(self.density_tab)
        self.density_view.setObjectName("density_view")
        self.density_view.resize(size)
        self.verticalLayout_2.addWidget(self.density_view)

        densityPic = ''.join([cwd,u'/bulletinTemp/',
            self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'],
            self.in_parameters[u'target_area'],u'闪电密度空间分布.tif'])

        scene = QGraphicsScene()
        pixmap_density = QPixmap(densityPic)
        scene.addPixmap(pixmap_density)
        self.density_view.setScene(scene)
        scale = float(self.density_view.width()) / pixmap_density.width()
        self.density_view.scale(scale, scale)

        #绘制雷暴日图
        self.day_view.setAttribute(Qt.WA_DeleteOnClose)
        self.verticalLayout.removeWidget(self.day_view)
        size = self.day_view.size()
        self.day_view.close()

        self.day_view = QGraphicsView(self.day_tab)
        self.day_view.setObjectName("day_view")
        self.day_view.resize(size)
        self.verticalLayout.addWidget(self.day_view)

        dayPic = ''.join([cwd,u'/bulletinTemp/',
            self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'],
            self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif'])

        pixmap_day = QPixmap(dayPic)
        scene = QGraphicsScene()
        scene.addPixmap(pixmap_day)
        self.day_view.resize(self.density_view.width(),self.density_view.height())
        self.day_view.setScene(scene)
        scale = float(self.day_view.width()) / pixmap_day.width()
        self.day_view.scale(scale, scale)

        #处理进度条和执行按钮状态
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(100)
        self.progressBar.setFormat(u'完成!')
        self.execute_button.setDisabled(False)
        self.execute_button.setText(u'执行')
        #改变一些控件的状态
        self.action_add_data.setDisabled(False)
        self.target_area.setDisabled(False)
        self.datetime.setDisabled(False)
        self.density_cell.setDisabled(False)
        self.density_class.setDisabled(False)
        self.day_cell.setDisabled(False)
        self.day_class.setDisabled(False)
        self.density_mxd.setDisabled(False)
        self.day_mxd.setDisabled(False)
        self.action_save_pic.setDisabled(False)

    def addData(self):
        fnames = QFileDialog.getOpenFileNames(self, u'请选择原始的电闪数据',
                                              u'E:/Documents/工作/雷电公报/闪电定位原始文本数据',
                                              'Text files (*.txt);;All(*.*)')

        self.in_parameters[u'origin_data_path'] = fnames[0]

    def savePic(self):
        densityPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/',
            self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'],
            self.in_parameters[u'target_area'],u'闪电密度空间分布.tif'])

        dayPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/',
            self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'],
            self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif'])

        directory = QFileDialog.getExistingDirectory(self,u'请选择图片保存位置',
                                                     u'E:/Documents/工作/雷电公报',
                                    QFileDialog.ShowDirsOnly|QFileDialog.DontResolveSymlinks)

        dest_density = os.path.join(directory,os.path.basename(densityPic))
        dest_day = os.path.join(directory,os.path.basename(dayPic))

        if os.path.isfile(dest_day) or os.path.isfile(dest_density):
            message = u"文件已经存在!"
            msgBox = QMessageBox()
            msgBox.setText(message)
            msgBox.setIcon(QMessageBox.Information)
            icon = QIcon()
            icon.addPixmap(QPixmap("./resource/weather-thunder.png"), QIcon.Normal, QIcon.Off)
            msgBox.setWindowIcon(icon)
            msgBox.setWindowTitle(" ")
            msgBox.exec_()
            return

        move(dayPic,directory)
        move(densityPic,directory)

    def openMxdDay(self):
        program  = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe'
        src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb'])
        dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']])
        src_file = ''.join([self.in_parameters[u'target_area'] , u"地闪雷暴日空间分布模板.mxd"])

        copy(os.path.join(src_dir,src_file),dest_dir)

        arguments = [os.path.join(dest_dir,src_file)]
        self.process = QProcess(self)
        self.process.start(program,arguments)

    def openMxdDensity(self):
        program  = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe'
        src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb'])
        dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']])
        src_file = ''.join([self.in_parameters[u'target_area'] ,u"闪电密度空间分布模板.mxd"])


        copy(os.path.join(src_dir,src_file),dest_dir)

        arguments = [os.path.join(dest_dir,src_file)]
        self.process = QProcess(self)
        self.process.start(program,arguments)

    def showAbout(self):
        self.about = About_Dialog()

    def showHelp(self):
        program  = u'C:/Windows/hh.exe'
        arguments = [''.join([cwd,'/help/help.CHM'])]
        self.process = QProcess(self)
        self.process.start(program,arguments)

    def updateTargetArea(self, area):
        self.in_parameters[u'target_area'] = area

    def updateDatetime(self, date):
        self.in_parameters[u'datetime'] = str(date.year()) + u'年'
        if self.in_parameters.has_key(u'origin_data_path'):
            self.in_parameters.__delitem__(u'origin_data_path')

    def updateDensityCell(self, cell):
        self.in_parameters[u'density_cell'] = str(cell)

    def updateDensityClass(self, nclass):
        self.in_parameters[u'density_class'] = nclass

    def updateDayCell(self, cell):
        self.in_parameters[u'day_cell'] = str(cell)


    def updateDayClass(self, nclass):
        self.in_parameters[u'day_class'] = nclass

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def retranslateUi(self):
        _translate = QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "绍兴防雷中心 雷电公报制图"))
        self.datetime_label.setText(_translate("MainWindow", "年份"))
        self.datetime.setDisplayFormat(_translate("MainWindow", "yyyy"))
        self.target_area_label.setText(_translate("MainWindow", "地区"))
        self.target_area.setItemText(0, _translate("MainWindow", "绍兴市"))
        self.target_area.setItemText(1, _translate("MainWindow", "柯桥区"))
        self.target_area.setItemText(2, _translate("MainWindow", "上虞区"))
        self.target_area.setItemText(3, _translate("MainWindow", "诸暨市"))
        self.target_area.setItemText(4, _translate("MainWindow", "嵊州市"))
        self.target_area.setItemText(5, _translate("MainWindow", "新昌县"))
        self.density_cell_label.setText(_translate("MainWindow", "插值网格大小"))
        self.density_class_label.setText(_translate("MainWindow", "制图分类数目"))
        self.density_mxd.setText(_translate("MainWindow", "ArcGIS文档"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.density_tab), _translate("MainWindow", "电闪密度"))
        self.day_cell_label.setText(_translate("MainWindow", "插值网格大小"))
        self.day_class_label.setText(_translate("MainWindow", "制图分类数目"))
        self.day_mxd.setText(_translate("MainWindow", "ArcGIS文档"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.day_tab), _translate("MainWindow", "雷暴日"))
        self.execute_button.setText(_translate("MainWindow", "执行"))
        self.file_menu.setTitle(_translate("MainWindow", "文件"))
        self.help_menu.setTitle(_translate("MainWindow", "帮助"))
        self.action_add_data.setText(_translate("MainWindow", "加载数据"))
        self.action_help.setText(_translate("MainWindow", "使用说明"))
        self.action_about.setText(_translate("MainWindow", "关于"))
        self.action_save_pic.setText(_translate("MainWindow", "图片另存为"))