コード例 #1
0
class NavigationInterface(QWidget):
    """ 导航界面 """
    def __init__(self, contactInfo_list: List[Dict[str, str]], parent=None):
        super().__init__(parent=parent)
        # 读取用户信息
        self.userInfo = getUserInfo()
        # 实例化小部件
        self.searchLineEdit = SearchLineEdit(self)
        self.__createButtons()
        self.userNameLabel = QLabel(self)
        self.personalSignatureLabel = QLabel(self)
        self.headPortraitWidget = HeadPortrait(
            self.userInfo['headPortraitPath'], (45, 45), self)
        self.stackedWidget = QStackedWidget(self)
        self.chatListWidget = ChatListWidget(self)
        self.contactInterface = ContactInterface(contactInfo_list, self)
        self.stateWidget = StateWidget(parent=self)
        # 界面字典
        self.__interface_dict = {
            0: self.chatListWidget,
            1: self.contactInterface
        }
        # 初始化界面
        self.__initWidget()

    def __initWidget(self):
        """ 初始化界面 """
        self.setFixedWidth(402)
        self.resize(402, 917)
        self.stateWidget.move(40, 40)
        self.dialsButton.move(351, 70)
        self.searchButton.move(22, 83)
        self.stackedWidget.move(0, 183)
        self.userNameLabel.move(67, 13)
        self.searchLineEdit.move(10, 70)
        self.headPortraitWidget.move(10, 10)
        self.moreActionsButton.move(351, 11)
        self.personalSignatureLabel.move(67, 33)
        self.chatButton.move(38, 127)
        self.noticeButton.move(340, 127)
        self.contactButton.move(233, 127)
        self.conversationButton.move(138, 127)
        # 将子窗口添加到层叠窗口中
        self.stackedWidget.addWidget(self.chatListWidget)
        self.stackedWidget.addWidget(self.contactInterface)
        self.chatButton.setSelected(True)
        # 设置层叠样式
        self.setAttribute(Qt.WA_StyledBackground)
        self.setObjectName('navigationInterface')
        self.userNameLabel.setObjectName('userNameLabel')
        self.personalSignatureLabel.setObjectName('personalSignatureLabel')
        self.__setQss()
        # 调整个新签名和用户名长度
        self.__setLabelText()
        # 信号连接到槽函数
        self.__connectSignalToSlot()

    def __createButtons(self):
        """ 创建按钮 """
        opacity_dict = {'normal': 1, 'hover': 0.72, 'pressed': 0.2}
        chatButtonIconPath_dict = {
            'normal': r'app\resource\Image\navigation_interface\聊天_normal.png',
            'hover': r'app\resource\Image\navigation_interface\聊天_hover.png',
            'selected':
            r'app\resource\Image\navigation_interface\聊天_selected.png',
        }
        conversationButtonIconPath_dict = {
            'normal': r'app\resource\Image\navigation_interface\通话_normal.png',
            'hover': r'app\resource\Image\navigation_interface\通话_hover.png',
            'selected':
            r'app\resource\Image\navigation_interface\通话_selected.png',
        }
        contactsButtonIconPath_dict = {
            'normal':
            r'app\resource\Image\navigation_interface\联系人_normal.png',
            'hover':
            r'app\resource\Image\navigation_interface\联系人_hover.png',
            'selected':
            r'app\resource\Image\navigation_interface\联系人_selected.png',
        }
        noticeButtonIconPath_dict = {
            'normal': r'app\resource\Image\navigation_interface\通知_normal.png',
            'hover': r'app\resource\Image\navigation_interface\通知_hover.png',
            'selected':
            r'app\resource\Image\navigation_interface\通知_selected.png',
        }
        self.moreActionsButton = OpacityThreeStateToolButton(
            r'app\resource\Image\navigation_interface\更多操作.png',
            opacity_dict,
            parent=self)
        self.searchButton = OpacityThreeStateToolButton(
            r'app\resource\Image\navigation_interface\搜索.png', opacity_dict,
            (18, 18), self)
        self.dialsButton = OpacityThreeStateToolButton(
            r'app\resource\Image\navigation_interface\拨号盘.png', opacity_dict,
            (40, 40), self)
        self.chatButton = NavigationButton(chatButtonIconPath_dict,
                                           '聊天',
                                           parent=self)
        self.conversationButton = NavigationButton(
            conversationButtonIconPath_dict, '通话', parent=self)
        self.contactButton = NavigationButton(contactsButtonIconPath_dict,
                                              '联系人', (38, 42),
                                              parent=self)
        self.noticeButton = NavigationButton(noticeButtonIconPath_dict,
                                             '通知',
                                             parent=self)
        self.navigationButton_list = [
            self.chatButton, self.contactButton, self.conversationButton,
            self.noticeButton
        ]

    def __setQss(self):
        """ 设置层叠样式 """
        with open(r'app\resource\qss\navigation_interface.qss',
                  encoding='utf-8') as f:
            self.setStyleSheet(f.read())

    def paintEvent(self, e):
        """ 绘制背景 """
        super().paintEvent(e)
        painter = QPainter(self)
        painter.setPen(QPen(QColor(213, 217, 222)))
        painter.drawLine(0, 182, self.width(), 183)

    def resizeEvent(self, e):
        """ 调整窗口大小 """
        super().resizeEvent(e)
        self.stackedWidget.resize(self.width(), self.height() - 183)
        self.contactInterface.resize(self.stackedWidget.size())
        self.chatListWidget.resize(self.stackedWidget.size())

    def __setLabelText(self):
        """设置用户名和个新签名标签的文字并根据字符串长短来添加省略号 """
        # 调整个新签名
        fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 8))
        newText = fontMetrics.elidedText(self.userInfo['personalSignature'],
                                         Qt.ElideRight, 250)
        self.personalSignatureLabel.setText(newText)
        self.personalSignatureLabel.adjustSize()
        # 调整用户名
        newText = fontMetrics.elidedText(self.userInfo['userName'],
                                         Qt.ElideRight, 260)
        self.userNameLabel.setText(newText)
        self.userNameLabel.adjustSize()

    def updateUserInfo(self, userInfo: dict):
        """ 更新用户信息 """
        self.userInfo = userInfo.copy()
        self.__setLabelText()
        self.headPortraitWidget.setHeadPortrait(userInfo['headPortraitPath'])

    def switchToContactInterface(self):
        """ 切换到联系人界面 """
        self.__switchInterface(1)

    def switchToChatInterface(self):
        """ 切换到联系人界面 """
        self.__switchInterface(0)

    def __switchInterface(self, index: int):
        """ 切换界面 """
        currentIndex = self.stackedWidget.currentIndex()
        if index not in self.__interface_dict.keys():
            self.navigationButton_list[index].setSelected(False)
            return
        elif index == currentIndex:
            return
        self.navigationButton_list[currentIndex].setSelected(False)
        self.navigationButton_list[index].setSelected(True)
        self.stackedWidget.setCurrentWidget(self.__interface_dict[index])

    def __connectSignalToSlot(self):
        """ 信号连接到槽函数 """
        # 切换界面
        for i, button in enumerate(self.navigationButton_list):
            button.clicked.connect(lambda x, i=i: self.__switchInterface(i))
コード例 #2
0
class MyMainWindow(QMainWindow):
    tuning = {"E A D G B E": [52, 47, 43, 38, 33, 28]}

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

        if self.editing_component == -1:
            self.new_music_project()
            # self.open_Gmusic_file()

    def initVariable(self):
        self.component = []  # 存放打开的音乐项目,最多5个
        self.editing_component = -1  # 正在编辑的项目,若没有则为-1
        self.editing_track = -1  # 正在编辑的音轨

        self.fs, self.fluid = self.load_soundfont()  # 初始化音色库
        self.varible = varible

    def initUI(self):
        self.resize(1000, 600)
        self.setWindowTitle("Guitar Music")
        self.center()

        self.set_widget()
        self.set_menu()

    # 设置菜单栏
    def set_menu(self):
        # menubar = QMenuBar(self)
        menubar = self.menuBar()
        menu = menubar.addMenu("文件(File)")
        menu.addAction("新建", lambda: self.new_music_project(),
                       Qt.CTRL + Qt.Key_N)  # 带图标,文字
        menu.addAction("打开", lambda: self.thread_it(self.open_Gmusic_file()),
                       Qt.CTRL + Qt.Key_O)
        menu.addSeparator()
        menu.addAction("保存", lambda: self.save_Gmusic_file(),
                       Qt.CTRL + Qt.Key_S)
        menu.addAction("另存为", lambda: self.save_other_Gmusic_file,
                       Qt.CTRL + Qt.SHIFT + Qt.Key_S)
        menu.addSeparator()
        m = menu.addMenu("导入")
        m.addAction("MIDI", lambda: self.import_midi())
        m = menu.addMenu("导出")
        m.addAction("MIDI...", lambda: self.thread_it(self.leading_out_midi()))
        m.addAction("PNG...", lambda: self.save_img())
        menu.addSeparator()
        menu.addAction("退出", lambda: print("退出"), Qt.ALT + Qt.Key_F4)

        menu = menubar.addMenu("编辑(Edit)")
        menu.addAction("复制", lambda: self.copy_bar(), Qt.CTRL + Qt.Key_C)
        menu.addAction("粘贴", lambda: self.paste_bar(), Qt.CTRL + Qt.Key_V)
        menu.addSeparator()
        menu.addAction("删除本节", lambda: self.remove_bar(), Qt.CTRL + Qt.Key_D)

        menu = menubar.addMenu("音轨(Track)")
        menu.addAction("添加", lambda: print("添加音轨"))
        menu.addAction("删除", lambda: print("删除音轨"))
        menu.addSeparator()
        menu.addAction("播放", lambda: self.thread_it(self.play_music()))

        menu = menubar.addMenu("帮助(Help)")
        menu.addAction("关于Guitar Music", lambda: print("关于Guitar Music"))
        menu.addSeparator()
        menu.addAction("用户中心", lambda: print("用户中心"))

    # 设置布局
    def set_widget(self):
        left_part = self._create_wedget(self, 300, 600, 0, 0)
        right_part = self._create_wedget(self, 700, 600, 300, 0)

        music_box = self._create_wedget(left_part, 300, 400, 0, 0, "#E0EEEE")
        note_box = self._create_wedget(left_part, 300, 200, 0, 400, "#E0EEEE")

        play_box = self._create_wedget(right_part, 700, 100, 0, 0, "#FFF8DC")
        draw_box = self._create_wedget(right_part, 700, 500, 0, 100, "#FCFCFC")

        self.set_music_message_layout(music_box)
        self.set_note_message_layout(note_box)
        self.set_play_layout(play_box)
        self.set_draw_layout(draw_box)

    # 设置音乐信息布局
    def set_music_message_layout(self, box):
        def change_to_music():
            self.stackedWidget.setCurrentIndex(0)
            music_but.setStyleSheet(
                "height:30;width:150;border:0;background:#E0EEEE")
            track_but.setStyleSheet(
                "height:30;width:150;border:0;background:#C9C9C9")

        def change_to_track():
            self.stackedWidget.setCurrentIndex(1)
            track_but.setStyleSheet(
                "height:30;width:150;border:0;background:#E0EEEE")
            music_but.setStyleSheet(
                "height:30;width:150;border:0;background:#C9C9C9")

        music_but = QPushButton("音乐", box)
        music_but.setStyleSheet(
            "height:30;width:150;border:0;background:#E0EEEE")
        music_but.clicked.connect(lambda: change_to_music())
        music_but.move(0, 23)
        track_but = QPushButton("音轨", box)
        track_but.setStyleSheet(
            "height:30;width:150;border:0;background:#C9C9C9")
        track_but.clicked.connect(lambda: change_to_track())
        track_but.move(150, 23)

        show = QWidget(box)
        show.resize(300, 347)
        show.move(0, 53)

        self.stackedWidget = QStackedWidget(show)
        self.stackedWidget.addWidget(self.__music_widget())
        self.stackedWidget.addWidget(self.__track_widget())
        self.stackedWidget.move(0, 23)

        # change_to_music()

    def __music_widget(self):
        music = QWidget()

        name = QLabel('音乐名称')
        artist = QLabel('艺术家')
        meter = QLabel('节拍')
        bpm = QLabel('bpm')

        self.music_name_edit = QLineEdit()
        self.music_name_edit.textChanged.connect(
            lambda: self.set_component_name())
        self.music_artist_edit = QLineEdit()
        self.music_artist_edit.textChanged.connect(
            lambda: self.set_artist_name())
        self.music_meter_edit = QComboBox()
        self.music_meter_edit.addItem("四分音符")
        # self.music_meter_edit.addItem("八分音符")

        self.music_bpm_edit = QSlider(Qt.Horizontal)  # 速度滑块
        self.music_bpm_edit.setRange(40, 360)
        self.music_bpm_edit.setValue(120)
        self.bpm_num = QLabel(str(self.music_bpm_edit.value()))
        self.music_bpm_edit.valueChanged.connect(lambda: self.set_bpm())

        grid = QGridLayout()
        grid.setContentsMargins(30, 0, 0, 0)  # 设置边界
        grid.setSpacing(10)  # 设置内部组件间距

        grid.addWidget(name, 1, 0)
        grid.addWidget(self.music_name_edit, 1, 1)
        grid.addWidget(artist, 2, 0)
        grid.addWidget(self.music_artist_edit, 2, 1)
        grid.addWidget(meter, 3, 0)
        grid.addWidget(self.music_meter_edit, 3, 1)
        grid.addWidget(bpm, 4, 0)
        grid.addWidget(self.music_bpm_edit, 4, 1)
        grid.addWidget(self.bpm_num, 4, 2)

        music.setLayout(grid)
        return music

    def __track_widget(self):
        track = QWidget()

        name = QLabel('音轨')
        change = QLabel('切换音轨')
        program = QLabel('乐器')
        tuning = QLabel('调音')

        self.track_name_edit = QLineEdit()
        self.track_name_edit.textEdited.connect(lambda: self.set_track_name())
        change_edit = QComboBox()
        change_edit.addItem("音轨1")
        # change_edit.addItem("八分音符")
        self.program_edit = QComboBox()
        self.program_edit.addItem("24 " + m_p.program_dict["24"])
        self.program_edit.addItem("25 " + m_p.program_dict["25"])
        self.program_edit.addItem("26 " + m_p.program_dict["26"])
        self.program_edit.addItem("27 " + m_p.program_dict["27"])
        self.program_edit.addItem("28 " + m_p.program_dict["28"])
        self.program_edit.currentIndexChanged.connect(
            lambda: self.set_track_program())

        tuning_edit = QPushButton('E A D G B E')

        playing_turning = QPushButton('▶')
        playing_turning.setMaximumWidth(35)
        playing_turning.clicked.connect(
            lambda: self.thread_it(self.play_tuning()))

        grid = QGridLayout()
        grid.setContentsMargins(30, 0, 0, 0)  # 设置边界
        grid.setSpacing(10)  # 设置内部组件间距

        grid.addWidget(name, 1, 0)
        grid.addWidget(self.track_name_edit, 1, 1)
        grid.addWidget(change, 2, 0)
        grid.addWidget(change_edit, 2, 1)
        grid.addWidget(program, 3, 0)
        grid.addWidget(self.program_edit, 3, 1)
        grid.addWidget(tuning, 4, 0)
        grid.addWidget(tuning_edit, 4, 1)
        grid.addWidget(playing_turning, 4, 2)

        track.setLayout(grid)

        return track

    # 设置音符信息布局
    def set_note_message_layout(self, box):
        def set_note_type(type):
            self.varible.note_type = type

        def set_special_note(note):
            self.varible.special_note = note

        self.note_1_button = QPushButton("全音符")
        self.note_1_button.clicked.connect(lambda: set_note_type(1))
        self.note_2_button = QPushButton("二分音符")
        self.note_2_button.clicked.connect(lambda: set_note_type(2))
        self.note_4_button = QPushButton("四分音符")
        self.note_4_button.clicked.connect(lambda: set_note_type(4))
        self.note_8_button = QPushButton("八分音符")
        self.note_8_button.clicked.connect(lambda: set_note_type(8))
        self.note_16_button = QPushButton("十六分音符")
        self.note_16_button.clicked.connect(lambda: set_note_type(16))
        # self.note_32_button = QPushButton("三十二分音符")
        # self.note_32_button.clicked.connect(lambda: set_note_type(32))

        self.note_downDrum_button = QPushButton("底鼓")
        self.note_downDrum_button.clicked.connect(
            lambda: set_special_note("Down_Drum"))
        self.note_upDrum_button = QPushButton("指鼓")
        self.note_upDrum_button.clicked.connect(
            lambda: set_special_note("Up_Drum"))
        self.note_slide_button = QPushButton("滑音")
        self.note_slide_button.clicked.connect(
            lambda: set_special_note("Pitch_Note"))
        self.note_harm_button = QPushButton("泛音")
        self.note_harm_button.clicked.connect(
            lambda: set_special_note("Harm_Note"))
        self.note_vibrato_button = QPushButton("颤音")
        self.note_vibrato_button.clicked.connect(
            lambda: set_special_note("Vibrato_Note"))
        self.note_muffled_button = QPushButton("闷音")
        self.note_muffled_button.clicked.connect(
            lambda: set_special_note("Muffled_Sound"))
        self.note_click_button = QPushButton("点弦")
        self.note_click_button.clicked.connect(
            lambda: set_special_note("Click_Note"))
        self.note_cut_button = QPushButton("空拍")
        self.note_cut_button.clicked.connect(
            lambda: set_special_note("Cut_Sound"))

        grid = QGridLayout()
        # grid.setContentsMargins(30, 0, 0, 0)  # 设置边界
        # grid.setSpacing(10)  # 设置内部组件间距

        grid.addWidget(self.note_1_button, 1, 0)
        grid.addWidget(self.note_2_button, 1, 1)
        grid.addWidget(self.note_4_button, 1, 2)
        grid.addWidget(self.note_8_button, 1, 3)

        grid.addWidget(self.note_16_button, 2, 0)
        # grid.addWidget(self.note_32_button, 2, 1)

        grid.addWidget(self.note_downDrum_button, 3, 0)
        grid.addWidget(self.note_upDrum_button, 3, 1)
        grid.addWidget(self.note_slide_button, 3, 2)
        grid.addWidget(self.note_harm_button, 3, 3)

        grid.addWidget(self.note_vibrato_button, 4, 0)
        grid.addWidget(self.note_muffled_button, 4, 1)
        grid.addWidget(self.note_click_button, 4, 2)
        grid.addWidget(self.note_cut_button, 4, 3)

        box.setLayout(grid)

    def set_play_layout(self, box):
        # 这里设置播放停止的按钮,切换歌曲窗口的下拉条,(当前歌曲的小节数,时间,放着或者musicbox里)
        grid = QGridLayout()
        grid.setSpacing(20)
        grid.setContentsMargins(40, 40, 40, 40)

        self.play_music_combo_box = QComboBox()
        self.play_music_combo_box.currentIndexChanged.connect(
            lambda: self.change_component())

        self.play = QPushButton('▶')
        self.play.setMaximumSize(30, 30)
        self.play.setMinimumSize(30, 30)
        self.play.setStyleSheet(
            "width:30;height:30;border:1px solid #6495ED;border-radius:15px;background:#6495ED;font-size:20px"
        )
        self.play.clicked.connect(lambda: self.play_music())

        self.stop = QPushButton('■')
        self.stop.setMaximumSize(30, 30)
        self.stop.setMinimumSize(30, 30)
        self.stop.setStyleSheet(
            "width:30;height:30;border:1px solid #6495ED;border-radius:15px;background:#6495ED;font-size:20px"
        )
        self.stop.clicked.connect(lambda: self.stop_music())
        self.stop.hide()
        bar_count = QLabel("小节数")
        self.bar_count_edit = QLabel()

        time = QLabel("时间")

        grid.addWidget(self.play_music_combo_box, 1, 0)
        grid.addWidget(self.play, 1, 1)
        grid.addWidget(self.stop, 1, 1)
        grid.addWidget(bar_count, 1, 2)
        grid.addWidget(self.bar_count_edit, 1, 3)
        grid.addWidget(time, 1, 4)

        box.setLayout(grid)

    def set_draw_layout(self, box):
        self.wheel_draw = QWidget()
        self.wheel_draw.resize(700, 10000)

        # 音乐名称
        self.component_name = QLabel(self.wheel_draw)
        self.component_name.move(0, 50)
        self.component_name.setStyleSheet("font:20pt '楷体'")

        # 艺术家
        artist_name = QLabel(self.wheel_draw)
        artist_name.setText("艺术家  ")
        artist_name.setStyleSheet("font:11pt '宋体'")
        artist_name.resize(50, 50)
        artist_name.move(50, 100)
        self.artist_name = QLabel(self.wheel_draw)
        self.artist_name.setStyleSheet("font:11pt '宋体'")
        self.artist_name.move(100, 100)
        self.artist_name.resize(200, 50)

        self.play_move = QPushButton(self.wheel_draw)
        self.play_move.setStyleSheet(
            "border:0;height:80;width:1;background:#1C86EE;opacity:0.5")
        self.play_move.move(50, 150)
        self.play_move.hide()

        self.scrol = WheelWidget(box)
        self.scrol.right_key.connect(self.create_new_barWidget)
        self.scrol.resize(700, 500)
        self.scrol.setWidget(self.wheel_draw)
        self.scroll_bar = self.scrol.verticalScrollBar()
        # 这里主要是绘制用,首先就需要一个滚动条

    # 建立一个布局空间
    def _create_wedget(self,
                       parent,
                       sizeX,
                       sizeY,
                       moveX=0,
                       moveY=0,
                       bgcolor="ffffff"):
        wedget = QWidget(parent)
        wedget.resize(sizeX, sizeY)
        wedget.move(moveX, moveY)
        wedget.setStyleSheet("background-color:" + bgcolor)
        return wedget

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

    # 加载音色库
    def load_soundfont(self):
        w = self._create_wedget(None, 200, 100)
        w.show()
        fs, fluid = assistant.load_soundfont("soundfont/Hubbe64MB.sf2")
        fs.start()
        w.close()
        return fs, fluid

    # 新建一个新的音乐项目
    def new_music_project(self):
        if self.component.__len__() <= 5:
            component = my_guitar.Component(self.fs, self.fluid)
            self.component.append({"component": component, "path": None})
            self.editing_component = self.component.__len__() - 1
            self.set_music()
        else:
            print("太多了,不能再新建了")

    # 打开一个gmusic文件
    def open_Gmusic_file(self):
        path, filetype = QFileDialog.getOpenFileName(
            self, "选取文件", "/Users/Kelisiya/Desktop", "Gmusic Files (*.gmusic)")
        if path == '': return
        if self.component.__len__() <= 5:
            component = my_guitar.Component(self.fs, self.fluid)
            component.load_Gmusic(path)
            self.component.append({"component": component, "path": path})
            self.editing_component = self.component.__len__() - 1
            self.set_music()
        else:
            # print("太多了,不能再新建了")
            pass

    # 保存(已完成)
    def save_Gmusic_file(self):
        if self.editing_component == -1: return
        if not self.component[self.editing_component]["path"]:
            self.component[self.editing_component]["path"], type = \
                QFileDialog.getSaveFileName(self, 'save file', '/home/jm/study', "Gmusic Files (*.gmusic)")

        path = self.component[self.editing_component]["path"]
        if path == "": return
        print(path)
        self.component[self.editing_component]["component"].save_Gmusic(path)

    # 另存为Gmusic(已完成)
    def save_other_Gmusic_file(self):
        if self.editing_component == -1: return
        self.component[self.editing_component]["path"], type = \
            QFileDialog.getSaveFileName(self, 'save file', '/home/jm/study', "Gmusic Files (*.gmusic)")

        path = self.component[self.editing_component]["path"]
        if path == "": return
        self.component[self.editing_component]["component"].save_Gmusic(path)

    # 导出为midi文件(已完成)
    def leading_out_midi(self):
        if self.editing_component == -1: return
        path, type = \
            QFileDialog.getSaveFileName(self, 'save file', '/home/jm/study', "Gmusic Files (*.midi)")

        if path == '': return
        pattern = assistant.change_music_to_pattern(
            self.component[self.editing_component]["component"])
        assistant.save_midi_file(path, pattern)

    # 根据当前的正在编辑的音乐设置音乐相关信息
    def set_music(self):
        component = self.component[self.editing_component]["component"]

        self.music_name_edit.setText(component.name)
        self.music_artist_edit.setText(component.artist)
        if component.denominator == 4:
            self.music_meter_edit.setCurrentIndex(0)
        elif component.denominator == 8:
            self.music_meter_edit.setCurrentIndex(1)
        self.music_bpm_edit.setValue(component.bpm)

        self.editing_track = 0
        self.track_name_edit.setText(
            component.track_msg[self.editing_track].name)
        # 切换音轨 = 添加所有音轨,显示当前音轨(主音轨不添加)
        self.program_edit.setCurrentIndex(
            component.track_msg[self.editing_track].program - 24)
        # 调音 = 当前音轨调音

        self.play_music_combo_box.addItem(component.name)
        self.play_music_combo_box.setCurrentIndex(self.editing_component)
        self.bar_count_edit.setText(
            str(self.component[self.editing_component]["component"].track_msg[
                self.editing_track].bars.__len__()))
        # 显示时间

        self.draw_component_track()

    # 设置读取的midi音乐
    def set_my_music(self):
        component = self.component[self.editing_component]["component"]

        # self.music_name_edit.setText(component.name)
        # self.music_artist_edit.setText(component.artist)
        # if component.denominator == 4:
        #     self.music_meter_edit.setCurrentIndex(0)
        # elif component.denominator == 8:
        #     self.music_meter_edit.setCurrentIndex(1)
        # self.music_bpm_edit.setValue(component.bpm)

        # self.editing_track = 0
        self.track_name_edit.setText("midi")
        # 切换音轨 = 添加所有音轨,显示当前音轨(主音轨不添加)
        # self.program_edit.setCurrentIndex(component.track_msg[self.editing_track].program - 24)
        # 调音 = 当前音轨调音

        self.play_music_combo_box.addItem("midi")
        self.play_music_combo_box.setCurrentIndex(self.editing_component)
        # self.bar_count_edit.setText(str(self.component[self.editing_component]["component"].track_msg[self.editing_track].bars.__len__()))
        # 显示时间

        # self.draw_component_track()

    # 设置音乐名称,包括显示在画布上
    def set_component_name(self):
        self.component_name.setText(self.music_name_edit.text())
        self.component_name.adjustSize()
        self.component[self.editing_component][
            "component"].name = self.music_name_edit.text()
        # self.component_name.resize()
        # print(self.component_name.size().width())
        self.component_name.move(350 - self.component_name.size().width() // 2,
                                 50)

    # 设置艺术家名称,包括显示在画布上
    def set_artist_name(self):
        self.artist_name.setText(self.music_artist_edit.text())
        # self.component[self.editing_component]["component"].name = self.music_name_edit.text()

    # 绘画音轨
    def draw_component_track(self):
        if self.editing_component == -1 or self.editing_track == -1:
            return
        track = self.component[self.editing_component]["component"].track_msg[
            self.editing_track]
        for old_bar in self.scrol.barWidgets:
            old_bar.deleteLater()
        self.scrol.barWidgets = []
        self.scrol.editing_barWidget = 0
        for index, bar in enumerate(track.bars):
            x = (index + 2) % 2
            y = index // 2
            self.wheel_draw.repaint()
            b = BarWidget(self.wheel_draw, 50 + x * 300, 150 + y * 120, bar)
            b.clicked.connect(
                self.scrol.change_editing_bar_widget)  # 接受点击后传回来的哪个barWidget
            b.show()
            self.scrol.barWidgets.append(b)

    def create_new_barWidget(self, x, y, y_index):
        # self.wheel_draw.repaint()
        # # 这里要把新的bar加入component
        bar = my_guitar.Bar()
        self.component[self.editing_component]["component"].track_msg[
            self.editing_track].add_bar(bar)
        b = BarWidget(self.wheel_draw, 50 + x * 300, 150 + y * 120, bar)
        b.clicked.connect(
            self.scrol.change_editing_bar_widget)  # 接受点击后传回来的哪个barWidget
        b.show()
        note = my_guitar.None_Note(varible.note_type)
        b.bar.add_note(note, y)
        b.repaint()

        self.scrol.barWidgets.append(b)
        self.scrol.barWidgets[self.scrol.editing_barWidget +
                              1].move_pitch_input(x, y_index)
        self.bar_count_edit.setText(
            str(self.component[self.editing_component]["component"].track_msg[
                self.editing_track].bars.__len__()))

    # 打包进线程(耗时的操作)
    @staticmethod
    def thread_it(func, *args):
        t = threading.Thread(target=func, args=args)
        t.setDaemon(True)  # 守护--就算主界面关闭,线程也会留守后台运行(不对!)
        t.start()  # 启动
        # t.join()          # 阻塞--会卡死界面!

    # 设置音轨名称
    def set_track_name(self):
        self.component[self.editing_component]["component"].track_msg[
            self.editing_track].set_track_name(self.track_name_edit.text())

    # 更换音轨乐器
    def set_track_program(self):
        self.component[self.editing_component]["component"].track_msg[
            self.editing_track].program = self.program_edit.currentIndex() + 24

    # 设置bpm
    def set_bpm(self):
        self.bpm_num.setText(str(self.music_bpm_edit.value()))
        self.component[self.editing_component][
            "component"].bpm = self.music_bpm_edit.value()
        com = self.component[self.editing_component]["component"]
        com.calculate_tick_with_bpm(com.bpm, com._resolution, com.denominator)

    # 播放调音
    def play_tuning(self):
        self.fs.program_select(0, self.fluid, 0,
                               self.program_edit.currentIndex() + 24)
        for i in reversed(varible.track_base_tuning):
            self.fs.noteon(0, i, 90)
            time.sleep(0.4)
            self.fs.noteoff(0, i)

    # 播放音乐
    def play_music(self):
        print("aaa")
        print(self.component[self.editing_component]
              ["component"].__class__.__name__)
        if self.component[self.editing_component][
                "component"].__class__.__name__ == "Component":
            self.play_move.show()
            self.play.hide()
            self.stop.show()

            self.move_thread = MoveThread(self.play_move,
                                          int(self.bpm_num.text()),
                                          self.scroll_bar)
            self.move_thread.start()

            self.play_thread = PlayThread(
                self.component[self.editing_component]["component"], self.play,
                self.stop, self.move_thread)
            self.play_thread.start()
        else:
            self.play.hide()
            self.stop.show()

            self.play_midi_thread = PlayMidi(
                self.component[self.editing_component]["component"],
                self.play,
                self.stop,
            )
            self.play_midi_thread.start()

    # 停止播放
    def stop_music(self):
        if self.component[self.editing_component][
                "component"].__class__.__name__ == "Component":
            self.move_thread.stop()
            self._async_raise(self.play_thread.ident, SystemExit)
        else:
            self._async_raise(self.play_midi_thread.ident, SystemExit)

        self.play.show()
        self.stop.hide()

    # 抛出异常来结束线程
    @staticmethod
    def _async_raise(t, exctype):
        """raises the exception, performs cleanup if needed"""
        tid = ctypes.c_long(t)
        if not inspect.isclass(exctype):
            exctype = type(exctype)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
            tid, ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            # """if it returns a number greater than one, you're in trouble,
            # and you should call it again with exc=NULL to revert the effect"""
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)

    # 复制一小节的数据
    def copy_bar(self):
        self.bar_data = {}
        groups = []
        bar = self.scrol.barWidgets[self.scrol.editing_barWidget].bar.bar
        for group in bar:
            group_msg = {}
            notes = []
            group_msg.setdefault("note_type", group["note_type"])
            for note in group["group"].group:
                note_msg = {}
                if note:
                    note_msg.setdefault("class", note.__class__.__name__)
                    if note.__class__.__name__ == "Pitch_start_Note":
                        note_msg.setdefault("new_pitch", note.new_pitch)
                    note_msg.setdefault("channel", note.channel)
                    note_msg.setdefault("division", note.division)
                    note_msg.setdefault("name", note.name)
                    note_msg.setdefault("pitch", note.pitch)
                    note_msg.setdefault("velocity", note.velocity)
                    notes.append(note_msg)
                else:
                    notes.append(None)
            group_msg.setdefault("group", notes)
            groups.append(group_msg)
        self.bar_data.setdefault("bar", groups)

    # 粘贴一小节数据
    def paste_bar(self):
        bar_msg = my_guitar.Bar()
        for i, group in enumerate(self.bar_data["bar"]):
            group_msg = my_guitar.NoteGroup(type=group["note_type"])
            for index, note in enumerate(group["group"]):
                bar_msg.is_using = True
                if not note:
                    continue
                if note["class"] == "Up_Drum" or note["class"] == "Down_Drum":
                    note_msg = globals()[note["class"]](note["pitch"],
                                                        note["velocity"],
                                                        note["name"],
                                                        note["channel"],
                                                        note["division"])
                    group_msg.set_nodes(6, note_msg)
                    continue
                if note["class"] == "Pitch_start_Note":
                    note_msg = globals()[note["class"]](
                        note["new_pitch"], note["pitch"], note["velocity"],
                        note["name"], note["channel"], note["division"])
                else:
                    note_msg = globals()[note["class"]](note["pitch"],
                                                        note["velocity"],
                                                        note["name"],
                                                        note["channel"],
                                                        note["division"])
                group_msg.set_nodes(index, note_msg)
            bar_msg.set_group(i, group_msg)

        self.scrol.barWidgets[self.scrol.editing_barWidget].bar = bar_msg
        self.scrol.barWidgets[self.scrol.editing_barWidget].parse_bar()
        self.scrol.barWidgets[self.scrol.editing_barWidget].repaint()
        self.component[self.editing_component]["component"].track_msg[
            self.editing_track].bars[self.scrol.editing_barWidget] = bar_msg

    # 切换音乐项目
    def change_component(self):
        if self.editing_component == self.play_music_combo_box.currentIndex():
            return
        self.editing_component = self.play_music_combo_box.currentIndex()

        component = self.component[self.editing_component]["component"]
        self.music_name_edit.setText(component.name)
        self.music_artist_edit.setText(component.artist)
        if component.denominator == 4:
            self.music_meter_edit.setCurrentIndex(0)
        elif component.denominator == 8:
            self.music_meter_edit.setCurrentIndex(1)
        self.music_bpm_edit.setValue(component.bpm)

        self.editing_track = 0
        self.track_name_edit.setText(
            component.track_msg[self.editing_track].name)
        # 切换音轨 = 添加所有音轨,显示当前音轨(主音轨不添加)
        self.program_edit.setCurrentIndex(
            component.track_msg[self.editing_track].program - 24)
        # 调音 = 当前音轨调音
        self.bar_count_edit.setText(
            str(self.component[self.editing_component]["component"].track_msg[
                self.editing_track].bars.__len__()))
        # 显示时间

        self.draw_component_track()

    # 删除小节
    def remove_bar(self):
        if self.scrol.barWidgets.__len__() == 1:
            return
        remove_index = self.scrol.editing_barWidget
        if remove_index == 0:
            self.scrol.barWidgets[1].move_pitch_input(0, 0)
            self.scrol.editing_barWidget = 0
        else:
            self.scrol.barWidgets[remove_index - 1].move_pitch_input(0, 0)
            self.scrol.editing_barWidget = remove_index - 1

        self.scrol.barWidgets.pop(remove_index).deleteLater()
        self.component[self.editing_component]["component"].track_msg[
            self.editing_track].bars.pop(remove_index)
        a = self.editing_component
        self.editing_component = -1
        #
        self.change_component()

    # 导出图片
    def save_img(self):
        if self.editing_component == -1: return
        path, type = \
            QFileDialog.getSaveFileName(self, 'save file', '/home/jm/study', "Gmusic Files (*.png)")

        if path == '': return
        save_thread = SaveImg(self.scroll_bar,
                              self.x() + 320,
                              self.y() + 135,
                              self.x() + 980,
                              self.y() + 601, path)
        save_thread.start()

    # 导入midi
    def import_midi(self):
        path, filetype = QFileDialog.getOpenFileName(
            self, "选取文件", "/Users/Kelisiya/Desktop", "Midi Files (*.midi)")
        if path == '': return
        if self.component.__len__() <= 5:
            pattern = assistant.read_midi(path)
            component = assistant.change_pattern_to_music(pattern)
            self.component.append({"component": component, "path": path})
            self.editing_component = self.component.__len__() - 1
            self.set_my_music()
        else:
            print("太多了,不能再新建了")
コード例 #3
0
import sys
from PyQt5.QtWidgets import QApplication, QStackedWidget
from PyQt5 import QtGui

from Login.View.ViewLogin import ViewLogin

if __name__ == '__main__':
    app = QApplication(sys.argv)

    widget = QStackedWidget()

    Vista_login = ViewLogin(widget)

    widget.addWidget(Vista_login)
    widget.setStyleSheet("background-color: rgb(254, 235, 156)")
    widget.setWindowTitle("Cinema")
    icon = QtGui.QIcon()
    icon.addPixmap(QtGui.QPixmap("images/biglietto.png"), QtGui.QIcon.Normal,
                   QtGui.QIcon.Off)
    widget.setWindowIcon(icon)
    # Spostamento widget al centro (fissare dimensione login al max per mantenere tutto al centro)
    widget.show()
    centerPoint = QtGui.QScreen.availableGeometry(app.primaryScreen()).center()
    fg = widget.frameGeometry()
    fg.moveCenter(centerPoint)
    widget.move(fg.topLeft())

    sys.exit(app.exec())
コード例 #4
0
ファイル: LeftPanel.py プロジェクト: zhuoyingcai/cts
class LeftPanel(QWidget):
    def __init__(self, width, hight, parent=None):
        super(LeftPanel, self).__init__(parent)

        # set width and hight
        self.width = width
        self.hight = hight

        # declare path string
        self.unknownUser = "******"
        self.menuIcon = "../img/menu-icon.png"

        # declare user picture label
        self.pic = QLabel(self)
        self.pic.setScaledContents(True)

        # declare control panel
        self.controlPanel = QStackedWidget(self)
        # declare control button
        # for visitor and temp user
        self.homeB0 = QPushButton("Home")
        self.searchB0 = QPushButton("Search")
        # for develop has no transaction history
        self.homeB1 = QPushButton("Home")
        self.searchB1 = QPushButton("Search")
        self.ProjectB1 = QPushButton("Project")
        self.messageB1 = QPushButton("Message")
        self.historyB1 = QPushButton("History")
        self.manageTeam1 = QPushButton("Team Manager")
        # for develop has transaction history
        self.homeB2 = QPushButton("Home")
        self.searchB2 = QPushButton("Search")
        self.ProjectB2 = QPushButton("Project")
        self.messageB2 = QPushButton("Message")
        self.historyB2 = QPushButton("History")
        self.manageTeam2 = QPushButton("Team Manager")
        # for client has no transaction history
        self.homeB3 = QPushButton("Home")
        self.searchB3 = QPushButton("Search")
        self.ProjectB3 = QPushButton("Project")
        self.messageB3 = QPushButton("Message")
        self.historyB3 = QPushButton("History")
        # for client has transaction history
        self.homeB4 = QPushButton("Home")
        self.searchB4 = QPushButton("Search")
        self.ProjectB4 = QPushButton("Project")
        self.messageB4 = QPushButton("Message")
        self.historyB4 = QPushButton("History")
        # for superuser
        self.manage = QPushButton("System Manager")
        self.messageB5 = QPushButton("Message")
        # for new user
        self.homeB5 = QPushButton("Home")
        self.searchB5 = QPushButton("Search")

        # declare function button
        self.funcbutt = QToolButton(self)
        self.mu = QMenu()
        # declare action
        self.personalInfo = QAction("Personal Information")
        self.grandStat = QAction("Grand Statistic")
        self.out = QAction("Sign Out")

        # start initUI
        self.initUI()

    def initUI(self):
        # set LeftPanel size
        self.setFixedSize(self.width, self.hight)

        # set LeftPanel background color
        self.setAutoFillBackground(True)
        palette = QPalette()
        palette.setColor(self.backgroundRole(), QColor(40, 42, 45))
        self.setPalette(palette)

        # set pic
        self.setpic(self.unknownUser)
        # set pic size
        self.pic.setFixedSize(self.width - 20, self.width - 20)
        # add pic to LeftPanel
        self.pic.move(10, 10)

        # set stackWidget size
        self.controlPanel.setFixedSize(self.width, self.hight - 250)
        # add visitor page to controlPanel
        v = QWidget()
        vly = QFormLayout()
        vly.addRow(self.homeB0)
        vly.addRow(self.searchB0)
        v.setLayout(vly)
        self.controlPanel.addWidget(v)
        # add dev has no transaction to controlpanel
        dnt = QWidget()
        dntly = QFormLayout()
        dntly.addRow(self.homeB1)
        dntly.addRow(self.searchB1)
        dntly.addRow(self.ProjectB1)
        dntly.addRow(self.messageB1)
        dntly.addRow(self.historyB1)
        dntly.addRow(self.manageTeam1)
        dnt.setLayout(dntly)
        self.controlPanel.addWidget(dnt)
        # add dev has transaction to controlPanel
        dt = QWidget()
        dtly = QFormLayout()
        dtly.addRow(self.homeB2)
        dtly.addRow(self.searchB2)
        dtly.addRow(self.ProjectB2)
        dtly.addRow(self.messageB2)
        dtly.addRow(self.historyB2)
        dtly.addRow(self.manageTeam2)
        dt.setLayout(dtly)
        self.controlPanel.addWidget(dt)
        # add client has no transaction
        cnt = QWidget()
        cntly = QFormLayout()
        cntly.addRow(self.homeB3)
        cntly.addRow(self.searchB3)
        cntly.addRow(self.ProjectB3)
        cntly.addRow(self.messageB3)
        cntly.addRow(self.historyB3)
        cnt.setLayout(cntly)
        self.controlPanel.addWidget(cnt)
        # add client has transaction
        ct = QWidget()
        ctly = QFormLayout()
        ctly.addRow(self.homeB4)
        ctly.addRow(self.searchB4)
        ctly.addRow(self.ProjectB4)
        ctly.addRow(self.messageB4)
        ctly.addRow(self.historyB4)
        ct.setLayout(ctly)
        self.controlPanel.addWidget(ct)
        # add super user
        su = QWidget()
        suly = QFormLayout()
        suly.addRow(self.manage)
        suly.addRow(self.messageB5)
        su.setLayout(suly)
        self.controlPanel.addWidget(su)
        # add new user
        new = QWidget()
        newly = QFormLayout()
        newly.addRow(self.homeB5)
        newly.addRow(self.searchB5)
        new.setLayout(newly)
        self.controlPanel.addWidget(new)
        # add controlPanel to LeftPanel
        self.controlPanel.setCurrentIndex(0)
        self.controlPanel.move(0, 180)

        # set funcbutt menu
        self.setFuncMenu(False)
        self.funcbutt.setPopupMode(QToolButton.InstantPopup)
        self.funcbutt.setMenu(self.mu)
        # set image for funcbutt
        self.funcbutt.setIcon(QIcon(self.menuIcon))
        self.funcbutt.setIconSize(QSize(60, 30))
        # add funcbutt to LeftPanel
        self.funcbutt.setFixedSize(61, 31)
        self.funcbutt.move(39, self.hight - 43)
        # connect menu event

    def setpic(self, user_id):
        """ set pic to the path image"""
        pixmap = QPixmap("../resources/pictures/" + user_id)
        # when path not found
        if (pixmap.isNull()):
            pixmap = QPixmap(self.unknownUser)
        # scaled and set
        pixmap.scaled(60, 60, Qt.KeepAspectRatio)
        self.pic.setPixmap(pixmap)

    def setFuncMenu(self, login):
        if login:
            self.mu.clear()
            self.mu.addAction(self.grandStat)
            self.mu.addAction(self.personalInfo)
            self.mu.addAction(self.out)
        else:
            self.mu.clear()
            self.mu.addAction(self.grandStat)
コード例 #5
0
class WireSharp(FramelessWindow):
    """ WireSharp 聊天界面 """

    BORDER_WIDTH = 5

    def __init__(self):
        super().__init__()
        self.__getContactInfo()
        self.userInfo = getUserInfo()
        # 实例化小部件
        t1 = time()
        print('🤖 正在初始化界面...')
        self.stackedWidget = QStackedWidget(self)
        self.dialogInterface = DialogInterface(self)
        self.welcomeInterface = WelcomeInterface(self)
        self.navigationInterface = NavigationInterface(self.contactInfo_list,
                                                       self)
        print(f'✅ 完成界面的初始化,耗时{time()-t1:.2f}s')
        # 创建线程
        self.publishThread = PublishThread(self)
        self.wiresharkThread = WiresharkThread(self)
        self.arpAttackThread = ArpAttackThread(self)
        # 引用子窗口
        self.chatListWidget = self.navigationInterface.chatListWidget
        self.contactInterface = self.navigationInterface.contactInterface
        # 初始化界面
        self.__initWidget()

    def __initWidget(self):
        """ 初始化界面 """
        self.setWindowTitle('Wiresharp')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setWindowIcon(QIcon(r'app\resource\Image\icon\icon.png'))
        self.setAttribute(Qt.WA_TranslucentBackground | Qt.WA_StyledBackground)
        # 调整窗口大小和小部件位置
        self.navigationInterface.move(0, 40)
        self.stackedWidget.move(403, 40)
        self.resize(1279, 957)
        # 将窗口添加到层叠窗口中
        self.stackedWidget.addWidget(self.welcomeInterface)
        self.stackedWidget.addWidget(self.dialogInterface)
        # 在去除任务栏的显示区域居中显示
        desktop = QApplication.desktop().availableGeometry()
        self.move(int(desktop.width() / 2 - self.width() / 2),
                  int(desktop.height() / 2 - self.height() / 2))
        # 信号连接到槽函数
        self.__connectSignalToSlot()

    def __getContactInfo(self) -> list:
        """ 获取联系人信息 """
        print('🌍 正在获取局域网内的主机...')
        t1 = time()
        host_list = getHost()
        print(f'✅ 完成局域网内主机的获取,耗时{time()-t1:.2f}s')
        self.contactInfo_list = []
        self.headPortraitPath_list = [
            r'app\resource\Image\head_portrait\硝子(1).png',
            r'app\resource\Image\head_portrait\硝子(2).png',
            r'app\resource\Image\head_portrait\硝子(3).jpg',
        ]
        for i, (hostName, IP) in enumerate(host_list):
            self.contactInfo_list.append({
                'IP':
                IP,
                'contactName':
                hostName,
                'headPortraitPath':
                self.headPortraitPath_list[i % len(self.headPortraitPath_list)]
            })

    def resizeEvent(self, e):
        """ 调整窗口大小 """
        super().resizeEvent(e)
        self.stackedWidget.resize(self.width() - 402, self.height() - 40)
        if hasattr(self, 'navigationInterface'):
            self.navigationInterface.resize(self.navigationInterface.width(),
                                            self.height() - 40)

    def __connectSignalToSlot(self):
        """ 将信号连接到槽函数 """
        # 欢迎界面信号连接到槽函数
        self.welcomeInterface.changeUserInfoSignal.connect(
            self.__changeUserInfoSlot)
        self.welcomeInterface.startConvButton.clicked.connect(
            self.navigationInterface.switchToContactInterface)
        # todo:联系人界面信号连接到槽函数
        self.contactInterface.selectContactSignal.connect(
            self.__selectContactSlot)
        self.chatListWidget.currentChatChanged.connect(
            self.__currentChatChangedSlot)
        self.chatListWidget.deleteChatSignal.connect(self.__deleteChatSlot)
        # todo:会话界面信号连接到槽函数
        self.dialogInterface.sendMessageSignal.connect(self.__newMessageSlot)
        self.dialogInterface.recvMessageSignal.connect(self.__newMessageSlot)
        self.dialogInterface.publishSignal.connect(self.__publishSlot)
        self.dialogInterface.startWiresharkSignal.connect(
            self.__startWiresharpSlot)
        self.dialogInterface.stopWiresharkSignal.connect(
            self.__stopWiresharpSlot)
        self.dialogInterface.startArpAttackSignal.connect(
            self.__startArpAttackSlot)
        self.dialogInterface.stopArpAttackSignal.connect(
            self.__stopArpAttackSlot)
        # todo:线程信号连接到槽函数
        self.wiresharkThread.catchPacketSignal.connect(self.__catchPacketSlot)
        self.wiresharkThread.wiresharkStateChangedSignal.connect(
            self.__wiresharpStateChangedSlot)
        self.arpAttackThread.arpAttackStateChangedSignal.connect(
            self.__arpAttackStateChangedSlot)
        self.publishThread.publishStateChangedSignal.connect(
            self.__publishStateChangedSlot)

    def __changeUserInfoSlot(self):
        """ 更新用户信息 """
        self.userInfo = getUserInfo()
        self.navigationInterface.updateUserInfo(self.userInfo)

    def __selectContactSlot(self, contactInfo: dict):
        """ 选中联系人时显示对话窗口 """
        # 如果选中的IP不在聊天列表已有的聊天用户中,就新建一个对话窗口
        IP = contactInfo['IP']
        if IP not in list(self.chatListWidget.IPContactName_dict.keys()) \
                + list(self.dialogInterface.IPIndex_dict.keys()):
            self.dialogInterface.addDialog(contactInfo)
        else:
            self.dialogInterface.setCurrentDialogByIP(IP)
        # 将当前窗口设置为对话界面
        self.stackedWidget.setCurrentWidget(self.dialogInterface)

    def __currentChatChangedSlot(self, IP: str):
        """ 当前选中的聊天框改变对应的槽函数 """
        self.dialogInterface.setCurrentDialogByIP(IP)
        self.stackedWidget.setCurrentWidget(self.dialogInterface)

    def __newMessageSlot(self, messageInfo: dict):
        """ 发送/接收 对话消息的槽函数 """
        IP = messageInfo['IP']
        # 如果对话框中没有当前的联系人对话记录,就创建一个新的聊天框,否则更新聊天框
        if IP not in self.chatListWidget.IPContactName_dict.keys():
            self.chatListWidget.addChatWidget(messageInfo)
        else:
            chatWidget, i = self.chatListWidget.findChatListWidgetByIP(
                IP, True)
            self.chatListWidget.setCurrentItem(
                self.chatListWidget.item_list[i])
            chatWidget.updateWindow(messageInfo)

    def __deleteChatSlot(self, IP: str):
        """ 删除对话框槽函数 """
        self.stackedWidget.setCurrentWidget(self.welcomeInterface)
        self.dialogInterface.removeDialog(IP)

    def __startWiresharpSlot(self, IP: str):
        """ 开始抓包 """
        self.arpAttackThread.stopArpAttack()
        self.arpAttackThread.startArpAttack(IP)
        self.wiresharkThread.startWireshark()

    def __stopWiresharpSlot(self):
        """ 停止抓包 """
        self.wiresharkThread.stopWireshark()
        self.arpAttackThread.stopArpAttack()

    def __catchPacketSlot(self, packetInfo: dict):
        """ 抓到包的槽函数 """
        self.arpAttackThread.stopArpAttack()
        self.dialogInterface.isArpAttack = False
        self.dialogInterface.isCatchingPacket = False
        # 将数据包保存到本地
        writeCatchPacket(packetInfo, 'app\\data\\catch_packet.json')
        with open(r'app\resource\html\send_file.html', encoding='utf-8') as f:
            self.__sendMessage(f.read())

    def __startArpAttackSlot(self, IP: str):
        """ 开始 ARP 欺骗槽函数(发送错误 MAC 地址) """
        self.arpAttackThread.startArpAttack(IP, False)

    def __stopArpAttackSlot(self):
        """ 开始 ARP 欺骗槽函数 """
        self.arpAttackThread.stopArpAttack()

    def __publishSlot(self):
        """ 发布消息槽函数 """
        packetInfo = readCatchPacket('app\\data\\catch_packet.json')
        if packetInfo:
            self.publishThread.publish(packetInfo['dst host'],
                                       packetInfo['topic'], packetInfo['msg'])
        else:
            self.__sendMessage('😋 当前没有抓到的包可供发布哦~')

    def __publishStateChangedSlot(self, message: str):
        """ 发布状态改变对应的槽函数 """
        self.__sendMessage(message)

    def __wiresharpStateChangedSlot(self, message: str):
        """ 显示 Wiresharp 线程发来的消息 """
        self.__sendMessage(message)

    def __arpAttackStateChangedSlot(self, message: str):
        """ 显示 ARP 攻击线程发来的消息 """
        self.__sendMessage(message)

    def __sendMessage(self, message: str):
        """ 作为contact发送消息 """
        messageInfo = deepcopy(self.dialogInterface.currentContactInfo)
        messageInfo['message'] = message
        messageInfo['time'] = QTime.currentTime().toString('H:mm')
        self.dialogInterface.receiveMessageSlot(messageInfo)
コード例 #6
0
ファイル: tomarFoto.py プロジェクト: ykv001/PyQt5
class Widgets(QWidget):
    def __init__(self, dispositivoCamara, parent=None):
        super(Widgets, self).__init__(parent)

        self.parent = parent

        self.estadoFoto = False
        self.byteArrayFoto = QByteArray()

        # ==========================================================

        frame = QFrame(self)
        frame.setFrameShape(QFrame.Box)
        frame.setFrameShadow(QFrame.Sunken)
        frame.setFixedWidth(505)
        frame.setFixedHeight(380)
        frame.move(10, 10)

        # Instancias
        self.paginaVisor = QVideoWidget()
        self.paginaVisor.resize(500, 375)

        self.visor = QCameraViewfinder(self.paginaVisor)
        self.visor.resize(500, 375)

        self.labelFoto = QLabel()
        self.labelFoto.setAlignment(Qt.AlignCenter)
        self.labelFoto.resize(500, 375)

        # QStackedWidget
        self.stackedWidget = QStackedWidget(frame)
        self.stackedWidget.addWidget(self.paginaVisor)
        self.stackedWidget.addWidget(self.labelFoto)
        self.stackedWidget.resize(500, 375)
        self.stackedWidget.move(2, 2)

        # ======================== BOTONES =========================

        self.buttonTomarFoto = QPushButton("Tomar foto", self)
        self.buttonTomarFoto.resize(110, 26)
        self.buttonTomarFoto.move(525, 10)

        self.buttonEliminarFoto = QPushButton("Eliminar foto", self)
        self.buttonEliminarFoto.resize(110, 26)
        self.buttonEliminarFoto.move(525, 50)

        self.buttonGuardarFoto = QPushButton("Guardar foto", self)
        self.buttonGuardarFoto.resize(110, 26)
        self.buttonGuardarFoto.move(525, 82)

        # ======================== EVENTOS =========================

        self.buttonTomarFoto.clicked.connect(self.tomarFoto)
        self.buttonEliminarFoto.clicked.connect(self.eliminarFoto)
        self.buttonGuardarFoto.clicked.connect(self.guardarFoto)

        # ================== FUNCIONES AUTOMÁTICAS =================

        self.setCamara(dispositivoCamara)

# ======================= FUNCIONES ============================

    def setCamara(self, dispositivoCamara):
        if dispositivoCamara.isEmpty():
            self.camara = QCamera()
        else:
            self.camara = QCamera(dispositivoCamara)

        self.camara.stateChanged.connect(self.actualizarEstadoCamara)

        self.capturaImagen = QCameraImageCapture(self.camara)

        self.camara.setViewfinder(self.visor)

        self.actualizarEstadoCamara(self.camara.state())

        self.capturaImagen.imageCaptured.connect(self.procesarImagenCapturada)
        self.capturaImagen.imageSaved.connect(self.imagenGuardada)

        self.camara.isCaptureModeSupported(QCamera.CaptureStillImage)

        self.camara.start()

        self.paginaVisor.update()

    def actualizarDispositivoCamara(self, action):
        self.setCamara(action.data())

    def actualizarEstadoCamara(self, estado):
        if estado == QCamera.ActiveState:
            self.parent.accionIniciarCamara.setEnabled(False)
            self.parent.accionDetenerCamara.setEnabled(True)

            if not self.estadoFoto:
                self.buttonTomarFoto.setEnabled(True)
                self.buttonEliminarFoto.setEnabled(False)
                self.buttonGuardarFoto.setEnabled(False)
        elif estado in (QCamera.UnloadedState, QCamera.LoadedState):
            self.parent.accionIniciarCamara.setEnabled(True)
            self.parent.accionDetenerCamara.setEnabled(False)

            if not self.estadoFoto:
                self.buttonTomarFoto.setEnabled(False)
                self.buttonEliminarFoto.setEnabled(False)
                self.buttonGuardarFoto.setEnabled(False)

    def iniciarCamara(self):
        self.camara.start()

    def detenerCamara(self):
        self.camara.stop()

    def tomarFoto(self):
        rutaFoto = "{}/fotoTemporal.jpg".format(getcwd())
        self.capturaImagen.capture(rutaFoto)

        self.estadoFoto = True

    def procesarImagenCapturada(self, requestId, imagen):
        foto = QPixmap.fromImage(imagen)

        buffer = QBuffer(self.byteArrayFoto)
        buffer.open(QIODevice.WriteOnly)
        buffer.close()
        foto.save(buffer, "PNG")

        fotoEscalada = foto.scaled(self.labelFoto.size())

        self.labelFoto.setPixmap(fotoEscalada)
        self.mostrarImagenCapturada()

    def visualizarVisor(self):
        self.stackedWidget.setCurrentIndex(0)

    def mostrarImagenCapturada(self):
        self.stackedWidget.setCurrentIndex(1)

        self.buttonTomarFoto.setEnabled(False)
        self.buttonEliminarFoto.setEnabled(True)
        self.buttonGuardarFoto.setEnabled(True)

    def imagenGuardada(self, id, nombreFoto):
        if QFile.exists(nombreFoto):
            remove(nombreFoto)

    def eliminarFoto(self):
        self.estadoFoto = False
        self.byteArrayFoto.clear()

        self.labelFoto.clear()

        self.actualizarEstadoCamara(self.camara.state())
        self.visualizarVisor()

    def guardarFoto(self):
        guardarComo, extension = QFileDialog.getSaveFileName(
            self,
            "Guardar como",
            "Foto",
            "JPG (*.jpg);;PNG (*.png);;ICO (*.ico);;BMP (*.bmp)",
            options=QFileDialog.Options())

        if guardarComo:
            foto = QPixmap()
            foto.loadFromData(self.byteArrayFoto, "PNG", Qt.AutoColor)
            foto.save(guardarComo, quality=100)

            QMessageBox.information(
                self, "Guardar foto",
                "Foto guardada con éxito                                 ")

            self.eliminarFoto()