Пример #1
0
class Wyrmy(QWidget):
    def __init__(self, outside):
        super(Wyrmy, self).__init__()

        # get/set basic information
        self.app_control = outside
        screen_res = self.app_control.desktop().screenGeometry()
        self.screen_width, self.screen_height = screen_res.width(
        ), screen_res.height()
        self.setWindowIcon(QIcon(':/resources/wyrmytheworm.png'))

        # get images to use
        self.worms = {}
        self.index = 0
        self.file_names = []
        self.images = {}
        self.load_images()

        # create first image, determine all dimensions
        self.label, self.panel_height, self.width, self.height = QLabel(
            self), 0, 0, 0
        self.alive, self.dead = QLabel(), QLabel()
        self.percent = QLabel()
        self.open, self.save, self.export = QPushButton(), QPushButton(
        ), QPushButton()
        self.curr_img_disp = QLabel()
        self.alive.setText('Alive: 0')
        self.dead.setText('Dead: 0')
        self.percent.setText('Percent: 0%')
        self.open.setText('Open')
        self.open.setToolTip('Load a data file')
        self.save.setText('Save')
        self.save.setToolTip('Save a data file')
        self.export.setText('Export')
        self.export.setToolTip('Export data as CSV')
        self.open.setMaximumWidth(100)
        self.save.setMaximumWidth(100)
        self.export.setMaximumWidth(100)
        self.open.clicked.connect(self.open_file)
        self.save.clicked.connect(self.save_file)
        self.export.clicked.connect(self.export_data)

        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.layout)

        self.panel_layout = QGridLayout(self.layout.widget())
        self.panel_layout.setContentsMargins(15, 0, 15, 0)

        self.orig = QtGui.QPixmap(self.file_names[self.index])
        scale_by = self.screen_height * 0.75 / self.orig.height()
        self.img = self.orig.scaled(self.orig.width() * scale_by,
                                    self.orig.height() * scale_by,
                                    QtCore.Qt.KeepAspectRatio)
        self.panel_height = self.screen_height * 0.1
        self.width, self.height = self.img.width(
        ), self.img.height() + self.panel_height

        # self.panel = QGroupBox()
        # self.layout.addWidget(self.panel)
        # self.panel.move(0, self.img.height())
        # self.panel.setFixedWidth(self.width)
        # self.panel.setFixedHeight(self.panel_height)

        self.layout.addLayout(self.panel_layout, 1, 0)

        self.panel_layout.addWidget(self.alive, 0, 0)
        self.panel_layout.addWidget(self.dead, 1, 0)
        self.panel_layout.addWidget(self.percent, 2, 0)
        self.panel_layout.addWidget(self.curr_img_disp, 1, 1)
        self.panel_layout.addWidget(self.open, 0, 2)
        self.panel_layout.addWidget(self.save, 1, 2)
        self.panel_layout.addWidget(self.export, 2, 2)

        startX = int((self.screen_width / 2) - (self.width / 2))
        startY = int(((self.screen_height - 100) / 2) - (self.height / 2))
        self.move(startX, startY)

        self.label.mousePressEvent = self.image_clicked
        self.dead_pic = QtGui.QPixmap(':/resources/red_target_scaled.png')
        self.alive_pic = QtGui.QPixmap(':/resources/green_target_scaled.png')

        self.layout.addWidget(self.label, 0, 0)

        self.markers = QBoxLayout(QBoxLayout.LeftToRight)
        self.layout.addChildLayout(self.markers)

        self.refresh()

        self.show()

    def load_images(self):
        file_names_import = QFileDialog.getOpenFileNames(
            self, "Open Image", "/",
            "Image Files (*.png *.jpg *.bmp *.tiff *.tif)")
        self.file_names = file_names_import[0]
        for name in self.file_names:
            self.worms[Wyrmy.pic_name(name)] = WormPic(
                filename=Wyrmy.pic_name(name))

    def refresh(self):
        # take care of index wraparounds
        if len(self.file_names) == 0:
            self.app_control.quit()
        if self.index > len(self.file_names) - 1:
            self.index = 0
        if self.index < 0:
            self.index = len(self.file_names) - 1

        curr_img_name = self.file_names[self.index]
        # self.panel.setTitle(Wyrmy.pic_name(self.file_names[self.index]))

        orig = QtGui.QPixmap(self.file_names[self.index])
        scale_by = self.screen_height * 0.75 / orig.height()
        self.img = orig.scaled(orig.width() * scale_by,
                               orig.height() * scale_by,
                               QtCore.Qt.KeepAspectRatio)

        self.label.setPixmap(self.img)
        self.setWindowTitle('Wyrmy - ' + curr_img_name)

        curr_pic = self.worms[Wyrmy.pic_name(self.file_names[self.index])]

        self.curr_img_disp.setText(Wyrmy.pic_name(curr_img_name))

        num_dead = len(curr_pic.dead)
        num_alive = len(curr_pic.alive)
        alive_text = 'Alive: ' + str(num_alive)
        self.alive.setText(alive_text)
        dead_text = 'Dead: ' + str(num_dead)
        self.dead.setText(dead_text)
        if num_dead + num_alive > 0:
            percent_text = '% Dead: ' + str(100 * num_dead /
                                            (num_dead + num_alive))
        else:
            percent_text = '% Dead: 0'
        self.percent.setText(percent_text)

        for ind in reversed(range(self.markers.count())):
            widget = self.markers.takeAt(ind).widget()
            if widget is not None:
                widget.deleteLater()

        for coords in curr_pic.dead:
            curr_dead = QLabel(self)
            curr_dead.setPixmap(self.dead_pic)
            self.markers.addWidget(curr_dead)
            curr_dead.move(coords.x * self.img.width() - 25,
                           coords.y * self.img.height() - 12.5)
            # print(coords.x, ', ', coords.y)
        for coords in curr_pic.alive:
            curr_alive = QLabel(self)
            curr_alive.setPixmap(self.alive_pic)
            self.markers.addWidget(curr_alive)
            curr_alive.move(coords.x * self.img.width() - 25,
                            coords.y * self.img.height() - 12.5)
            # print(coords.x, ', ', coords.y)

    def safe_index(self, index):
        if index < 0:
            new_ind = len(self.file_names) + index
        elif index > len(self.file_names) - 1:
            new_ind = index - len(self.file_names)
        else:
            new_ind = index
        if new_ind < 0:
            new_ind = 0
        elif new_ind > len(self.file_names) - 1:
            new_ind = len(self.file_names) - 1
        return new_ind

    @staticmethod
    def pic_name(file_name):
        last_index = file_name.rfind('/')
        return file_name[last_index + 1:last_index + 4]

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_W:
            self.index -= 1
        if event.key() == QtCore.Qt.Key_S:
            self.index += 1
        if event.key() == QtCore.Qt.Key_A:
            start = QWidget.mapToGlobal(self.label, self.label.pos())
            click_x = (QtGui.QCursor.pos().x() - start.x()) / self.img.width()
            click_y = (QtGui.QCursor.pos().y() - start.y()) / self.img.height()
            click = Pair(click_x, click_y)
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].alive.append(click)
        if event.key() == QtCore.Qt.Key_D:
            start = QWidget.mapToGlobal(self.label, self.label.pos())
            click_x = (QtGui.QCursor.pos().x() - start.x()) / self.img.width()
            click_y = (QtGui.QCursor.pos().y() - start.y()) / self.img.height()
            click = Pair(click_x, click_y)
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].dead.append(click)
        if event.key() == QtCore.Qt.Key_X:
            curr_pic = self.worms[Wyrmy.pic_name(self.file_names[self.index])]
            curr_pic.alive = []
            curr_pic.dead = []
        self.refresh()
        event.accept()

    def image_clicked(self, event):
        click = Pair(event.x() / self.img.width(),
                     event.y() / self.img.height())
        if event.button() == QtCore.Qt.LeftButton:
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].alive.append(click)
        if event.button() == QtCore.Qt.RightButton:
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].dead.append(click)
        # if event.button() == QtCore.Qt.MidButton:
        #     curr_pic = self.worms[Wyrmy.pic_name(self.file_names[self.index])]
        #     max_diff_x = 25/self.img.width()
        #     max_diff_y = 25/self.img.height()
        #     for ind, coords in enumerate(curr_pic.alive):
        #         if abs(coords.x-click.x) < max_diff_x and abs(coords.y-click.y) < max_diff_y:
        #             del curr_pic.alive[ind]
        #             break
        #     for ind, coords in enumerate(curr_pic.dead):
        #         if abs(coords.x-click.x) < max_diff_x and abs(coords.y-click.y) < max_diff_y:
        #             del curr_pic.dead[ind]
        #             break
        self.refresh()
        event.accept()

    @pyqtSlot()
    def open_file(self):
        input_from = QFileDialog.getOpenFileName(self,
                                                 caption='Open File',
                                                 filter='Wyrmy Data (*.wyrm)')
        if len(input_from[0]) > 0:
            with open(input_from[0], 'rb') as reading:
                self.worms = pickle.load(reading)
                reading.close()
        self.refresh()

    @pyqtSlot()
    def save_file(self):
        output_at = QFileDialog.getSaveFileName(self,
                                                caption='Save File',
                                                filter='Wyrmy Data (*.wyrm)')
        if len(output_at[0]) > 0:
            with open(output_at[0], 'wb') as out:
                pickle.dump(self.worms, out)
                out.close()

    @pyqtSlot()
    def export_data(self):
        output_at = QFileDialog.getSaveFileName(
            self, caption='Save File', filter='CSV (Comma delimited) (*.csv)')
        if len(output_at[0]) > 0:
            out = open(output_at[0], 'a')
            out.write('Name,Alive,Dead\n')
            for name in self.file_names:
                curr = self.worms[Wyrmy.pic_name(name)]
                this_pic = str(curr.filename) + ',' + str(len(
                    curr.alive)) + ',' + str(len(curr.dead)) + '\n'
                out.write(this_pic)
            out.close()
Пример #2
0
class MainWindow(QMainWindow):
    shortcuts = {
        "QUIT": "Ctrl+W",
        "ADD": "Ctrl+N",
        "EDIT": "Ctrl+I",
        "OPEN": "Ctrl+O",
        "OPEN-LEGACY": "Ctrl+Shift+O",
        "CREATE": "Ctrl+Shift+N",
        "SETTINGS": "Ctrl+Alt+S",
        "MANAGE-SCHEDULES": ""
    }

    icons = {
        "QUIT": ":/small/quit",
        "ADD": ":/medium/add",
        "EDIT": ":/medium/edit",
        "OPEN": ":/small/open",
        "OPEN-LEGACY": ":/small/open",
        "CREATE": ":/small/create",
        "SETTINGS": ":/small/settings",
        "MANAGE-SCHEDULES": ":/small/manage",
        "REMOVE": ":/medium/remove",
        "WINDOW": ":/small/window"
    }

    def __init__(self):
        super().__init__(flags=Qt.Window)

        # setup actions
        self.status_bar = self.statusBar()
        self.tool_bar = self.addToolBar("Video")
        # TODO: icon sizes
        self.tool_bar.setIconSize(QSize(36, 36))
        # add the following 3 lines back in if you want the buttons to be right aligned
        # spacer = QWidget()
        # spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        # self.tool_bar.addWidget(spacer)
        self.action_quit = QAction("Quit")
        self.action_quit.setShortcut(self.shortcuts["QUIT"])
        self.action_quit.setIcon(QIcon(QPixmap(self.icons["QUIT"])))
        self.action_quit.triggered.connect(self.close)

        self.action_add = QAction("Add Video")
        self.action_add.setShortcut(self.shortcuts["ADD"])
        self.action_add.setIcon(QIcon(QPixmap(self.icons["ADD"])))
        self.action_add.triggered.connect(self.add_video)

        self.action_edit = QAction("Edit Video Options")
        self.action_edit.setShortcut(self.shortcuts["EDIT"])
        self.action_edit.setIcon(QIcon(QPixmap(self.icons["EDIT"])))
        self.action_edit.triggered.connect(lambda: print("Action Edit Video"))

        self.action_open = QAction("Open")
        self.action_open.setShortcut(self.shortcuts["OPEN"])
        self.action_open.setIcon(QIcon(QPixmap(self.icons["OPEN"])))
        self.action_open.triggered.connect(lambda: print("Action Open"))

        self.action_open_legacy = QAction("Open Legacy File(.vst)")
        self.action_open_legacy.setShortcut(self.shortcuts["OPEN-LEGACY"])
        self.action_open_legacy.setIcon(QIcon(QPixmap(self.icons["OPEN-LEGACY"])))
        self.action_open_legacy.triggered.connect(lambda: print("Action Open Legacy"))

        self.action_create = QAction("Create Schedule")
        self.action_create.setShortcut(self.shortcuts["CREATE"])
        self.action_create.setIcon(QIcon(QPixmap(self.icons["CREATE"])))
        self.action_create.triggered.connect(self.create_schedule)

        self.action_settings = QAction("Settings")
        self.action_settings.setShortcut(self.shortcuts["SETTINGS"])
        self.action_settings.setIcon(QIcon(QPixmap(self.icons["SETTINGS"])))
        self.action_settings.triggered.connect(lambda: print("Action Settings"))

        self.action_remove = QAction("Remove Video")
        # self.action_remove.setShortcut(self.shortcuts["REMOVE"])
        self.action_remove.setIcon(QIcon(QPixmap(self.icons["REMOVE"])))
        self.action_remove.triggered.connect(self.table_right_clicked)
        # build views
        self.central_widget = QWidget(self, Qt.Widget)
        self.main_layout = QGridLayout()
        self.central_widget.setLayout(self.main_layout)

        self.schedule_layout = QHBoxLayout()
        picker_text = QLabel()
        picker_text.setText("Select Schedule:")
        self.schedule_picker = QComboBox()
        self.schedule_picker.currentIndexChanged.connect(lambda x: print("Picker!"))
        self.schedule_picker.addItems(["Item 1", "Item 2", "Item 3"])
        self.schedule_layout.addWidget(self.schedule_picker)
        self.main_layout.addWidget(picker_text, 0, 0)
        self.main_layout.addChildLayout(self.schedule_layout)
        self.main_layout.addWidget(self.schedule_picker, 0, 1)
        self.video_table_view = QTableView(self)
        self.video_table_view.hideColumn(0)
        self.video_table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.main_layout.addWidget(self.video_table_view, 1, 0, 1, 4)
        self.video_table_view.customContextMenuRequested.connect(lambda: "right click")

        self.inspect_video_window = QDockWidget()
        lbl = QLabel()
        lbl.setText("I am a dock window label!")
        self.inspect_video_window.setWidget(lbl)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.inspect_video_window)
        self.setCentralWidget(self.central_widget)

        self.init_ui()

    def add_video(self):
        # when add video event is clicked
        # does nothing - child will override this method
        pass

    def create_schedule(self):
        # when create schedule event is clicked
        # does nothing - child will override this method
        pass

    def table_right_clicked(self, position):
        print("Right clicked")
        menu = QMenu()
        menu.addAction(self.action_remove)
        menu.exec_(self.ui.table_videos.viewport().mapToGlobal(position))
        pass

    @staticmethod
    def default_event():
        # this is what all the onClicks, menu buttons, etc. get connected to by default
        # it does nothing - is just a placeholder
        pass

    def init_ui(self):
        self.setWindowTitle("Video Scheduler")
        self.setWindowIcon(QIcon(QPixmap(self.icons["WINDOW"])))

        #with open("../darkstyle.qss") as f:
        #    self.setStyleSheet(f.read())
        self.resize(800, 600)
        self.setup_menu_bar()
        self.setup_toolbar()
        self.post_status_message()

    def setup_menu_bar(self):
        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("File")
        file_menu.addAction(self.action_create)
        file_menu.addAction(self.action_open)
        file_menu.addAction(self.action_open_legacy)

        file_menu.addSeparator()
        file_menu.addAction(self.action_settings)
        file_menu.addSeparator()
        file_menu.addAction(self.action_quit)

        edit_menu = menu_bar.addMenu("Edit")
        edit_menu.addAction(self.action_add)
        edit_menu.addAction(self.action_edit)

    def setup_toolbar(self):
        self.tool_bar.show()
        self.tool_bar.addAction(self.action_add)
        self.tool_bar.addAction(self.action_edit)
        self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

    def post_status_message(self):
        # status_bar_layout = self.status_bar.layout()
        now_playing = QLabel()
        now_playing.setText("Now playing: video1.mp4")
        time_left = QLabel()
        time_left.setText("Time left: 5:05")
        line = QFrame(self, Qt.Widget)
        # line.setObjectName(QString.fromUtf8("line"))
        # line.setGeometry(QRect(320, 150, 118, 3))
        # line.setSiz
        line.setFrameShape(QFrame.VLine)
        line.setFrameShadow(QFrame.Sunken)
        # status_bar_layout.addWidget(now_playing)
        self.status_bar.addWidget(now_playing)
        self.status_bar.addWidget(line)
        self.status_bar.addWidget(time_left)

    @staticmethod
    def table_double_clicked(index):
        print(index.column())
        if index.column() == 0:
            # we want to open a file dialog to choose new video
            filename, status = QFileDialog.getOpenFileName(caption="Choose Video File")
            print(filename)
        else:
            return