示例#1
0
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(600, 300)
        self.model = QDirModel(self)  # 1
        self.model.setReadOnly(False)
        self.model.setSorting(QDir.Name | QDir.IgnoreCase)

        self.tree = QTreeView(self)  # 2
        self.tree.setModel(self.model)
        self.tree.clicked.connect(self.show_info)
        self.index = self.model.index(QDir.currentPath())
        self.tree.expand(self.index)
        self.tree.scrollTo(self.index)

        self.info_label = QLabel(self)  # 3

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.tree)
        self.v_layout.addWidget(self.info_label)
        self.setLayout(self.v_layout)

    def show_info(self):  # 4
        index = self.tree.currentIndex()
        file_name = self.model.fileName(index)
        file_path = self.model.filePath(index)
        file_info = 'File Name: {}\nFile Path: {}'.format(file_name, file_path)
        self.info_label.setText(file_info)
示例#2
0
class MyCentralWidget(QWidget):
    def __init__(self, parent=None, flags=Qt.WindowFlags()):
        super().__init__(parent=parent, flags=flags)
        self.initUI()
        self.pix = ''

    def initUI(self):
        hbox = QHBoxLayout(self)

        self.lefttopframe = MyPixmap()
        # self.lefttopframe.frameWidth = 40
        self.lefttopframe.setMinimumWidth(150)
        self.lefttopframe.setFrameShape(QFrame.StyledPanel)
        # leftbottomframe = QFrame(self)
        self.dirmodel = QDirModel()
        qtree = QTreeView()
        qtree.setMaximumWidth(300)
        qtree.setModel(self.dirmodel)
        qtree.setRootIndex(
            self.dirmodel.index(QDir.currentPath() + '/mapeditor/Maps'))
        qtree.doubleClicked.connect(self.tree_clicked)

        # leftbottomframe.setFrameShape(QFrame.StyledPanel)
        splitter = QSplitter(Qt.Vertical)
        splitter.handleWidth = 20
        splitter.addWidget(self.lefttopframe)
        splitter.addWidget(qtree)

        self.rightframe = MyPixmap(self)
        # rightframe.set_tileset()
        self.rightframe.setFrameShape(QFrame.StyledPanel)
        splitter2 = QSplitter(Qt.Horizontal)
        splitter2.addWidget(splitter)
        splitter2.addWidget(self.rightframe)

        hbox.addWidget(splitter2)
        self.setLayout(hbox)

    def tree_clicked(self, idx):
        print(self.dirmodel.fileName(idx))
        self.rightframe.set_tileset(QDir.currentPath() + '/mapeditor/' +
                                    self.dirmodel.filePath(idx))

    def paintEvent(self, e):
        painter = QPainter(self)
        if self.pix != '':
            painter.drawPixmap(self.lefttopframe.rect(), self.pix)

    def set_tileset(self, path):
        # print ('set tileset %s' % path)
        self.path = path
        self.pix = QPixmap()
        self.pix.load(path)
class MyApp(QMainWindow):
    def __init__(self):
        super(MyApp, self).__init__()
        loadUi("ui/main_window.ui", self)
        self.setWindowTitle("Openpose GUI")
        self.setWindowIcon(QIcon('media/logo.png'))

        self.params = {
            # "net_resolution": "128x96",  # uncomment if cuda error
            "model_folder": "models/",
            "body": 1,
            "render_pose": 0,
            "render_threshold": 0.1,
            "hand": False,
            "hand_render": 1,
            "hand_render_threshold": 0.2,
            "face": False,
            "face_render": 1,
            "face_render_threshold": 0.4,
            "disable_blending": False  # black blackgroud if True
        }

        self.datum = op.Datum()
        self.op_wrapper = op.WrapperPython()
        self.tree_model = QDirModel()
        self.fourcc = cv2.VideoWriter_fourcc(*'XVID')
        self.cap = cv2.VideoCapture()

        self.save_window = SaveWindow()

        self.timer = QTimer()
        self.timer.timeout.connect(self.show_frame)

        self.out_path = "output"
        self.out_img_path = os.path.join(self.out_path, "{}/img")
        self.out_body_path = os.path.join(self.out_path, "{}/keypoint_body")
        self.out_hand_path = os.path.join(self.out_path, "{}/keypoint_hand")
        self.out_face_path = os.path.join(self.out_path, "{}/keypoint_face")

        self.webcam_open = False
        self.is_writing = False
        self.is_gesture_recognition = False
        self.timestamp = ""
        self.start_time = 0
        self.count = 0

        self.gesture_model = self.get_gesture_model(
            "models/gesture/[email protected]")
        self.idx_to_gesture = {
            0: 'eight',
            1: 'five',
            2: 'handssors',
            3: 'normal',
            4: 'ten'
        }
        # {'eight': 0, 'five': 1, 'handssors': 2, 'normal': 3}
        self.gesture_threshold = 0.57

        self.init_openpose()
        self.init_checkbox()
        self.init_pushbutton()
        self.init_radiobutton()
        self.init_slider()
        self.init_treeview()
        self.init_others()

    def init_openpose(self):
        self.op_wrapper.configure(self.params)
        self.op_wrapper.start()

    def init_checkbox(self):
        self.checkBox_body.setChecked(False)  # 默认设置为选中
        self.checkBox_hand.setChecked(False)  # 默认设置为选中
        self.checkBox_face.setChecked(False)  # 默认设置为选中
        self.checkBox_gesture.setChecked(False)  # 默认设置为选中
        self.checkBox_gesture.setEnabled(False)  # 默认设置为选中
        self.checkBox_body.stateChanged.connect(
            self.check_body)  # 状态改变触发check_box_changed函数
        self.checkBox_hand.stateChanged.connect(
            self.check_hand)  # 状态改变触发check_box_changed函数
        self.checkBox_face.stateChanged.connect(
            self.check_face)  # 状态改变触发check_box_changed函数
        self.checkBox_gesture.stateChanged.connect(self.check_gesture)

    def init_radiobutton(self):
        self.radioButton_black.setEnabled(False)
        self.radioButton_rgb.setEnabled(False)
        self.radioButton_black.setChecked(False)
        self.radioButton_rgb.setChecked(True)
        self.radioButton_black.toggled.connect(self.change_background)
        # self.radioButton_rgb.toggled.connect(self.changeBackground)

    def init_pushbutton(self):
        self.pushButton_webcam.clicked.connect(self.run_webcam)
        self.pushButton_folder.clicked.connect(self.change_folder)
        self.pushButton_save.clicked.connect(self.save_current)
        self.pushButton_record.clicked.connect(self.record_video)
        self.pushButton_record.setEnabled(False)

    def init_slider(self):
        self.horizontalSlider_Body.setEnabled(False)
        self.horizontalSlider_Hand.setEnabled(False)
        self.horizontalSlider_Face.setEnabled(False)
        self.horizontalSlider_Body.setMaximum(100)
        self.horizontalSlider_Body.setMinimum(0)
        self.horizontalSlider_Body.setValue(1)
        self.horizontalSlider_Hand.setMaximum(100)
        self.horizontalSlider_Hand.setMinimum(0)
        self.horizontalSlider_Hand.setValue(20)
        self.horizontalSlider_Face.setMaximum(100)
        self.horizontalSlider_Face.setMinimum(0)
        self.horizontalSlider_Face.setValue(40)
        self.label_threshold_body.setText(str(1))
        self.label_threshold_hand.setText(str(20))
        self.label_threshold_face.setText(str(40))
        self.horizontalSlider_Body.sliderReleased.connect(
            self.change_body_threshold)
        self.horizontalSlider_Face.sliderReleased.connect(
            self.change_face_threshold)
        self.horizontalSlider_Hand.sliderReleased.connect(
            self.change_hand_threshold)

    def init_treeview(self):
        # 目录树
        self.treeView_file.setModel(self.tree_model)
        self.treeView_file.setRootIndex(self.tree_model.index(os.getcwd()))
        self.treeView_file.show()
        self.treeView_file.doubleClicked.connect(self.tree_clicked)

    def init_others(self):
        # 图像显示标签
        self.label_frame.setScaledContents(True)

    def save_record_frame(self, img):
        cv2.imwrite(
            os.path.join(self.out_img_path.format(self.timestamp),
                         "{:0>4d}.jpg".format(self.count)), img)
        if self.checkBox_body.isChecked():
            body = os.path.join(self.out_body_path.format(self.timestamp),
                                "{:0>4d}_body.npy".format(self.count))
            np.save(body, self.datum.poseKeypoints)
        if self.checkBox_hand.isChecked():
            hand = os.path.join(self.out_hand_path.format(self.timestamp),
                                "{:0>4d}_hand.npy".format(self.count))
            np.save(hand, self.datum.handKeypoints)
        if self.checkBox_face.isChecked():
            face = os.path.join(self.out_face_path.format(self.timestamp),
                                "{:0>4d}_face.npy".format(self.count))
            np.save(face, self.datum.faceKeypoints)

    def show_frame(self):
        _, frame = self.cap.read()
        if frame is None:
            print("camera error")
            return

        img = self.process_image(frame)
        if self.is_writing:
            self.count += 1
            self.save_record_frame(img)  # 保存图片,关节点
            t = str(time.time() - self.start_time)[:4]
            cv2.putText(img, t, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1,
                        (255, 255, 255))

        if self.is_gesture_recognition:
            hand_keypoints = self.datum.handKeypoints
            # print(hand_keypoints)
            for hand in hand_keypoints:
                if hand.size == 1:
                    continue
                for i in range(hand.shape[0]):
                    if np.sum(hand[i, :, 2]) < 21 * 0.5:
                        continue
                    single_hand = hand[i, :, :2]
                    x, y, w, h = self.find_hand_bbox(single_hand)
                    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 255))
                    gesture = self.gesture_recognize(single_hand)  # 识别单个手
                    cv2.putText(img, gesture, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
                                1, (255, 255, 255))

        self.update_label(img)

    def find_hand_bbox(self, single_hand):
        n_points = single_hand.shape[0]
        points_list = []
        for i in range(n_points):
            if np.sum(single_hand[i, :]) != 0:
                points_list.append(single_hand[i, :])
        rect = cv2.boundingRect(np.array(points_list))
        return rect

    def gesture_recognize(self, hand):
        hand[:, 0] /= 640
        hand[:, 1] /= 480
        hand = ToTensor()(hand)
        if torch.cuda.is_available():
            hand = hand.cuda()
        hand = hand.view(1, -1)
        out = self.gesture_model(hand)
        out = F.softmax(out, 1)
        value, index = torch.max(out, 1)
        if value.item() > self.gesture_threshold:
            print(self.idx_to_gesture[index.item()], value.item())
            return self.idx_to_gesture[index.item()]
        else:
            return None

    def tree_clicked(self, file_index):
        file_name = self.tree_model.filePath(file_index)
        if file_name.endswith(('.jpg', '.png')):
            if self.webcam_open:
                QMessageBox.information(self, "Note",
                                        "Please stop webcam first",
                                        QMessageBox.Yes)
                return
            img = cv2.imdecode(np.fromfile(file_name, dtype=np.uint8),
                               cv2.IMREAD_COLOR)  # -1表示cv2.IMREAD_UNCHANGED
            result = self.process_image(img)
            self.update_label(result)

    def update_label(self, frame):
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # bgr -> rgb
        h, w, c = frame.shape  # 获取图片形状
        image = QImage(frame, w, h, 3 * w, QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(image)
        self.label_frame.setPixmap(pixmap)

    def process_image(self, img):
        self.datum.cvInputData = img
        self.op_wrapper.emplaceAndPop([self.datum])
        result = self.datum.cvOutputData
        return result

    def change_background(self):
        if self.radioButton_black.isChecked():
            self.params['disable_blending'] = True
        else:
            self.params['disable_blending'] = False
        self.update_wrapper()

    def change_folder(self):
        folder_name = QFileDialog.getExistingDirectory(self, '标题',
                                                       './')  # 可设置默认路径
        if folder_name:
            self.treeView_file.setRootIndex(self.tree_model.index(folder_name))
            self.treeView_file.show()

    def save_current(self):
        pixmap = self.label_frame.pixmap()
        if not pixmap:
            QMessageBox.warning(self, "Note", "No data in frame",
                                QMessageBox.Yes)
            return
        body_keypoint = copy.deepcopy(
            self.datum.poseKeypoints) if self.checkBox_body.isChecked(
            ) else None
        hand_keypoint = copy.deepcopy(
            self.datum.handKeypoints) if self.checkBox_hand.isChecked(
            ) else None
        face_keypoint = copy.deepcopy(
            self.datum.faceKeypoints) if self.checkBox_face.isChecked(
            ) else None
        self.save_window.setFrame(pixmap.copy(), body_keypoint, hand_keypoint,
                                  face_keypoint)
        self.save_window.show()

    def record_video(self):
        if not self.cap.isOpened():
            QMessageBox.warning(self, "Note", "Please open webcam first",
                                QMessageBox.Yes)
            return

        if not self.is_writing:
            # 启动录制
            self.pushButton_webcam.setEnabled(False)
            self.pushButton_save.setEnabled(False)
            self.pushButton_folder.setEnabled(False)
            self.pushButton_record.setText("Stop Record")
            self.is_writing = True
            self.timestamp = str(int(time.time()))
            self.start_time = time.time()
            # 初始化路径
            if not os.path.exists(self.out_img_path.format(self.timestamp)):
                os.makedirs(self.out_img_path.format(self.timestamp))
            if not os.path.exists(self.out_body_path.format(self.timestamp)):
                os.makedirs(self.out_body_path.format(self.timestamp))
            if not os.path.exists(self.out_hand_path.format(self.timestamp)):
                os.makedirs(self.out_hand_path.format(self.timestamp))
            if not os.path.exists(self.out_face_path.format(self.timestamp)):
                os.makedirs(self.out_face_path.format(self.timestamp))
        else:
            # 停止录制
            self.pushButton_webcam.setEnabled(True)
            self.pushButton_save.setEnabled(True)
            self.pushButton_folder.setEnabled(True)
            self.pushButton_record.setText("Begin Record")
            self.is_writing = False

            QMessageBox.information(self, "Note",
                                    "Saving in {}".format(self.out_path),
                                    QMessageBox.Yes)
            self.timestamp = ""
            self.start_time = 0
            self.count = 0

    def run_webcam(self):
        if self.webcam_open:
            self.webcam_open = False
            self.cap.release()
            self.label_frame.clear()
            self.timer.stop()
            self.pushButton_webcam.setText("Open Webcam")
            self.pushButton_record.setEnabled(False)
        else:
            self.webcam_open = True
            self.cap.open(0)
            self.timer.start(20)
            self.pushButton_webcam.setText("Stop Webcam")
            self.pushButton_record.setEnabled(True)

    def check_body(self, status):
        flag = True if status == Qt.Checked else False
        render_pose = 1 if status == Qt.Checked else 0
        self.horizontalSlider_Body.setEnabled(flag)
        self.radioButton_black.setEnabled(flag)
        self.radioButton_rgb.setEnabled(flag)
        self.params["render_pose"] = render_pose
        self.update_wrapper()

    def check_hand(self, status):
        flag = True if status == Qt.Checked else False
        self.horizontalSlider_Hand.setEnabled(flag)
        self.checkBox_gesture.setEnabled(flag)
        self.params["hand"] = flag
        self.update_wrapper()

    def check_face(self, status):
        flag = True if status == Qt.Checked else False
        self.horizontalSlider_Face.setEnabled(flag)
        self.params["face"] = flag
        self.update_wrapper()

    def check_gesture(self, status):
        flag = True if status == Qt.Checked else False
        self.is_gesture_recognition = flag

    def change_body_threshold(self):
        value = self.horizontalSlider_Body.value()
        print(value)
        self.params["render_threshold"] = value / 100
        self.label_threshold_body.setText(str(value))
        self.update_wrapper()

    def change_hand_threshold(self):
        value = self.horizontalSlider_Hand.value()
        print(value)
        self.params["hand_render_threshold"] = value / 100
        self.label_threshold_hand.setText(str(value))
        self.update_wrapper()

    def change_face_threshold(self):
        value = self.horizontalSlider_Face.value()
        print(value)
        self.params["face_render_threshold"] = value / 100
        self.label_threshold_face.setText(str(value))
        self.update_wrapper()

    def update_wrapper(self):
        self.op_wrapper.configure(self.params)
        self.op_wrapper.start()

    @staticmethod
    def get_gesture_model(weights_path):
        model = Model(42, 32, 5)
        if torch.cuda.is_available():
            model.load_state_dict(torch.load(weights_path))
            model = model.cuda()
        else:
            model.load_state_dict(
                torch.load(weights_path,
                           map_location=lambda storage, loc: storage))
        model.eval()
        return model
示例#4
0
class MyMainWindow(QWidget, Ui_Form):
    def __init__(self, proPath, parent=None):
        super(MyMainWindow, self).__init__(parent)
        # self.setCentralWidget(self.widget)
        self.proPath = proPath
        #************** 初始化窗口
        self.setupUi(self)
        # 设置窗口的标题
        self.setWindowTitle('ftpFilesys')
        # 设置窗口的图标,引用当前目录下的web.png图片
        self.setWindowIcon(QIcon(self.proPath + '/Icon/LOGO.jpg'))
        self.setSignal()
        self.downing = True
        #************** 初始化按键
        # self.Bt_down.setEnabled(False)
        self.Bt_up.setEnabled(False)
        # 创建SSH对象
        self.ssh = paramiko.SSHClient()
        # 允许连接不在know_hosts文件中的主机,否则可能报错:paramiko.ssh_exception.SSHException: Server '192.168.43.140' not found in known_hosts
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ftp_root = "/home/sd/ftp/biaodingCloud"

        #************** 初始化变量
        """FTP窗口"""
        self.ftp = myFTP()  # 实例化FTP
        self.ftp.encoding = "utf-8"
        self.select_file = ""  # listView中选择的文件名
        self.file_list = []  # 存放查询FTP返回的当前目录所有文件列表
        self.ftp_tip = []  #存储当前登陆信息
        """本地窗口"""
        # self.sysfile = QFileSystemModel() # 获取本地文件系统
        # self.sysfile.setRootPath('')
        # self.treeView_local.setModel(self.sysfile)
        self.model = QDirModel()
        self.model.setFilter(QtCore.QDir.Dirs | QtCore.QDir.NoDotAndDotDot)
        self.treeView_local.header().hide()  # 隐藏表头
        self.treeView_local.setModel(self.model)
        for col in range(1, 4):
            self.treeView_local.setColumnHidden(col, True)

        self.save_path = ""
        # self.treeView_local.setRootIndex(self.model.index(self.save_path))
        self.save_name = ""

        self.lineEdit_ip.setText("192.168.200.11")
        self.lineEdit_port.setText("21")
        self.lineEdit_user.setText("admin")
        self.lineEdit_pwd.setText("123")

    # 信号绑定设置
    def setSignal(self):
        self.Bt_link.clicked.connect(self.ftp_connect)
        self.Bt_down.clicked.connect(self.Bt_down_run)
        # self.Bt_up.clicked.connect(self.ftp_connect)
        # 任意输入框改变就可以重新使能连接按键
        self.lineEdit_ip.editingFinished.connect(self.BtEnabled)
        self.lineEdit_port.editingFinished.connect(self.BtEnabled)
        self.lineEdit_user.editingFinished.connect(self.BtEnabled)
        self.lineEdit_pwd.editingFinished.connect(self.BtEnabled)
        self.treeWidget_master.itemClicked.connect(self.select_item_ftp)
        # self.treeView_local.doubleClicked.connect(self.select_item_local)
        self.treeView_local.expanded.connect(self.select_item_local)
        self.treeView_local.clicked.connect(self.select_item_local)
        # self.treeWidget_master.doubleClicked.connect(self.cd_button)

    # 按键使能
    def BtEnabled(self):
        self.Bt_link.setEnabled(True)
        self.Bt_down.setEnabled(False)
        self.Bt_up.setEnabled(False)

    # ftp 连接登录
    def ftp_connect(self):
        self.Text_log.append("linking...")
        self.treeWidget_master.clear()
        host = self.lineEdit_ip.text()  # 获取IP地址框内容
        port = int(self.lineEdit_port.text())  # 获取端口号,注意要转换为int
        usr = self.lineEdit_user.text()  # 获取用户名
        pwd = self.lineEdit_pwd.text()  # 获取密码
        self.ftp_tip.append(host)
        self.ftp_tip.append(port)
        self.ftp_tip.append(usr)
        self.ftp_tip.append(pwd)

        try:
            self.ftp.connect(host, port, timeout=10)  # 连接FTP
        except:
            logging.warning('network connect time out')  # 打印日志信息
            self.Text_log.append("network connect time out")
        try:
            self.ftp.login(usr, pwd)  # 登录FTP
        except:
            logging.warning("username or password error")  # 打印日志信息
            self.Text_log.append("username or password error")

        self.file_list = self.ftp.nlst()  # 查询当前目录的所有文件列表
        self.Bt_link.setEnabled(False)

        self.root = QTreeWidgetItem(self.treeWidget_master)
        self.root.setText(0, '/')
        # print(self.setItemIcon('/'))
        self.root.setIcon(0, QIcon(self.setItem_Icon('/')))
        self.root.setToolTip(0, '/')
        # self.dirItem(self.file_list,self.root)
        self.dirItem(self.root)
        self.cursor = self.Text_log.textCursor()
        self.Text_log.moveCursor(self.cursor.End)
        self.Text_log.append("link success!")
        # 连接服务器
        result = self.ssh.connect(hostname=b'192.168.200.11',
                                  port=22,
                                  username=b'fs_001',
                                  password=b'123')
        self.Text_log.append(result)
        print("link success!")
        self.treeWidget_master.itemExpanded.connect(self.dirItem_new)
        # for col in range(len(self.file_list)):
        #     print(col)
        #     self.treeWidget_master.setColumnHidden(col, True)
        # print(self.ftp.dir('/DetectMask.zip'))

    # 判断数据类型,设置图标
    def setItem_Icon(self, obj):
        if "." in obj:  # 是文件则不能进入
            icon = self.proPath + "/Icon/file.png"
        else:  # 是文件夹则可以进入
            icon = self.proPath + "/Icon/folder.png"

        if ".jpg" in obj or ".jpeg" in obj or ".png" in obj:  # 是文件则不能进入
            icon = self.proPath + "/Icon/file_img.png"
        elif ".zip" in obj or ".rar" in obj or ".7z" in obj:
            icon = self.proPath + "/Icon/file_zip.png"

        elif ".xls" in obj or ".xlsx" in obj:
            icon = self.proPath + "/Icon/file_excel.png"
        elif ".ppt" in obj or "pptx" in obj:
            icon = self.proPath + "/Icon/file_ppt.png"
        elif ".doc" in obj or ".docx" in obj or ".7z" in obj:
            icon = self.proPath + "/Icon/file_word.png"
        elif ".pdf" in obj:
            icon = self.proPath + "/Icon/file_pdf.png"
        elif ".py" in obj:
            icon = self.proPath + "/Icon/file_python.png"
        return icon

    # 递归操作,遍历ftp服务器所有文件
    def dirItem(self, item):
        # print(item.toolTip((0)))
        list = self.ftp.nlst(str(item.toolTip(0)))
        # for name1 in list:
        #     print("      ",name1)
        #self.showMessage("加载... ", QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
        for i, path in enumerate(list):
            name = path.split('/')[-1]
            child = QTreeWidgetItem(item)
            item.addChild(child)
            child.setIcon(0, QIcon(self.setItem_Icon(name)))
            child.setText(0, name)
            # print(self.ftp.pwd())
            child.setToolTip(0, path)
            # print(child.toolTip(0))
            # print(this,name)

    # 动态加载dirItem
    def dirItem_new(self, item):
        # print(item.toolTip((0)))
        # list=self.ftp.nlst(str(item.toolTip(0)))
        child_num = item.childCount()
        for i in range(child_num):
            cc_num = item.child(i).childCount()
            item.child(i).setExpanded(False)
            if cc_num >= 0:
                for j in range(cc_num):
                    item.child(i).removeChild(item.child(i).child(j))
            if self.checkFileDir(self.ftp, item.child(i).toolTip(0)) == "dir":
                self.dirItem(item.child(i))

        # time.sleep(10)

    """递归操作,耗费资源+加载时间久,放弃"""

    # 递归操作,遍历ftp服务器所有文件
    # def dirItem(self,list,item):
    #     # list=self.ftp.nlst(str(item.toolTip(0)))
    #     # self.showMessage("加载... ", QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
    #     for i,name in enumerate(list):
    #         child = QTreeWidgetItem(item)
    #         item.addChild(child)
    #         child.setIcon(0,QIcon(self.setItem_Icon(name)))
    #         child.setText(0,name)
    #         child.setToolTip(0,self.ftp.pwd())
    #         # print(child.toolTip(0))
    #         # print(this,name)
    #         this = self.checkFileDir(self.ftp, name)
    #         if this == "dir":
    #             # print(self.ftp.pwd(), name)
    #             self.ftp.cwd(name)
    #             filelist=self.ftp.nlst()
    #             # for name1 in filelist:
    #             #     print("      ",name1)
    #             self.dirItem(filelist,child)
    #             self.ftp.cwd("..")

    # 判断是否为文件

    def checkFileDir(self, ftp, file_name):
        """
        判断当前目录下的文件与文件夹
        :param ftp: 实例化的FTP对象
        :param file_name: 文件名/文件夹名
        :return:返回字符串“File”为文件,“Dir”问文件夹,“Unknow”为无法识别
        """
        rec = ""
        try:
            rec = ftp.cwd(file_name)  # 需要判断的元素

            ftp.cwd("..")  # 如果能通过路径打开必为文件夹,在此返回上一级
        except ftplib.error_perm as fe:
            rec = fe  # 不能通过路劲打开必为文件,抓取其错误信息

        finally:
            # print(file_name,rec)
            if "550" in str(rec)[:3]:
                return "file"
            elif "250" in str(rec)[:3]:
                return "dir"
            else:
                return "unknow"

    # 单击选中,使能下载按键
    def select_item_ftp(self, item):
        # print(item.text(0),item.columnCount())
        self.select_item = item
        self.select_file = item.toolTip(0)
        # print(self.select_file)
        if '.' in self.select_file:  # 如果是文件,则可下载
            self.Bt_down.setEnabled(True)
        else:  # 否则是文件夹,不能下载
            self.Bt_down.setEnabled(False)

    # 选择文件保存目录
    def select_item_local(self, obj):
        self.save_path = self.model.filePath(obj)

    # 更新主窗口显示
    def handleDisplay(self, data):
        if "ERROR" in data:
            self.Text_log.append(data)
            self.Bt_link.setEnabled(True)

        else:
            self.cursor = self.Text_log.textCursor()
            self.cursor.select(QTextCursor.LineUnderCursor)
            self.cursor.removeSelectedText()
            # self.Text_log.moveCursor(QtGui.QTextCursor.StartOfLine, QtGui.QTextCursor.MoveAnchor)
            self.Text_log.insertPlainText(data)
            if data == "100%":
                self.downing = True
                self.Text_log.append("Download Success!")
                self.thread.quit()
                # 执行命令
                # stdin:标准输入(就是你输入的命令);stdout:标准输出(就是命令执行结果);stderr:标准错误(命令执行过程中如果出错了就把错误打到这里),stdout和stderr仅会输出一个
                self.mv_file()
                self.Bt_down.setEnabled(False)

    # 移动文件
    def mv_file(self):
        old_file = False
        path, file = os.path.split(self.select_file)
        print(self.ftp_root + path + "/old_file/")
        # s = self.ftp.mkd(path + "/old_file/")
        stdin, stdout, stderr = self.ssh.exec_command(
            "mkdir  %s" % (self.ftp_root + path + "/old_file/"))

        stdin, stdout, stderr = self.ssh.exec_command(
            "mv %s  %s" % (self.ftp_root + self.select_file,
                           self.ftp_root + path + "/old_file/" + file))
        #
        # self.Text_log.append(str(stdout))
        parent = self.select_item.parent()

        print(parent.toolTip(0))
        parent.setExpanded(False)
        parent.removeChild(self.select_item)
        child_num = parent.childCount()
        for i in range(child_num):
            if self.checkFileDir(self.ftp,
                                 parent.child(i).toolTip(0)) == "dir":
                if parent.child(i).text(0) == "old_file":

                    old_file = True
        if old_file == False:

            item_name = "old_file"
            child = QTreeWidgetItem(parent)
            parent.addChild(child)
            child.setIcon(0, QIcon(self.setItem_Icon(item_name)))
            child.setText(0, item_name)
            # print(self.ftp.pwd())
            child.setToolTip(0, path + "/old_file")
        # else:
        # child_num = parent.childCount()
        # for i in range(child_num):
        #     parent.removeChild(parent.child(i))
        # self.dirItem(parent)

        parent.setExpanded(True)
        self.treeWidget_master.update()
        # self.select_item.setExpanded(True)

    # 下载晚间操作
    def Bt_down_run(self):

        if self.save_path == "":
            self.Text_log.append("未选择保存路径")
            self.downing = True
            reply = QMessageBox.warning(self, "警告", "未选择保存路径", QMessageBox.Ok)
            return

        if self.select_file == "":
            self.Text_log.append("未选择下载文件")
            self.downing = True
            reply = QMessageBox.warning(self, "警告", "未选择下载文件", QMessageBox.Ok)
            return

        if self.downing == False:
            reply = QMessageBox.warning(self, "警告", "正在下载,请等待。。。",
                                        QMessageBox.Ok)
            return
        self.downing = False
        self.save_name = self.save_path + "/%s" % self.select_file.split(
            '/')[-1]
        # print(self.select_file, self.save_name)
        self.Text_log.append("开始下载,\"%s\"将文件下载到\"%s\"" %
                             (self.select_file, self.save_name))
        if self.checkFileDir(self.ftp, self.select_file) == "dir":
            self.Text_log.append("这是文件夹,不能下载")
            return

        print(self.save_name)

        if os.path.exists(self.save_name):
            reply = QMessageBox.warning(self, "文件已存在", "是否覆盖?",
                                        QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:
                os.remove(self.save_name)
            else:
                self.downing = True
                return

        # 创建线程
        self.down = down_Thread(self.ftp_tip, self.select_file, self.save_name)
        # self.down = down_Thread(self)
        # thread = MyThread(target=self.tcp_run, args=(self.ftp_tip,self.select_file,self.save_name))
        # target = self.ftp.retrbinary, args = ("RETR %s" % self.select_file, open(self.save_name, 'wb').write)
        # 连接信号
        self.down.update_date.connect(self.handleDisplay)
        self.thread = QThread()
        self.Text_log.append("0%")
        self.down.moveToThread(self.thread)
        # 开始线程
        self.thread.started.connect(self.down.run)
        self.thread.start()
示例#5
0
class Notebook(QMainWindow, Ui_CodePlus):
    r"""
        Notebook 类
    """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.icon = QIcon()
        self.icon.addPixmap(QPixmap("./tianhou.ico"), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(self.icon)
        self.setupUi(self)
        """-------- System ---------"""
        self.local_system = platform.system()
        """-------- Short Cuts ---------"""
        self.actionSave.setShortcut(QKeySequence(QKeySequence.Save))
        self.actionUndo.setShortcut(QKeySequence(QKeySequence.Undo))
        self.actionRedo.setShortcut(QKeySequence(QKeySequence.Redo))
        self.actionNew.setShortcut(QKeySequence(QKeySequence.New))
        self.actionCopy.setShortcut(QKeySequence(QKeySequence.Copy))
        self.actionPaste.setShortcut(QKeySequence(QKeySequence.Paste))
        self.actionCut.setShortcut(QKeySequence(QKeySequence.Cut))
        self.actionFind.setShortcut(QKeySequence(QKeySequence.Find))
        self.actionSelect_All.setShortcut(QKeySequence(QKeySequence.SelectAll))
        """-------- Code ---------"""
        self.actionAbout_us.triggered.connect(self.aboutusEvent)  # 关于我们
        self.actionExit.triggered.connect(self.closeEvent)  # 退出
        self.actionPreference.triggered.connect(
            self.showpreferenceEvent)  # 偏好设置
        """-------- File ---------"""
        self.actionNew.triggered.connect(self.newfileEvent)  # 新建
        self.actionOpen_File.triggered.connect(self.openfileEvent)  # 打开文件
        self.actionOpen_Folder.triggered.connect(self.openfolderEvent)  # 打开文件夹
        self.actionSave.triggered.connect(self.savefileEvent)  # 保存文件
        self.actionSave_All.triggered.connect(self.saveallEvent)  # 全部保存
        self.actionSave_As.triggered.connect(self.saveasEvent)  # 另存为
        self.actionClose.triggered.connect(self.closefileEvent)  # 关闭
        self.tabWidget.tabCloseRequested.connect(self.closefileEvent)  # 关闭tab
        """-------- Edit ---------"""
        self.actionUndo.triggered.connect(self.text_undo)  # 撤销
        self.actionRedo.triggered.connect(self.text_redo)  # 重做
        self.actionCut.triggered.connect(self.text_cut)  # 剪切
        self.actionCopy.triggered.connect(self.text_copy)  # 复制
        self.actionPaste.triggered.connect(self.text_paste)  # 粘贴
        self.actionFind.triggered.connect(self.text_find)  # 查找
        self.win_find_is_show = False
        self.actionSelect_All.triggered.connect(self.text_selectAll)  # 全选
        """-------- Language ---------"""
        self.actionPlain_Text.triggered.connect(self.selectLanguage)
        self.actionC.triggered.connect(self.selectLanguage)
        self.actionMarkdown.triggered.connect(self.selectLanguage)
        self.actionPython.triggered.connect(self.selectLanguage)
        """-------- Whatever... ---------"""
        self.actionQR_Code.triggered.connect(self.rewardEvent)  # 打赏
        """-------- Status bar ---------"""
        self.lb_margin = QtWidgets.QLabel()
        self.lb_lang = QtWidgets.QLabel()
        self.statusbar.addWidget(self.lb_margin, 4)
        self.statusbar.addWidget(self.lb_lang, 1)
        """-------- Dir Tree ---------"""
        self.model = QDirModel()
        """ view from source"""
        """-------- Run Event ---------"""
        self.dock_win = QtWidgets.QDockWidget()
        self.dock_tab = QtWidgets.QTabWidget()
        self.dock_win.setWidget(self.dock_tab)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.dock_win)
        self.dock_tab.setTabPosition(QTabWidget.South)
        self.teridx = 0
        self.dock_win.setFeatures(QDockWidget.DockWidgetVerticalTitleBar)
        self.dock_tab.setTabsClosable(True)
        self.dock_tab.tabCloseRequested.connect(self.run_close_event)
        self.run_event = False
        self.actionStop.setDisabled(True)
        """-------- Basic Configs ---------"""
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.tabWidget.setAttribute(Qt.WA_DeleteOnClose, True)
        self.tabidx = 0
        self.font_content = None  # 字体和大小
        self.interpreter = None  # 解释器
        self.preference = Preference(par=self)
        self.tab_dict = {}  # 存放tab
        self.file_save_path = None  # 保存文件的路径
        self.language = 'txt'  # 当前语言
        """-------- Terminal ---------"""
        self.actionNew_Terminal.triggered.connect(self.new_terminal_event)
        # self.actionClose_Terminal.triggered.connect(self.close_terminal_event)
        """-------- Run ---------"""
        self.run_browser = RunBrowser(self.font_content)
        self.run_browser.startSignal.connect(self.run_start_event)
        self.run_browser.exitSignal.connect(self.run_exit_event)
        self.gcc = None
        self.actionRun.triggered.connect(self.new_run_event)
        self.actionStop.triggered.connect(self.stop_run)
        self.actionCompile.triggered.connect(self.compile_event)
        """--------tool------------"""
        self.actionWrite_Board.triggered.connect(self.OpenBoard)

        self.enableClickFlag = True  # 改变tab enable的flag
        """所有语言类型为:
            txt -> 文本文件
            md -> Markdown文件
            c -> C文件
            py -> Python文件
            """
        """-------- 初始执行的操作 ---------"""
        self.openIDEevent()

    def OpenBoard(self):
        textedit = self.__get_textEditor()
        self.boardwindow = PaintForm(textedit)
        self.boardwindow.show()

    def openIDEevent(self):
        tmp_path = '.tmp'

        def listdir(path):
            for item in os.listdir(path):
                if not item.startswith('.') and not item.endswith('.pkl'):
                    yield item

        if not os.path.exists(tmp_path) or not os.path.exists(
                os.path.join(tmp_path, 'mapping.pkl')):
            self.__create_tab()  # 初始创建一个tab
            self.tabWidget.currentChanged.connect(self.changeTab)  # 切换tab触发
        else:
            """读取缓存的文件"""
            with open(os.path.join(tmp_path, 'mapping.pkl'), 'rb') as f:
                mapping = pickle.load(f)
            tmp_files = listdir(tmp_path)
            for i, file in enumerate(tmp_files):

                file_path = os.path.join(tmp_path, file)
                if file.startswith('*'):
                    file = file[1:]
                origin_path = mapping[file]
                self.openfileEvent(file_path, origin_path)
                if i == 0:
                    self.tabWidget.currentChanged.connect(
                        self.changeTab)  # 切换tab触发

        self.lb_lang.setText(self.language)

    def stop_run(self):
        self.run_browser.process.close()

    def run_start_event(self):
        self.actionRun.setDisabled(True)
        self.actionStop.setDisabled(False)

    def run_exit_event(self):
        self.actionRun.setDisabled(False)
        self.actionStop.setDisabled(True)

    def new_run_event(self):
        if not self.run_event:
            pix = QPixmap('./imgs/run.jpg')
            icon = QIcon()
            icon.addPixmap(pix)
            self.dock_tab.addTab(self.run_browser, 'Run ')
            index = self.dock_tab.count() - 1
            self.dock_tab.setTabIcon(index, icon)
            self.dock_tab.setCurrentIndex(index)
            self.run_event = True
        cur_path = self.__get_textEditor().filepath
        if cur_path:
            if os.path.splitext(cur_path)[-1] == '.py':
                if not self.interpreter:
                    QMessageBox.warning(
                        self, '提示', '未设置有效的python解释器\n' + '->\n'.join([
                            'Code', 'Preference', 'Environment', 'interpreter'
                        ]))
                    return
                cmd = ' '.join([self.interpreter, cur_path])
                self.run_browser.start_process(cmd)
            elif os.path.splitext(cur_path)[-1] == '.c':
                cmd = os.path.splitext(cur_path)[0] + '.exe'
                if os.path.exists(cmd):
                    self.run_browser.process.start(cmd)
                else:
                    compile_cmd = 'gcc ' + cur_path
                    self.run_browser.process.start(compile_cmd)
                    self.run_browser.process.waitForFinished()
                    if os.path.exists(cmd):
                        self.run_browser.process.start(cmd)

    def compile_event(self):
        if not self.run_event:
            pix = QPixmap('./imgs/run.jpg')
            icon = QIcon()
            icon.addPixmap(pix)
            self.dock_tab.addTab(self.run_browser, 'Run ')
            index = self.dock_tab.count() - 1
            self.dock_tab.setTabIcon(index, icon)
            self.dock_tab.setCurrentIndex(index)
            self.run_event = True
        cur_path = self.__get_textEditor().filepath
        if cur_path:
            if os.path.splitext(cur_path)[-1] == '.c':
                cmd = 'gcc ' + cur_path
                self.run_browser.start_process(cmd)

    def run_close_event(self):
        if not self.actionRun.isEnabled():
            ref = QMessageBox.information(self, '提示', '还有项目正在运行\n确定退出?',
                                          QMessageBox.Yes | QMessageBox.No)
            if ref == QMessageBox.Yes:
                self.stop_run()
            else:
                return
        self.run_event = False
        self.dock_tab.removeTab(0)

    def new_terminal_event(self):
        if self.local_system == 'Windows':
            os.system('start cmd')
        elif self.local_system == 'Linux':
            os.system('gnome-terminal')
        elif self.local_system == 'Darwin':
            os.system('open -a Terminal .')

    def close_terminal_event(self):
        if self.local_system == 'Darwin':
            import appscript
            appscript.app('Terminal').do_script('exit')

    # def new_terminal_event(self):
    #     from threading import Thread
    #     t = Thread(target=self.aaa)
    #     t.start()
    #
    #     self.teridx += 1
    #     self.temp = QTextEdit()
    #     time.sleep(1)
    #     calc_hwnd = win32gui.FindWindow(None, u'C:\WINDOWS\system32\cmd.exe')
    #     print(calc_hwnd)
    #
    #     self.win = QWindow.fromWinId(calc_hwnd)
    #
    #     self.new_tab = self.createWindowContainer(self.win, self.temp)
    #     self.new_tab.showMaximized()
    #     # self.win.setKeyboardGrabEnabled(True)
    #     # self.win.setMouseGrabEnabled(True)

    # 查找
    def text_find(self):
        textedit = self.__get_textEditor()
        # if isinstance(textedit, QTextEdit):
        if not self.win_find_is_show:
            self.win_find_is_show = True
            self.find_win = Find_Win(self, textedit)
            self.find_win.show()

    def text_undo(self):
        textedit = self.__get_textEditor()
        # if isinstance(textedit, QTextEdit):
        textedit.undo()

    def text_redo(self):

        textedit = self.__get_textEditor()
        # if isinstance(textedit, QTextEdit):
        textedit.redo()

    def text_copy(self):
        textedit = self.__get_textEditor()
        # if isinstance(textedit, QTextEdit):
        textedit.copy()

    def text_paste(self):
        textedit = self.__get_textEditor()
        # if isinstance(textedit, QTextEdit):
        textedit.paste()

    def text_cut(self):
        textedit = self.__get_textEditor()
        # if isinstance(textedit, QTextEdit):
        textedit.cut()

    def text_selectAll(self):
        textedit = self.__get_textEditor()
        # if isinstance(textedit, QTextEdit):
        textedit.selectAll()

    def selectLanguage(self):
        r"""
            选择语言
        :return:
        """
        language_support = {
            'Plain Text': 'txt',
            'C': 'c',
            'Markdown': 'md',
            'Python': 'py'
        }
        textedit = self.__get_textEditor()
        signal_src = self.sender().text()
        language = language_support[signal_src]
        textedit.setlanguage(language)
        self.language = language
        self.lb_lang.setText(self.language)
        # if self.language == 'txt':
        #     self.actionPlain_Text.setDisabled(True)

        if signal_src == 'Markdown':
            self.markdown_handler()
        else:
            self.normalmode_handler()

    def changeTab(self):
        # super().tabWidget.changeEvent()
        self.language = self.cur_language()
        self.lb_lang.setText(self.language)
        cur_tabs = self.tabWidget.count()
        if cur_tabs == 0:
            self.actionCut.setDisabled(True)
            self.actionFind.setDisabled(True)
            self.actionSave.setDisabled(True)
            self.actionSave_All.setDisabled(True)
            self.actionSave_As.setDisabled(True)
            self.actionClose.setDisabled(True)
            self.actionUndo.setDisabled(True)
            self.actionRedo.setDisabled(True)
            self.actionCopy.setDisabled(True)
            self.actionPaste.setDisabled(True)
            self.actionSelect_All.setDisabled(True)
            self.actionC.setDisabled(True)
            self.actionPython.setDisabled(True)
            self.actionPlain_Text.setDisabled(True)
            self.actionMarkdown.setDisabled(True)
            self.actionRun.setDisabled(True)
            self.actionCompile.setDisabled(True)
            self.enableClickFlag = False
        else:
            if not self.enableClickFlag:
                self.enableClickFlag = True
                self.actionCut.setDisabled(False)
                self.actionFind.setDisabled(False)
                self.actionSave.setDisabled(False)
                self.actionSave_All.setDisabled(False)
                self.actionSave_As.setDisabled(False)
                self.actionClose.setDisabled(False)
                self.actionUndo.setDisabled(False)
                self.actionRedo.setDisabled(False)
                self.actionCopy.setDisabled(False)
                self.actionPaste.setDisabled(False)
                self.actionSelect_All.setDisabled(False)
                self.actionC.setDisabled(False)
                self.actionPython.setDisabled(False)
                self.actionPlain_Text.setDisabled(False)
                self.actionMarkdown.setDisabled(False)
                self.actionRun.setDisabled(False)
                self.actionCompile.setDisabled(False)

    def cur_language(self):
        if self.tabWidget.count() == 0:
            return ''
        language = self.__get_textEditor().language
        return language

    def __find_tab_by_index(self, index):
        r"""
            通过currentIndex获取字典中的
        :param index: CurrentIndex
        :return: (str, object) 当前Tab名,TabItem 对象
        """

        cur_tab_name = self.tabWidget.widget(index).objectName()
        return cur_tab_name, self.tab_dict[cur_tab_name]

    def __get_textEditor(self, index=None):
        r"""
            获取当前tab的textEditor
        :return: (object) textEditor
        """
        if index is None:
            index = self.tabWidget.currentIndex()
        _, tabitem = self.__find_tab_by_index(index)
        return tabitem.text

    def __get_tabitem(self, index=None):
        r"""
            获取当前tab
        :return: (object) tab
        """
        if index is None:
            index = self.tabWidget.currentIndex()
        _, tabitem = self.__find_tab_by_index(index)
        return tabitem

    def newfileEvent(self):
        r"""
            新建文件事件函数
        :return: None
        """
        self.__create_tab()

    def __create_tab(self, name=None):
        r"""
            新建tab
        :return: None
        """

        self.tabidx += 1
        newfile_name = f'New File {self.tabidx}' if name is None else name
        if name:
            _, language = os.path.splitext(name)
            language = language[1:]
        else:
            language = 'txt'
        new_tabname = 'tab_' + str(self.tabidx)
        tab_new = QWidget()
        tab_new.setObjectName(new_tabname)
        layout = QGridLayout(tab_new)
        layout.setObjectName(f'layout_of_{new_tabname}')
        # text_editor = TextEditorS(name=newfile_name, parent_tabWidget=self.tabWidget,
        #                           language=language, font_size=self.fontsize)
        # text_editor = Editor()
        text_editor = IDEeditor(name=newfile_name,
                                parent_tabWidget=self.tabWidget,
                                language=language,
                                font_content=self.font_content)
        text_editor.newFileSignal.connect(lambda: self.model.refresh())
        # text_editor.textChange.connect(self.__handle_textChange)

        layout.addWidget(text_editor, 0, 0, 1, 1)
        tabitem = TabItem(tab_new, layout, text_editor)
        self.tab_dict[new_tabname] = tabitem
        self.tabWidget.addTab(tab_new, newfile_name)
        # 跳转到新页面
        index = self.tabWidget.count() - 1
        self.tabWidget.setCurrentIndex(index)
        if language == 'md':
            self.markdown_handler()

    def openfileEvent(self, file_path=None, mapping=None):
        r"""
            打开文件事件函数
        :return: None
        """
        if not file_path:
            file_path, _ = QFileDialog.getOpenFileName(
                self, 'Choose a file', '/', 'All Files (*);;'
                'Text Files (*.txt);;'
                'Markdown Files (*.md);;'
                'C Sources (*.c);;'
                'Python Scripts (*.py)')
            if not file_path:
                return
        # 判断文件是否可读取
        if os.path.isdir(file_path):  # 屏蔽文件夹
            return
        if not os.path.splitext(file_path)[-1] in ['.py', '.c', '.txt', '.md']:
            QMessageBox.warning(self, u'警告', u'文件类型不支持!')
            return
        if len(file_path):
            _, file_fullname = os.path.split(file_path)

            for tabitem in self.tab_dict.values():
                tmp_edititem = tabitem.text
                if file_fullname == tmp_edititem.objectName():
                    index = self.tabWidget.indexOf(tabitem.tab)
                    self.tabWidget.setCurrentIndex(index)
                    return
            self.__create_tab(name=file_fullname)
            index = self.tabWidget.count() - 1
            textedit = self.__get_textEditor(index=index)
            textedit.load(file_path, mapping)

    def openfolderEvent(self):
        folder_path = QFileDialog.getExistingDirectory(self, '请选择打开的文件夹')
        if folder_path:
            self.dirtree.setModel(self.model)
            self.dirtree.setRootIndex(self.model.index(folder_path))
            self.dirtree.setAnimated(False)
            self.dirtree.setIndentation(20)
            self.dirtree.setSortingEnabled(True)
            self.dirtree.doubleClicked.connect(self.__choose_file)
            self.dirtree.setWindowTitle("Dir View")
            # self.dirtree.setHeaderHidden(True)

    def __choose_file(self, index):
        file_path = self.model.filePath(index)
        # print(file_path)
        self.openfileEvent(file_path)

    def saveasEvent(self):
        r"""
            另存为事件函数
        :return: None
        """
        textedit = self.__get_textEditor()
        status = textedit.saveas()
        if status:
            """保存成功,设置tab名"""
            index = self.tabWidget.currentIndex()
            textedit = self.__get_textEditor(index)
            self.language = textedit.language
            self.lb_lang.setText(self.language)

    def savefileEvent(self):
        r"""
            保存文件事件函数
        :return:
        """
        textedit = self.__get_textEditor()
        text_saveas = textedit.save()
        if text_saveas:
            self.language = textedit.language
            self.lb_lang.setText(self.language)

    def saveallEvent(self):
        r"""
            全部保存
        :return:
        """
        for tabitem in self.tab_dict.values():
            textedit = tabitem.text
            text_saveas = textedit.save()
            if text_saveas:
                self.language = textedit.language
                self.lb_lang.setText(self.language)

    def closefileEvent(self, index):
        r"""
            关闭文件事件函数
        :return: None
        """
        if self.tabWidget.count() == 0:
            self.close()
            return
        cur_tab_name, tabitem = self.__find_tab_by_index(index)
        textedit = tabitem.text
        # print(cur_tab_name)
        if textedit.isModified():
            """已修改文件,需要保存"""
            ret_code = QMessageBox.information(
                self, '提示', '文件尚未保存,确定退出?', QMessageBox.Yes | QMessageBox.No)
            # ret_code: Yes -- 16384
            #           No -- 65536
            if ret_code == QMessageBox.Yes:
                textedit.closeText()
                self.tabWidget.removeTab(index)
                del self.tab_dict[cur_tab_name]
        else:
            textedit.closeText()
            self.tabWidget.removeTab(index)
            del self.tab_dict[cur_tab_name]

    def setFontSizeEvent(self):
        r"""
            改变所有textedit的字体大小和样式
        :return:
        """
        for tabitem in self.tab_dict.values():
            textedit = tabitem.text
            textedit.setFontSize(self.font_content)
        self.run_browser.set_font(self.font_content)

    def rewardEvent(self):
        r"""
            打赏事件函数
        :return:
        """
        self.qrcode_window = Reward()
        self.qrcode_window.show()

    def showpreferenceEvent(self):
        r"""
            调出偏好设置
        :return:
        """
        self.preference.show()

    def aboutusEvent(self):
        r"""
            关于我们事件函数
        :return:
        """
        QMessageBox.information(
            self, 'About us', 'Monkey Editor v0.1\n'
            u'天猴工作室出品 \n'
            u'制作人:吴栋、廖满文、汪潇翔、文一晴、吴雨暄、张维天')

    def closeEvent(self, event):
        r"""
            关闭notebook事件函数
        :param event:
        :return: None
        """
        # 缓存文件的文件夹
        tmp_path = '.tmp'
        if os.path.exists(tmp_path):
            # os.system(f'rm -r {tmp_path}')
            shutil.rmtree(tmp_path)

        if len(self.tab_dict):
            os.mkdir(tmp_path)
        # check_quit = True
        increment = 1
        mapping = {}  # 地址映射表
        for tabitem in self.tab_dict.values():
            # 缓存当前未关闭的页面
            textedit = tabitem.text
            if textedit.filepath is None:
                tmp_filename = f'Plain_{increment}.' + self.language
                mapping[tmp_filename] = None
                tmp_filepath = os.path.join(tmp_path, tmp_filename)
                increment += 1
            else:
                _, tmp_filename = os.path.split(textedit.filepath)
                mapping[tmp_filename] = textedit.filepath
                tmp_filepath = os.path.join(tmp_path, tmp_filename)

            if textedit.isModified():
                # check_quit = False
                tmp_filepath = os.path.join(tmp_path, '*' + tmp_filename)
            textedit.save(tmp_filepath)

        # 保存mapping
        try:
            with open(os.path.join(tmp_path, 'mapping.pkl'), 'wb') as f:
                pickle.dump(mapping, f)
        except:
            pass

        # if not check_quit:
        #     ret_code = QMessageBox.information(self, '提示', '存在文件未保存,确定退出?',
        #                                            QMessageBox.Yes | QMessageBox.No)
        #     if ret_code == QMessageBox.Yes:
        #         self.close()
        #     else:
        #         event.ignore()
        # else:
        # 保存preference
        self.preference.close()
        self.close()

    def markdown_handler(self):
        index = self.tabWidget.currentIndex()
        _, tabitem = self.__find_tab_by_index(index)
        current_tab = tabitem.tab
        current_layout = tabitem.layout
        current_text = tabitem.text
        # content = current_text.text()
        # content.replace(r'\r\n', r'  \n')
        # content = ''
        # for i in range(linenum - 1):
        #     current_content = current_text.document().findBlockByLineNumber(i).text()
        #     current_content += '  \n'
        #     content += current_content
        # for i in reversed(range(current_layout.count())):
        #     current_layout.takeAt(i).widget().deleteLater()
        # markdown_tab = QtWidgets.QTabWidget(current_tab)
        # markdown_tab.setTabPosition(3)
        # orin = QWidget()
        # md = QWidget()
        # orin.setObjectName("orin")
        # md.setObjectName("md")
        # layout_orin = QGridLayout(orin)
        # text_editor_orin = TextEditorS(name='orin', parent_tabWidget=self.tabWidget, language=language)
        # layout_orin.addWidget(text_editor_orin, 0, 0, 1, 1)
        # layout_md = QGridLayout(md)
        # text_editor_txt = TextEditorS(name='md_txt', parent_tabWidget=self.tabWidget,
        #                         language='txt', font_content=self.font_content)
        text_browser_md = TextEditorS(name='md_show',
                                      parent_tabWidget=self.tabWidget,
                                      language='md')

        text_browser_md.setReadOnly(True)
        # text_editor_txt = TextEditorS(name='md_txt', parent_tabWidget=self.tabWidget, language='txt')
        # text_browser_md = TextEditorS(name='md_md', parent_tabWidget=self.tabWidget, language=self.language)
        # layout_md.addWidget(text_editor_txt, 0, 0, 1, 1)
        # layout_md.addWidget(text_browser_md, 0, 1, 1, 1)
        # markdown_tab.addTab(orin, 'orin')
        # markdown_tab.addTab(md, 'md')
        current_layout.addWidget(text_browser_md, 0, 1, 1, 1)
        # current_layout.addWidget(markdown_tab, 0, 0, 1, 1)
        tabitem = TabItem(current_tab, current_layout, current_text,
                          text_browser_md)
        now_tabname = 'tab_' + str(self.tabidx)
        self.tab_dict[now_tabname] = tabitem
        current_text.linesChanged.connect(self.show_markdown)
        # text_editor_txt.document().blockCountChanged.connect(self.show_markdown)
        # text_editor_txt.setPlainText(content)
        # text_editor_txt.document().blockCountChanged.connect(self.show_markdown)

    def normalmode_handler(self):
        index = self.tabWidget.currentIndex()
        _, tabitem = self.__find_tab_by_index(index)
        current_tab = tabitem.tab
        current_layout = tabitem.layout
        current_text = tabitem.text
        if tabitem.textview != None:
            current_layout.itemAt(1).widget().close()
            tabitem = TabItem(current_tab, current_layout, current_text)
            now_tabname = 'tab_' + str(self.tabidx)
            self.tab_dict[now_tabname] = tabitem

    def show_markdown(self):
        current_tab = self.__get_tabitem()
        textedit = current_tab.text
        textview = current_tab.textview
        if textview != None:
            content = textedit.text()
            content = content.replace('\r\n', '  \n')
            textview.document().setMarkdown(content)
        # linenum = textedit.document().lineCount()
        # content = ''
        # for i in range(linenum - 1):
        #     current_content = textedit.document().findBlockByLineNumber(i).text()
        #     current_content += '  \n'
        #     content += current_content
    def windowShow(self):
        youWin.show()  #你的主页程序