Пример #1
0
class MainWindow(QMainWindow):
    """
    主窗口类
    """
    def __init__(self):
        super().__init__()
        #print('init')
        self.item_cnt = 0
        # self.canvas_cnt = 1

        # 使用QListWidget来记录已有的图元,并用于选择图元。注:这是图元选择的简单实现方法,更好的实现是在画布中直接用鼠标选择图元
        self.list_widget = QListWidget(self)
        self.list_widget.setMinimumWidth(200)

        # 使用QGraphicsView作为画布
        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, 600, 600)
        self.canvas_widget = MyCanvas(self.scene, self)
        self.canvas_widget.setFixedSize(610, 610)
        self.canvas_widget.main_window = self
        self.canvas_widget.list_widget = self.list_widget

        # 设置菜单栏
        menubar = self.menuBar()
        file_menu = menubar.addMenu('文件')
        set_pen_act = file_menu.addAction('设置画笔')
        reset_canvas_act = file_menu.addAction('重置画布')
        save_canvas_act = file_menu.addAction('保存画布')
        exit_act = file_menu.addAction('退出')
        draw_menu = menubar.addMenu('绘制')
        line_menu = draw_menu.addMenu('线段')
        line_naive_act = line_menu.addAction('Naive')
        line_dda_act = line_menu.addAction('DDA')
        line_bresenham_act = line_menu.addAction('Bresenham')
        polygon_menu = draw_menu.addMenu('多边形')
        polygon_dda_act = polygon_menu.addAction('DDA')
        polygon_bresenham_act = polygon_menu.addAction('Bresenham')
        ellipse_act = draw_menu.addAction('椭圆')
        curve_menu = draw_menu.addMenu('曲线')
        curve_bezier_act = curve_menu.addAction('Bezier')
        curve_b_spline_act = curve_menu.addAction('B-spline')
        edit_menu = menubar.addMenu('编辑')
        translate_act = edit_menu.addAction('平移')
        rotate_act = edit_menu.addAction('旋转')
        scale_act = edit_menu.addAction('缩放')
        clip_menu = edit_menu.addMenu('裁剪')
        clip_cohen_sutherland_act = clip_menu.addAction('Cohen-Sutherland')
        clip_liang_barsky_act = clip_menu.addAction('Liang-Barsky')

        # 连接信号和槽函数
        exit_act.triggered.connect(qApp.quit)
        set_pen_act.triggered.connect(self.set_pen)
        reset_canvas_act.triggered.connect(self.reset_canvas)
        save_canvas_act.triggered.connect(self.save_canvas)
        line_naive_act.triggered.connect(self.line_naive_action)
        line_dda_act.triggered.connect(self.line_dda_action)
        line_bresenham_act.triggered.connect(self.line_bresenham_action)
        polygon_dda_act.triggered.connect(self.polygon_dda_action)
        polygon_bresenham_act.triggered.connect(self.polygon_bresenham_action)
        ellipse_act.triggered.connect(self.ellipse_action)
        curve_bezier_act.triggered.connect(self.curve_bezier_action)
        curve_b_spline_act.triggered.connect(self.curve_b_spline_action)
        translate_act.triggered.connect(self.translate_action)
        rotate_act.triggered.connect(self.rotate_action)
        scale_act.triggered.connect(self.scale_action)
        clip_cohen_sutherland_act.triggered.connect(self.clip_cohen_sutherland_action)
        clip_liang_barsky_act.triggered.connect(self.clip_liang_barsky_action)
        self.list_widget.currentTextChanged.connect(self.canvas_widget.selection_changed)

        # 设置主窗口的布局
        self.hbox_layout = QHBoxLayout()
        self.hbox_layout.addWidget(self.canvas_widget)
        self.hbox_layout.addWidget(self.list_widget, stretch=1)
        self.central_widget = QWidget()
        self.central_widget.setLayout(self.hbox_layout)
        self.setCentralWidget(self.central_widget)
        self.statusBar().showMessage('空闲')
        self.resize(600, 600)
        self.setWindowTitle('CG 171860004')

    def get_id(self):
        self.item_cnt += 1
        _id = str(self.item_cnt)
        return _id
 
    def set_pen(self):
        red, ok1 = QInputDialog.getInt(self, "设置画笔颜色", "RED:")
        green, ok2 = QInputDialog.getInt(self, "设置画笔颜色", "GREEN:")
        blue, ok3 = QInputDialog.getInt(self, "设置画笔颜色", "BLUE:")
        if ok1 and ok2 and ok3:
            self.canvas_widget.set_color(QColor(red, green, blue))

    def reset_canvas(self):
        width, ok1 = QInputDialog.getInt(self, "重置画布", "width:")
        height, ok2 = QInputDialog.getInt(self, "重置画布", "height:")
        if width < 100:
            width = 100
        if width > 1000:
            width = 1000
        if height < 100:
            height = 100
        if height > 1000:
            height = 1000
        if ok1 and ok2:
            if self.canvas_widget.status != '':
                self.canvas_widget.finish_draw()
            self.list_widget.disconnect()
            self.list_widget.clear()
            self.scene.clear()
            self.list_widget.currentTextChanged.connect(self.canvas_widget.selection_changed)
            self.item_cnt = 0
            self.scene.setSceneRect(0, 0, width, height)
            self.canvas_widget.setFixedSize(width + 10, height + 10)

    def save_canvas(self):
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()
        img = self.canvas_widget.grab()
        name, ok = QInputDialog.getText(self, "保存画布", "文件名:")
        if ok:
            file_name = "output/"+name+".bmp"
            # self.canvas_cnt = self.canvas_cnt + 1
            img.save(file_name)

    def line_naive_action(self):
        self.canvas_widget.start_draw_line('Naive', str(self.item_cnt))
        self.statusBar().showMessage('Naive算法绘制线段')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def line_dda_action(self):
        self.canvas_widget.start_draw_line('DDA', str(self.item_cnt))
        self.statusBar().showMessage('DDA算法绘制线段')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def line_bresenham_action(self):
        self.canvas_widget.start_draw_line('Bresenham', str(self.item_cnt))
        self.statusBar().showMessage('Bresenham算法绘制线段')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def polygon_dda_action(self):
        self.canvas_widget.start_draw_polygon('DDA', str(self.item_cnt))
        self.statusBar().showMessage('DDA算法绘制多边形')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def polygon_bresenham_action(self):
        self.canvas_widget.start_draw_polygon('Bresenham', str(self.item_cnt))
        self.statusBar().showMessage('Bresenham算法绘制多边形')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def ellipse_action(self):
        self.canvas_widget.start_draw_ellipse(str(self.item_cnt))
        self.statusBar().showMessage('中点圆生成算法绘制椭圆')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def curve_b_spline_action(self):
        self.canvas_widget.start_draw_curve('B_spline', str(self.item_cnt))
        self.statusBar().showMessage('B-spline算法绘制曲线')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def curve_bezier_action(self):
        self.canvas_widget.start_draw_curve('Bezier', str(self.item_cnt))
        self.statusBar().showMessage('Bezier算法绘制曲线')
        self.list_widget.clearSelection()
        self.canvas_widget.clear_selection()

    def translate_action(self):
        self.canvas_widget.start_translate()
        self.statusBar().showMessage('平移')

    def rotate_action(self):
        self.canvas_widget.start_rotate()
        self.statusBar().showMessage('旋转')

    def scale_action(self):
        self.canvas_widget.start_scale()
        self.statusBar().showMessage('缩放')

    def clip_cohen_sutherland_action(self):
        self.canvas_widget.start_clip('Cohen-Sutherland')
        self.statusBar().showMessage('Cohen-Sutherland算法裁剪')
    
    def clip_liang_barsky_action(self):
        self.canvas_widget.start_clip('Liang-Barsky')
        self.statusBar().showMessage('Liang-Barsky算法裁剪')
Пример #2
0
class AudioPedantik(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.title = "AudioPedantik"
        self.top = 100
        self.left = 100
        self.width = 700
        self.height = 500

        self.config = configparser.ConfigParser()
        self.config.read("config.ini")

        self.search_dir = ""
        self.dest_dir = ""

        self.audio_id3 = None
        self.results = []
        self.artwork_bytes = None

        self.init_ui()

    def init_ui(self):
        # Main widgets declaration
        search_dir_button = QPushButton("Select search directory")

        dest_dir_button = QPushButton("Select destination directory")

        self.search_dir_edit = QLineEdit()
        self.search_dir_edit.setText(self.config["Last"]["search_dir"])
        self.search_dir = self.config["Last"]["search_dir"]
        self.search_dir_edit.setReadOnly(True)

        self.dest_dir_edit = QLineEdit()
        self.dest_dir_edit.setText(self.config["Last"]["dest_dir"])
        self.dest_dir = self.config["Last"]["dest_dir"]
        self.dest_dir_edit.setReadOnly(True)

        self.listbox = QListWidget()
        self.listbox.setMaximumWidth(250)

        self.combobox = QComboBox()

        # ID3 group widgets declarations
        file_name_label = QLabel("File name: ")

        self.artwork_id3_label = QLabel()
        self.artwork_id3_label.setPixmap(QPixmap("default.jpg"))

        artist_id3_label = QLabel("Artist: ")
        title_id3_label = QLabel("Title: ")
        genre_id3_label = QLabel("Genre: ")
        album_id3_label = QLabel("Album: ")
        release_year_id3_label = QLabel("Release year: ")
        track_no_id3_label = QLabel("Track number: ")

        self.file_name_edit = QLineEdit()

        self.artist_id3_edit = QLineEdit()
        self.artist_id3_edit.setReadOnly(True)

        self.title_id3_edit = QLineEdit()
        self.title_id3_edit.setReadOnly(True)

        self.genre_id3_edit = QLineEdit()
        self.genre_id3_edit.setReadOnly(True)

        self.album_id3_edit = QLineEdit()
        self.album_id3_edit.setReadOnly(True)

        self.release_year_id3_edit = QLineEdit()
        self.release_year_id3_edit.setReadOnly(True)

        self.track_no_id3_edit = QLineEdit()
        self.track_no_id3_edit.setReadOnly(True)

        # iTunes group widgets declarations
        search_phrase_label = QLabel("Search phrase: ")

        self.checkbox = QCheckBox("Don't overwrite artwork")

        self.artwork_itunes_label = QLabel()
        self.artwork_itunes_label.setPixmap(QPixmap("default.jpg"))

        artist_itunes_label = QLabel("Artist: ")
        title_itunes_label = QLabel("Title: ")
        genre_itunes_label = QLabel("Genre: ")
        genre_itunes_label = QLabel("Genre: ")
        album_itunes_label = QLabel("Album: ")
        release_year_itunes_label = QLabel("Release year: ")
        track_no_itunes_label = QLabel("Track number: ")

        self.search_phrase_edit = QLineEdit()
        self.artist_itunes_edit = QLineEdit()
        self.title_itunes_edit = QLineEdit()
        self.genre_itunes_edit = QLineEdit()
        self.album_itunes_edit = QLineEdit()
        self.release_year_itunes_edit = QLineEdit()
        self.track_no_itunes_edit = QLineEdit()

        load_artwork_button = QPushButton("Load custom artwork")

        self.save_button = QPushButton("Save")
        self.save_button.setMaximumWidth(50)
        self.save_button.setDisabled(True)

        # Layout
        main_layout = QGridLayout()

        main_layout.addWidget(search_dir_button, 0, 0)
        main_layout.addWidget(dest_dir_button, 1, 0)
        main_layout.addWidget(self.search_dir_edit, 0, 1)
        main_layout.addWidget(self.dest_dir_edit, 1, 1)
        main_layout.addWidget(self.listbox, 2, 0, 3, 1)
        main_layout.addWidget(self.combobox, 2, 1)

        # Group box for mp3 data
        id3_data_group_box = QGroupBox("MP3 data: ")
        id3_data_group_layout = QGridLayout()

        id3_data_group_layout.addWidget(file_name_label, 0, 0)

        id3_data_group_layout.addWidget(self.artwork_id3_label, 1, 0, 5, 1)

        id3_data_group_layout.addWidget(artist_id3_label, 1, 2)
        id3_data_group_layout.addWidget(title_id3_label, 2, 2)
        id3_data_group_layout.addWidget(genre_id3_label, 3, 2)
        id3_data_group_layout.addWidget(album_id3_label, 4, 2)
        id3_data_group_layout.addWidget(release_year_id3_label, 5, 2)
        id3_data_group_layout.addWidget(track_no_id3_label, 6, 2)

        id3_data_group_layout.addWidget(self.file_name_edit, 0, 2, 1, 2)

        id3_data_group_layout.addWidget(self.artist_id3_edit, 1, 3)
        id3_data_group_layout.addWidget(self.title_id3_edit, 2, 3)
        id3_data_group_layout.addWidget(self.genre_id3_edit, 3, 3)
        id3_data_group_layout.addWidget(self.album_id3_edit, 4, 3)
        id3_data_group_layout.addWidget(self.release_year_id3_edit, 5, 3)
        id3_data_group_layout.addWidget(self.track_no_id3_edit, 6, 3)

        id3_data_group_box.setLayout(id3_data_group_layout)

        main_layout.addWidget(id3_data_group_box, 3, 1)

        # Group box for iTunes data
        itunes_data_group_box = QGroupBox("iTunes data: ")
        itunes_data_group_layout = QGridLayout()

        itunes_data_group_layout.addWidget(search_phrase_label, 0, 0)

        itunes_data_group_layout.addWidget(self.artwork_itunes_label, 1, 0, 5,
                                           1)
        itunes_data_group_layout.addWidget(self.checkbox, 6, 0)

        itunes_data_group_layout.addWidget(artist_itunes_label, 1, 2)
        itunes_data_group_layout.addWidget(title_itunes_label, 2, 2)
        itunes_data_group_layout.addWidget(genre_itunes_label, 3, 2)
        itunes_data_group_layout.addWidget(album_itunes_label, 4, 2)
        itunes_data_group_layout.addWidget(release_year_itunes_label, 5, 2)
        itunes_data_group_layout.addWidget(track_no_itunes_label, 6, 2)
        itunes_data_group_layout.addWidget(track_no_itunes_label, 6, 2)

        itunes_data_group_layout.addWidget(self.search_phrase_edit, 0, 2, 1, 2)

        itunes_data_group_layout.addWidget(self.artist_itunes_edit, 1, 3)
        itunes_data_group_layout.addWidget(self.title_itunes_edit, 2, 3)
        itunes_data_group_layout.addWidget(self.genre_itunes_edit, 3, 3)
        itunes_data_group_layout.addWidget(self.album_itunes_edit, 4, 3)
        itunes_data_group_layout.addWidget(self.release_year_itunes_edit, 5, 3)
        itunes_data_group_layout.addWidget(self.track_no_itunes_edit, 6, 3)

        itunes_data_group_layout.addWidget(load_artwork_button, 7, 0)
        itunes_data_group_layout.addWidget(self.save_button, 7, 3)

        itunes_data_group_box.setLayout(itunes_data_group_layout)

        main_layout.addWidget(itunes_data_group_box, 4, 1)

        self.setLayout(main_layout)

        # Bindings
        dest_dir_button.pressed.connect(self.choose_dest_dir)
        search_dir_button.pressed.connect(self.choose_search_dir)
        load_artwork_button.pressed.connect(self.load_custom_artwork)
        self.save_button.pressed.connect(self.save)
        self.search_phrase_edit.editingFinished.connect(self.search_itunes)
        self.combobox.currentIndexChanged.connect(self.combobox_selected)

        # Window settings
        self.setGeometry(self.top, self.left, self.width, self.height)
        self.setWindowTitle(self.title)
        self.show()

        self.refresh_listbox()
        self.save_button.setDisabled(False)

    def refresh_listbox(self):

        self.listbox.disconnect()
        self.listbox.clear()
        try:
            self.listbox.addItems([
                file for file in os.listdir(self.search_dir)
                if file.endswith(".mp3")
            ])
        except FileNotFoundError:
            # FIXME:
            pass

        self.listbox.currentItemChanged.connect(self.listbox_selected)

    def choose_search_dir(self):

        self.search_dir = QFileDialog.getExistingDirectory(
            self, "Select Search Directory")
        self.search_dir_edit.setText(self.search_dir)
        self.config["Last"]["search_dir"] = self.search_dir

        with open("config.ini", "w") as configfile:
            self.config.write(configfile)

        self.refresh_listbox()

    def choose_dest_dir(self):

        self.dest_dir = QFileDialog.getExistingDirectory(
            self, "Select destination directory")
        self.dest_dir_edit.setText(self.dest_dir)
        self.config["Last"]["dest_dir"] = self.dest_dir

        with open("config.ini", "w") as configfile:
            self.config.write(configfile)

        self.save_button.setDisabled(False)

    def listbox_selected(self):

        file_name = self.listbox.currentItem().text()

        self.search_phrase_edit.setText(file_name[:-4])
        self.file_name_edit.setText(file_name)

        self.get_id3_tags(file_name)
        self.search_itunes()

    def get_id3_tags(self, file_name):
        try:
            self.audio_id3 = ID3(self.search_dir + "/" + file_name,
                                 v2_version=3)
        except _util.ID3NoHeaderError:
            file = File(self.search_dir + "/" + file_name)
            file.add_tags()
            file.save()

            self.audio_id3 = ID3(self.search_dir + "/" + file_name,
                                 v2_version=3)

        for tag in self.audio_id3:
            if tag.startswith("APIC") and (PictureType.COVER_FRONT == 3):
                image = QImage()
                image.loadFromData(self.audio_id3[tag].data)
                self.artwork_id3_label.setPixmap(
                    QPixmap(image).scaled(150, 150))
                break

        else:
            #TODO: default image should be stored as raw data
            self.artwork_id3_label.setPixmap(QPixmap("default.jpg"))

        if "TPE1" in self.audio_id3:
            self.artist_id3_edit.setText(str(self.audio_id3["TPE1"]))
        else:
            self.artist_id3_edit.clear()

        if "TIT2" in self.audio_id3:
            self.title_id3_edit.setText(str(self.audio_id3["TIT2"]))
        else:
            self.title_id3_edit.clear()

        if "TCON" in self.audio_id3:
            self.genre_id3_edit.setText(str(self.audio_id3["TCON"]))
        else:
            self.genre_id3_edit.clear()

        if "TALB" in self.audio_id3:
            self.album_id3_edit.setText(str(self.audio_id3["TALB"]))
        else:
            self.album_id3_edit.clear()

        if "TYER" in self.audio_id3:
            self.release_year_id3_edit.setText(str(self.audio_id3["TYER"]))
        else:
            self.release_year_id3_edit.clear()

        if "TRCK" in self.audio_id3:
            self.track_no_id3_edit.setText(str(self.audio_id3["TRCK"]))
        else:
            self.track_no_id3_edit.clear()

    def search_itunes(self):

        params = {
            "term": self.search_phrase_edit.text(),
            "media": "music",
            "limit": 10
        }

        json_data = json.loads(
            urlopen("https://itunes.apple.com/search?" +
                    urlencode(params)).read().decode('utf8'))

        self.combobox.clear()
        self.combobox.disconnect()

        self.results = []

        for result in json_data["results"]:
            # Prepare icon
            image_data = urlopen(result["artworkUrl30"]).read()
            image = QPixmap()
            image.loadFromData(image_data)

            self.combobox.addItem(
                QIcon(image),
                result["artistName"] + " - " + result["trackName"])
            self.results.append(result)

        self.combobox.currentIndexChanged.connect(self.combobox_selected)

        if len(self.results) > 0:
            self.combobox.setCurrentIndex(0)
            self.combobox_selected()
        else:
            self.artwork_itunes_label.setPixmap(QPixmap("default.jpg"))
            self.artwork_bytes = None

            self.artist_itunes_edit.clear()
            self.title_itunes_edit.clear()
            self.genre_itunes_edit.clear()
            self.album_itunes_edit.clear()
            self.release_year_itunes_edit.clear()

    def combobox_selected(self):

        current_combobox_index = self.combobox.currentIndex()

        artwork_url = self.results[current_combobox_index][
            "artworkUrl30"].split("/")
        artwork_url[-1] = "600x600bb.jpg"
        artwork_url = "/".join(artwork_url)

        self.artwork_bytes = urlopen(artwork_url).read()
        artwork = QPixmap()
        artwork.loadFromData(self.artwork_bytes)

        self.artwork_itunes_label.setPixmap(artwork.scaled(150, 150))

        self.artist_itunes_edit.setText(
            self.results[current_combobox_index]["artistName"])
        self.title_itunes_edit.setText(
            self.results[current_combobox_index]["trackName"])
        self.genre_itunes_edit.setText(
            self.results[current_combobox_index]["primaryGenreName"])

        if "collectionName" in self.results[current_combobox_index]:
            self.album_itunes_edit.setText(
                self.results[current_combobox_index]["collectionName"])

        self.release_year_itunes_edit.setText(
            self.results[current_combobox_index]["releaseDate"][:4])

        if "trackNumber" in self.results[current_combobox_index]:
            self.track_no_itunes_edit.setText(
                str(self.results[current_combobox_index]["trackNumber"]))

        self.file_name_edit.setText(
            self.results[current_combobox_index]["artistName"] + " - " +
            self.results[current_combobox_index]["trackName"] + ".mp3")

    def load_custom_artwork(self):
        image_file_name, _ = QFileDialog.getOpenFileName(
            self, "Select Artwork File", None, "Images (*.png *.jpg)")

        with open(image_file_name, 'rb') as f:
            self.artwork_bytes = f.read()

            artwork = QPixmap()
            artwork.loadFromData(self.artwork_bytes)

        self.artwork_itunes_label.setPixmap(artwork.scaled(150, 150))

    def save(self):
        audio_path = self.search_dir + "/" + self.listbox.currentItem().text()
        audio_save_path = self.dest_dir + "/" + self.file_name_edit.text()

        if not self.artwork_bytes == None:
            if not self.checkbox.isChecked():
                found = 0
                for tag in self.audio_id3:
                    if tag.startswith("APIC") and (PictureType.COVER_FRONT
                                                   == 3):
                        self.audio_id3[tag].data = self.artwork_bytes
                        break

                if not found:
                    self.audio_id3.add(
                        APIC(encoding=3,
                             mime='image/jpeg',
                             type=3,
                             data=self.artwork_bytes))

        self.audio_id3.add(
            TPE1(encoding=3, text=self.artist_itunes_edit.text()))
        self.audio_id3.add(TIT2(encoding=3,
                                text=self.title_itunes_edit.text()))
        self.audio_id3.add(TCON(encoding=3,
                                text=self.genre_itunes_edit.text()))
        self.audio_id3.add(TALB(encoding=3,
                                text=self.album_itunes_edit.text()))
        self.audio_id3.add(
            TYER(encoding=3, text=self.release_year_itunes_edit.text()))
        self.audio_id3.add(
            TRCK(encoding=3, text=self.track_no_itunes_edit.text()))

        self.audio_id3.save(v2_version=3)

        shutil.move(audio_path, audio_save_path)

        self.refresh_listbox()
        self.listbox.setCurrentRow(0)