Beispiel #1
0
    def paintEvent(self, event):
        if self._flag_1:
            qp = QPainter()
            qp.begin(self)

            qp.setBrush(QColor(255, 237,
                               0))  # задаем желтый цвет для рамки выбора
            qp.drawRect(self._col * 40 + 15, self._activ_pic * 50, 50,
                        50)  # задаем положение и размер рамки выбора

            for i in range(self._col):
                for j in range(self._row):
                    qp.setBrush(QColor(50, 50, 50))
                    qp.drawRect(i * 40, j * 40, 40, 40)
                    qp.drawPixmap(i * 40, j * 40, self._elem_map[
                        self._sp_map[j][i]])  # рисуем картинками из elem_map

            for i in range(PIC):
                qp.drawPixmap(self._col * 40 + 20, i * 50 + 5,
                              self._elem_map[i])

            if self._mouse_x < self._col * 40 and self._mouse_y < self._row * 40:
                qp.drawPixmap(self._mouse_x - 30, self._mouse_y - 30,
                              self._elem_map[self._activ_pic])
            qp.end()
Beispiel #2
0
 def paintEvent(self, e):
     if self.img:
         painter = QPainter()
         painter.begin(self)
         painter.scale(self.scale, self.scale)
         painter.drawPixmap(self.point, self.img)
         painter.end()
Beispiel #3
0
    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        painter.setPen(Qt.QPen(Qt.QColor('#3d3c3c')))
        painter.setFont(QFont("MS Shell Dlg 2", 16))

        if self.move_mode_open:
            painter.fillRect(Qt.QRectF(0, 0, 1280, 80), Qt.QColor('#d6ffdd'))
        else:
            painter.fillRect(Qt.QRectF(0, 0, 1280, 80), QtCore.Qt.white)

        if self.alarm or self.inform:
            self.alarm_button.resize(640, 560)
            self.alarm_button.move(0, 160)
            self.inform_button.resize(640, 560)
            self.inform_button.move(640, 160)
        else:
            self.alarm_button.resize(640, 640)
            self.alarm_button.move(0, 80)
            self.inform_button.resize(640, 640)
            self.inform_button.move(640, 80)

        if self.alarm:
            painter.fillRect(Qt.QRectF(0, 80, 1280, 80), Qt.QColor('#ffbfbc'))
            painter.drawText(Qt.QRectF(0, 80, 1280, 80), QtCore.Qt.AlignCenter,
                             'opiekun jest alarmowany')
        elif self.inform:
            painter.fillRect(Qt.QRectF(0, 80, 1280, 80), Qt.QColor('#cceeff'))
            painter.drawText(Qt.QRectF(0, 80, 1280, 80), QtCore.Qt.AlignCenter,
                             'opiekun jest powiadamiany')
        painter.drawText(
            Qt.QRectF(0, 0, 1280,
                      80), QtCore.Qt.AlignCenter, 'sterowanie kursorem jest ' +
            ('włączone' if self.move_mode_open else 'wyłączone'))
        painter.end()
Beispiel #4
0
 def paintEvent(self, event):
     if self.flag:
         qp = QPainter()
         qp.begin(self)
         qp.setBrush(
             QColor(random.randrange(255), random.randrange(255),
                    random.randrange(255)))
         a = random.randrange(1, 351)
         qp.drawEllipse(100, 100, a, a)
         qp.end()
 def paintEvent(self, e):
     """
     receive paint events
     :param e: QPaintEvent
     :return:
     """
     if self.scaled_img:
         painter = QPainter()
         painter.begin(self)
         painter.scale(self.scale, self.scale)
         painter.drawPixmap(self.point, self.scaled_img)
         painter.end()
Beispiel #6
0
class PaintBoard(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.__InitData()
        self.__InitView()

    def __InitData(self):
        self.__size = QSize(280, 280)
        self.__board = QPixmap(self.__size)
        self.__board.fill(Qt.black)
        self.__isEmpty = True
        self.__lastPose = QPoint(0, 0)
        self.__currentPose = QPoint(0, 0)
        self.__painter = QPainter()
        self.__thickness = 20
        self.__penColor = QColor('white')

    def __InitView(self):
        self.setFixedSize(self.__size)

    def paintEvent(self, paintEvent):
        self.__painter.begin(self)
        self.__painter.drawPixmap(0, 0, self.__board)
        self.__painter.end()

    def mousePressEvent(self, mouseEvent):
        self.__currentPose = mouseEvent.pos()
        self.__lastPose = self.__currentPose

    def mouseMoveEvent(self, mouseEvent):
        self.__currentPose = mouseEvent.pos()
        self.__painter.begin(self.__board)
        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawLine(self.__lastPose, self.__currentPose)
        self.__painter.end()
        self.__lastPose = self.__currentPose
        self.update()

    def mouseReleaseEvent(self, mouseEvent):
        self.__isEmpty = False

    def clear(self):
        self.__board.fill(Qt.black)
        self.update()
        self.__isEmpty = True

    def isEmpty(self):
        return self.__isEmpty

    def getImage(self):
        image = self.__board.toImage()
        return image
Beispiel #7
0
    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        if self._flag_1:
            for i in range(self.map.get_col()):
                for j in range(self.map.get_row()):
                    qp.drawPixmap(
                        i * 40, j * 40 + 40,
                        self.map.get_elem_xy(
                            i, j).get_pic())  # рисуем картинками из elem_map
            qp.drawPixmap(self.hero.get_x() * 40,
                          self.hero.get_y() * 40 + 40, self.hero.get_pic())
            for enemy in self.enemies:
                qp.drawPixmap(enemy.get_x() * 40,
                              enemy.get_y() * 40 + 40, enemy.get_pic())
            for i in range(game.hero.get_lifes()):
                qp.drawPixmap(280 + i * 40, 0,
                              self.hero._pic[self.hero._STOP][0])

            txt = "00000" + str(self._score)
            self.lable_score.setText(txt[len(txt) - 5:len(txt)])
        qp.end()
Beispiel #8
0
class PaintBoard(QWidget):


    def __init__(self, Parent=None):
        '''
        Constructor
        '''
        super().__init__(Parent)

        self.__InitData() #先初始化数据,再初始化界面
        self.__InitView()
        
    def __InitView(self):
        self.setFixedSize(self.__size)
        
    def __InitData(self):
        
        self.__size = QSize(1600,1200)
        
        self.__board = QPixmap(self.__size) #新建QPixmap作为画板,宽350px,高250px
        self.__board.fill(Qt.white) #用白色填充画板
        
        self.__IsEmpty = True #默认为空画板 
        self.EraserMode = False #默认为禁用橡皮擦模式
        
        self.__lastPos = QPoint(0,0)
        self.__currentPos = QPoint(0,0)
        
        self.__painter = QPainter()
        
        self.__thickness = 10       #默认画笔粗细为10px
        self.__penColor = QColor("black")       #设置默认画笔颜色为黑色
        self.__colorList = QColor.colorNames() #获取颜色列表
        
    def Clear(self):
        #清空画板
        self.__board.fill(Qt.white)
        self.update()
        self.__IsEmpty = True
        
    def ChangePenColor(self, color="black"):
        #改变画笔颜色
        self.__penColor = QColor(color)
        
    def ChangePenThickness(self, thickness=10):
        #改变画笔粗细
        self.__thickness = thickness
        
    def IsEmpty(self):
        #返回画板是否为空
        return self.__IsEmpty
    
    def GetContentAsQImage(self):
        #获取画板内容(返回QImage)
        image = self.__board.toImage()
        return image
        
    def paintEvent(self, paintEvent):

        self.__painter.begin(self)
        self.__painter.drawPixmap(0,0,self.__board)
        self.__painter.end()
        
    def mousePressEvent(self, mouseEvent):
        
        self.__currentPos =  mouseEvent.pos()
        self.__lastPos = self.__currentPos
        
        
    def mouseMoveEvent(self, mouseEvent):
        self.__currentPos =  mouseEvent.pos()
        self.__painter.begin(self.__board)
        
        if self.EraserMode == False:
            #非橡皮擦模式
            self.__painter.setPen(QPen(self.__penColor,self.__thickness)) #设置画笔颜色,粗细
        else:
            #橡皮擦模式下画笔为纯白色,粗细为10
            self.__painter.setPen(QPen(Qt.white,10))
            
        self.__painter.drawLine(self.__lastPos, self.__currentPos)
        self.__painter.end()
        self.__lastPos = self.__currentPos
                
        self.update() #更新显示
        
    def mouseReleaseEvent(self, mouseEvent):
        self.__IsEmpty = False #画板不再为空
        
class PaintBoard(QWidget):
    def __init__(self, parent=None):

        super().__init__(parent)

        self.__size = QSize(350, 350)

        # 新建画板,尺寸为__size
        self.__board = QPixmap(self.__size)
        self.__board.fill(Qt.white)  # 用白色填充画板

        self.__painter = QPainter()  # 新建绘图工具
        self.eraser_mode = False  # 默认为禁用橡皮擦模式
        self.__thickness = 6  # 默认画笔粗细为10px

        self.__lastPos = QPoint(0, 0)  # 上一次鼠标位置
        self.__currentPos = QPoint(0, 0)  # 当前的鼠标位置
        self.__undo_num = 0
        self.__redo_num = 0
        self.__undo_list = []
        self.__redo_list = []
        self.__undo_list.append(self.__board.toImage())

        # 设置界面的尺寸为__size
        self.setFixedSize(self.__size)

    def clear(self):
        self.__board.fill(Qt.white)
        # 清空画板
        self.update()
        self.__undo_list.append(self.__board.toImage())
        self.__redo_list = []
        self.__undo_num += 1
        self.__redo_num = 0

    def up(self, image):
        self.__board = image
        # 清空画板
        self.update()
        self.__undo_list.append(self.__board.toImage())
        self.__redo_list = []
        self.__undo_num += 1
        self.__redo_num = 0

    def undo(self):
        if self.__undo_num > 0:
            image = self.__undo_list[self.__undo_num - 1]
            self.__board = QPixmap.fromImage(image)
            self.update()
            self.__redo_list.append(self.__undo_list.pop())
            self.__redo_num += 1
            self.__undo_num -= 1

    def redo(self):
        if self.__redo_num > 0:
            image = self.__redo_list[self.__redo_num - 1]
            self.__board = QPixmap(image)
            self.update()
            self.__undo_list.append(self.__redo_list.pop())
            self.__redo_num -= 1
            self.__undo_num += 1

    def change_pen_thickness(self, thickness=10):
        # 改变画笔粗细
        self.__thickness = thickness

    def get_content_as_image(self):
        # 获取画板内容(返回QImage)
        image = self.__board.toImage()
        return image

    def paintEvent(self, paint_event):
        # 绘图事件
        # 绘图时必须使用QPainter的实例,此处为__painter
        # 绘图在begin()函数与end()函数间进行
        # begin(param)的参数要指定绘图设备,即把图画在哪里
        self.__painter.begin(self)
        # 0,0为绘图的左上角起点的坐标,__board即要绘制的图
        self.__painter.drawPixmap(0, 0, self.__board)
        self.__painter.end()

    def mouse_press_event(self, mouse_event):
        # 鼠标按下时,获取鼠标的当前位置保存为上一次位置
        # self.__currentPos = mouse_event.pos()
        self.__currentPos.setX(mouse_event.pos().x() - 803)
        self.__currentPos.setY(mouse_event.pos().y() - 147)
        self.__lastPos = self.__currentPos

    def mouse_move_event(self, mouse_event):
        # self.__currentPos = mouse_event.pos()
        # 鼠标移动时,更新当前位置,并在上一个位置和当前位置间画线
        self.__currentPos.setX(mouse_event.pos().x() - 803)
        self.__currentPos.setY(mouse_event.pos().y() - 147)
        self.__painter.begin(self.__board)

        if not self.eraser_mode:
            # 非橡皮擦模式
            self.__painter.setPen(QPen(Qt.black,
                                       self.__thickness))  # 设置画笔颜色,粗细
        else:
            # 橡皮擦模式下画笔为纯白色,粗细为10
            self.__painter.setPen(QPen(Qt.white, self.__thickness))

        # 画线
        self.__painter.drawLine(self.__lastPos, self.__currentPos)
        self.__painter.end()
        self.__lastPos = self.__currentPos

        self.update()  # 更新显示

    def mouse_release_event(self, mouse_event):
        self.__undo_list.append(self.__board.toImage())
        self.__redo_list = []
        self.__undo_num += 1
        self.__redo_num = 0
Beispiel #10
0
class PaintBoard(QWidget):

    set_paint = pyqtSignal(bool)

    def __init__(self, signals: ClientSignal, Parent=None):
        '''
        Constructor
        '''
        super().__init__(Parent)

        self.Signals = signals


        # 是否是本玩家在画图
        # 判断是否需要发送画图信息
        self.Painting = False
        self.BoardSize = QSize(*board_resolution)

        # 新建QPixmap作为画板,尺寸为size
        self.Board = QPixmap(self.BoardSize)
        self.Board.fill(Qt.white)  # 用白色填充画板

        self.IsEmpty = True  # 默认为空画板
        self.EraserMode = False  # 默认为禁用橡皮擦模式

        self.LastPos = QPoint(0, 0)  # 上一次鼠标位置
        self.CurrentPos = QPoint(0, 0)  # 当前的鼠标位置

        self.Painter = QPainter()  # 新建绘图工具

        self.Thickness = default_thickness  # 默认画笔粗细为10px
        self.PenColor = QColor(default_color)  # 设置默认画笔颜色为黑色
        self.ColorList = QColor.colorNames()  # 获取颜色列表

        self.set_paint.connect(self.set_painting)
        self.PaintPoints = []


        self.init_view()


    def init_view(self):
        # 设置界面的尺寸为size
        self.setFixedSize(self.BoardSize)

    def set_painting(self, painting):
        # print('seting painting to', painting)
        self.Painting = painting


    def set_pen_thickness(self, thickness):
        self.Thickness = int(thickness)


    def set_pen_color(self, color):
        self.PenColor = QColor(color)


    def set_eraser(self, e):
        self.EraserMode = e
        if self.Painting:
            self.Signals.EraserChangeSignal.emit(e)
            # self.EraserSender.emit(e)


    def clear(self):
        if self.Painting:
            self.Signals.ClearSignal.emit()
            # self.ClearSender.emit()
        # 清空画板
        self.Board.fill(Qt.white)
        self.repaint()#update()
        self.IsEmpty = True


    def change_pen_color(self, color="black"):
        print('color changed:', color)
        if self.Painting:
            self.Signals.ColorChangeSignal.emit(color)
            # self.ColorSender.emit(color)
        # 改变画笔颜色
        self.PenColor = QColor(color)

    def change_pen_thickness(self, thickness=default_thickness):

        if self.Painting:
            self.Signals.ThicknessChangeSignal.emit(thickness)
            # self.ThicknessSender.emit(thickness)
        # 改变画笔粗细
        self.Thickness = thickness
        # print('thickness:',type(self.thickness), self.thickness)

    # 返回画板是否为空
    def is_empty(self):
        return self.IsEmpty

    def get_content_as_QImage(self):
        # 获取画板内容(返回QImage)
        image = self.Board.toImage()
        return image


    def paintEvent(self, paintEvent):
        # 绘图事件
        # 绘图时必须使用QPainter的实例,此处为painter
        # 绘图在begin()函数与end()函数间进行
        # begin(param)的参数要指定绘图设备,即把图画在哪里
        # drawPixmap用于绘制QPixmap类型的对象
        self.Painter.begin(self)
        # 0,0为绘图的左上角起点的坐标,board即要绘制的图
        self.Painter.drawPixmap(0, 0, self.Board)
        self.Painter.end()


    def mousePressEvent(self, mouseEvent):
        # 鼠标按下时,获取鼠标的当前位置保存为上一次位置
        self.CurrentPos = mouseEvent.pos()
        self.LastPos = self.CurrentPos

        if self.Painting:
            self.Signals.ClickPointSignal.emit(mouseEvent.pos())
            # self.click_point_sender.emit(mouseEvent.pos())


    def mouseMoveEvent(self, mouseEvent):
        # print('moving! painting=', self.Painting)
        if self.Painting:
            # 鼠标移动时,更新当前位置,并在上一个位置和当前位置间画线
            self.CurrentPos = mouseEvent.pos()
            self.paint_point()
            # print('painting...')
            self.repaint()
            # print('complete painting...')
            self.LastPos = self.CurrentPos

            # self.paint_points.append([self.currentPos.x(), self.currentPos.y()])
            # self.paint_point_sender.emit(mouseEvent.pos())
            self.Signals.PaintPointSignal.emit(mouseEvent.pos())

    def mouseReleaseEvent(self, mouseEvent):
        self.IsEmpty = False  # 画板不再为空
        if self.Painting:
            self.Signals.ReleasePointSignal.emit()
            # self.release_point_sender.emit()
            # self.paint_points.clear()

    def paint_point(self):
        self.Painter.begin(self.Board)

        if not self.EraserMode:
            # 非橡皮擦模式
            self.Painter.setPen(QPen(self.PenColor, self.Thickness))  # 设置画笔颜色,粗细
        else:
            # 橡皮擦模式下画笔为纯白色,粗细为10
            self.Painter.setPen(QPen(Qt.white, 10))
            # 画线

        self.Painter.drawLine(self.LastPos, self.CurrentPos)
        self.Painter.end()


    def extern_click(self, x, y):
        self.LastPos = QPoint(x, y)
        self.CurrentPos = QPoint(x, y)


    def extern_paint(self, ps):
        for x,y in ps:
            self.CurrentPos = QPoint(x, y)
            self.paint_point()
            self.LastPos = self.CurrentPos
        self.repaint()


    def reset_last_point(self, x, y):
        self.LastPos = QPoint(x, y)
        self.CurrentPos = QPoint(x, y)
class PaintBoard(QWidget):


    def __init__(self, Parent=None, fpath=None):
        '''
        Constructor
        '''
        
        super().__init__(Parent)
        self.pos_xy = []  #保存鼠标移动过的点
        self._InitData(fpath) #先初始化数据,再初始化界面
        self.__InitView()
        
    def __InitView(self):
        self.setFixedSize(self.__size)
        
    def _InitData(self,fpath=None):
        
        self.__size = QSize(280,280)
        if fpath is None:
            self.__board = QPixmap(self.__size) #新建QPixmap作为画板,宽350px,高250px
            self.__board.fill(Qt.white) #用白色填充画板
        else:
            self.__board = QPixmap(fpath).scaled(280,280)
        
      
    def paintEvent(self, event):
        self.__painter = QPainter()
        self.__painter.begin(self)
        self.__painter.drawPixmap(0,0,self.__board)
        pen = QPen(Qt.black, 30, Qt.SolidLine)
        self.__painter.setPen(pen)
    
        if len(self.pos_xy) > 1:
            point_start = self.pos_xy[0]
            for pos_tmp in self.pos_xy:
                point_end = pos_tmp
    
                if point_end == (-1, -1):
                    point_start = (-1, -1)
                    continue
                if point_start == (-1, -1):
                    point_start = point_end
                    continue
    
                self.__painter.drawLine(point_start[0], point_start[1], point_end[0], point_end[1])
                point_start = point_end
            self.__painter.end()
            
    def mouseMoveEvent(self, event):
        '''
            按住鼠标移动事件:将当前点添加到pos_xy列表中
        '''
        #中间变量pos_tmp提取当前点
        pos_tmp = (event.pos().x(), event.pos().y())
        #pos_tmp添加到self.pos_xy中
        self.pos_xy.append(pos_tmp)

        self.update()

    def mouseReleaseEvent(self, event):
        '''
            重写鼠标按住后松开的事件
            在每次松开后向pos_xy列表中添加一个断点(-1, -1)
        '''
        pos_test = (-1, -1)
        self.pos_xy.append(pos_test)

        self.update()
        
    def Clear(self):
        pass
Beispiel #12
0
class PaintBoard(QWidget):

    # Define virtual panel coordinates for different shapes/regions
    VPCoord_Start = [316, 332]  #LeftTopX, Y
    VPCoord_Circle = [316, 332, 336, 363]  #LeftTopX, Y, RightBotX, Y
    VPCoord_Rect = [336, 332, 356, 363]  #LeftTopX, Y, RightBotX, Y
    VPCoord_Tri = [316, 363, 336, 395]  #LeftTopX, Y, RightBotX, Y
    VPCoord_Line = [336, 363, 356, 395]  #LeftTopX, Y, RightBotX, Y

    # A flag to check if the user is currently using the virtual panel
    usingVP = False

    def __init__(self, sizeX, sizeY, Parent=None):
        '''
        Constructor
        '''
        super().__init__(Parent)

        self.__InitData(sizeX,
                        sizeY)  #Initialize Data first, then interface/view
        self.__InitView()
        print("Init PaintBoard")

    def __InitView(self):

        self.setFixedSize(self.__size)

    def __InitData(self, sizeX, sizeY):
        self.__size = QSize(sizeX, sizeY)

        self.__board = QPixmap(
            self.__size)  #Make a new QPixmap as paint board,350px * 250px
        self.__board.fill(Qt.white)  #Fill the paint board with white

        self.__IsEmpty = True  #board is empty by default
        self.EraserMode = False  #eraser mode is disabled by default

        self.__lastPos = None
        self.__currentPos = QPoint(0, 0)

        self.__painter = QPainter()

        self.__thickness = 1  #default pen thickness is 1
        self.__penColor = QColor("black")  #default color is black
        self.__colorList = QColor.colorNames()  #get the list of colors

    def Clear(self):
        #Clear the board
        self.__board.fill(Qt.white)
        self.update()
        self.__IsEmpty = True

    def ChangePenColor(self, color="black"):
        self.__penColor = QColor(color)

    def ChangePenThickness(self, thickness=1):
        self.__thickness = thickness

    def IsEmpty(self):
        #Is the board empty
        return self.__IsEmpty

    def GetContentAsQImage(self):
        #return the content of the board (return QImage)
        image = self.__board.toImage()
        return image

    def paintEvent(self, paintEvent):

        self.__painter.begin(self)
        self.__painter.drawPixmap(0, 0, self.__board)
        self.__painter.end()

        # print("inside paintEvent")

    def penPressEvent(self, pos):

        self.__currentPos = QPoint(pos[0], pos[1])
        self.__lastPos = self.__currentPos

    def penMoveEvent(self, pos, pressure):
        pen_x = pos[0]
        pen_y = pos[1]
        pen_pressure = pressure

        if self.__lastPos is None:
            self.__lastPos = QPoint(pen_x, pen_y)
        elif (abs(pen_x - self.__lastPos.x()) > 21
              or abs(pen_y - self.__lastPos.y()) > 21):
            self.__lastPos = QPoint(pen_x, pen_y)

        self.__currentPos = QPoint(pen_x, pen_y)
        self.__painter.begin(self.__board)

        if self.EraserMode == False:
            #Non-Eraser mode
            self.__painter.setPen(QPen(
                self.__penColor, self.__thickness))  #Set pen color, thickness
        else:
            #Eraser mode: pen color is white, thickness is 6
            self.__painter.setPen(QPen(Qt.white, 6))

        self.__painter.drawLine(self.__lastPos, self.__currentPos)
        self.__painter.end()
        self.__lastPos = self.__currentPos

        self.update()  #Show updates

    def penVPEvent(self, pos, pressure):
        pass

    '''    
        # Check if the pressure is over 500
        if(pen_pressure > 400):
            # Check which region the pen is in and prepare to draw shape accordingly
            if(pen_x < self.VPCoord_Circle[2] and pen_y < self.VPCoord_Circle[3]):
                print("A")        
            elif(pen_x < self.VPCoord_Rect[2] and pen_y < self.VPCoord_Rect[3]):
                print("B")
            elif(pen_x < self.VPCoord_Tri[2] and pen_y < self.VPCoord_Tri[3]):
                print("C")
            elif(pen_x < self.VPCoord_Line[2] and pen_y < self.VPCoord_Line[3]):
                print("D")
    '''

    def penReleaseEvent(self, pos):
        self.__IsEmpty = False  #board is not empty

    def paintEllipse(self, center_x, center_y, radias1, radias2):
        self.__painter.begin(self.__board)

        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawEllipse(QPoint(center_x, center_y), radias1,
                                   radias2)

        self.__painter.end()

        self.update()  #Show updates

    def paintRect(self, center_x, center_y, upper_left_x, upper_left_y):
        width = abs(2 * (center_x - upper_left_x))
        height = abs(2 * (center_y - upper_left_y))

        self.__painter.begin(self.__board)

        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawRect(upper_left_x, upper_left_y, width, height)

        self.__painter.end()

        self.update()  #Show updates

    def paintTriangle(self, points):
        self.__painter.begin(self.__board)

        self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        self.__painter.drawPolygon(points)

        self.__painter.end()

        self.update()  #Show updates

    def paintLine(self, P1_x, P1_y, P2_x, P2_y):
        P1 = QPoint(P1_x, P1_y)
        P2 = QPoint(P2_x, P2_y)

        self.__painter.begin(self.__board)
        self.__painter.drawLine(P1, P2)
        self.__painter.end()

        self.update()  #Show updates
class QChessBoard(QWidget):
    square_size = 72
    board_edge = 8
    board_width = board_edge + square_size * 9 + board_edge
    board_height = board_edge + square_size * 10 + board_edge
    pc_str = ('K', 'A', 'B', 'N', 'R', 'C', 'P', '', 'RK', 'RA', 'RB', 'RN',
              'RR', 'RC', 'RP', '', 'BK', 'BA', 'BB', 'BN', 'BR', 'BC', 'BP',
              '')
    selected_str = ('', 'S')
    pc_path = 'images\\IMAGES_X\\COMIC\\'

    def __init__(self, parent=None):
        super().__init__(parent)
        self.board_jpg = QtGui.QPixmap('images\\IMAGES_X\\WOOD.JPG')
        self.oos_gif = QtGui.QPixmap('images\\IMAGES_X\\COMIC\\OOS.GIF')
        self.painter = QPainter()
        self.agent = None
        self.is_flipped = False
        # self.game_state = None
        self.sq_selected = (-1, -1)
        self.mv_cur = (-1, -1, -1, -1)
        self.mv_last = (-1, -1, -1, -1)

    def set_agent(self, agent: AlphaZeroAgent):
        self.agent = agent

    def mousePressEvent(self, e: QtGui.QMouseEvent):
        super().mousePressEvent(e)
        x, y = e.x(), e.y()
        x = round((x - 40) / self.square_size)
        y = round((y - 40) / self.square_size)
        agent = self.agent
        env = agent.env
        player = env.player
        pc = env.board[y][x]
        self_side = side_tag(player)
        if is_self_piece_by_tag(pc, self_side):
            self.sq_selected = (x, y)
            self.repaint()
            return

        if self.sq_selected != (-1, -1) and not is_self_piece_by_tag(
                pc, self_side):
            if not is_legalmove(env.board, self.sq_selected[0],
                                self.sq_selected[1], x, y, player):
                self.sq_selected = (-1, -1)
                return
            """
            玩家走子
            """
            action = (dict_mv[mv_to_str(self.sq_selected[0],
                                        self.sq_selected[1], x, y)], )
            env.step(action)
            self.mv_last = self.mv_cur
            self.mv_cur = (self.sq_selected[0], self.sq_selected[1], x, y)
            self.sq_selected = (-1, -1)
            self.repaint()
            state = (env.board, env.player, env.depth)
            game_state = env.get_winner(state)
            if game_state != None:
                QMessageBox.information(self, '游戏结束!', '游戏结束!')
                return
            """
            AI走子
            """
            self.mv_last = self.mv_cur
            state = (env.board, env.player, env.depth)
            action = agent.decide(state)
            env.step(action)
            self.mv_cur = str_to_mv(labels_mv[action[0]])
            self.sq_selected = (-1, -1)
            self.repaint()
            state = (env.board, env.player, env.depth)
            game_state = env.get_winner(state)
            print(game_state)
            if game_state != None:
                QMessageBox.information(self, '游戏结束!', '游戏结束!')
                return

    def printBoard(self):
        self.env.render()

    def drawOOS(self, x, y):
        if x == -1 or y == -1:
            return
        x = self.board_edge + self.square_size * x
        y = self.board_edge + self.square_size * y
        self.painter.drawPixmap(x, y, self.oos_gif)

    def paintEvent(self, e):
        super().paintEvent(e)
        env = self.agent.env
        board = env.board
        self.painter.begin(self)
        self.painter.drawPixmap(0, 0, self.board_jpg)
        for j in range(env.BOARD_SHAPE[0]):
            for i in range(env.BOARD_SHAPE[1]):
                pc = board[j][i]
                if pc == 0:
                    continue
                gif_path = f'{self.pc_path}{self.pc_str[pc]}' \
                           f'{self.selected_str[int(self.sq_selected == (i, j))]}.GIF'
                gif = QtGui.QPixmap(gif_path)
                x = i
                y = j
                px = self.board_edge + self.square_size * x
                py = self.board_edge + self.square_size * y
                self.painter.drawPixmap(px, py, gif)
        self.drawOOS(self.mv_last[0], self.mv_last[1])
        self.drawOOS(self.mv_last[2], self.mv_last[3])
        self.drawOOS(self.mv_cur[0], self.mv_cur[1])
        self.drawOOS(self.mv_cur[2], self.mv_cur[3])
        self.painter.end()
class PaintBoard(QWidget):
    def __init__(self, Parent=None):
        super().__init__(Parent)
        self.__init_data()
        self.__init_view()

    def __init_data(self):
        """
        initial the canvas, painter
        :return:
        """
        self.__size = QSize(420, 420)

        # create a new canvas by QPixmap, size for self.__size
        self.__canvas = QPixmap(self.__size)
        # set the background of the board as white, for better visual effect
        self.__canvas.fill(Qt.white)

        # default for none
        self.__IsEmpty = True
        # default for no eraser
        self.EraserMode = False

        # initial the last mouse position
        self.__lastPos = QPoint(0, 0)
        # initial the current mouse position
        self.__currentPos = QPoint(0, 0)

        # new a painter for drawing
        self.__painter = QPainter()

        # default pen size for 10px
        self.__thickness = 30
        # default pen color for black
        self.__penColor = QColor("black")
        # get the color list from library
        self.colorList = QColor.colorNames()

    def __init_view(self):
        """
        set the initial size of the canvas
        :return:
        """
        self.setFixedSize(self.__size)

    def clear(self):
        """
        clear the canvas
        :return:
        """
        self.__canvas.fill(Qt.white)
        self.update()
        self.__IsEmpty = True

    def pen_color(self, color="black"):
        """
        set the color of the pen
        :param color:
        :return:
        """
        self.__penColor = QColor(color)

    def pen_size(self, thick=40):
        """
        set the size of the pen
        :param thick:
        :return:
        """
        self.__thickness = thick

    def is_empty(self):
        """
        return the canvas is empty or not
        :return:
        """
        return self.__IsEmpty

    def get_current_image(self):
        """
        fet the current content of the canvas, return as an image
        :return:
        """
        current_image = self.__canvas.toImage()
        return current_image

    def paintEvent(self, paintEvent):
        """
        the painter works between begin() and end()
        - begin(param): parameter--canvas
        - drawPixmap: paint QPixmap object
            0, 0 start
        :param paintEvent:
        :return:
        """
        self.__painter.begin(self)
        self.__painter.drawPixmap(0, 0, self.__canvas)
        self.__painter.end()

    def mousePressEvent(self, mouseEvent):
        """
        capture the mouse when pressed
        :param mouseEvent:
        :return:
        """
        self.__currentPos = mouseEvent.pos()
        self.__lastPos = self.__currentPos

    def mouseMoveEvent(self, mouseEvent):
        """
        when the mouse moves, update the position
        :param mouseEvent:
        :return:
        """
        self.__currentPos = mouseEvent.pos()
        self.__painter.begin(self.__canvas)

        if self.EraserMode == False:
            self.__painter.setPen(QPen(self.__penColor, self.__thickness))
        else:
            self.__painter.setPen((QPen(Qt.white, 40)))

        self.__painter.drawLine(self.__lastPos, self.__currentPos)
        self.__painter.end()
        self.__lastPos = self.__currentPos

        self.update()

    def mouseReleaseEvent(self, QMouseEvent):
        """
        set the canvas for not empty
        :param QMouseEvent:
        :return:
        """
        self.__IsEmpty = False
Beispiel #15
0
    def drawIconWithShadow(self,
                           icon,
                           rect,
                           painter,
                           iconMode,
                           radius=3,
                           color=QColor(0, 0, 0, 130),
                           offset=QPoint(1, -2)):
        '''
        @brief: Draw a cached pixmap with shadow
        @param: icon QIcon
        @param: rect QRect
        @param: painter QPainter
        @param: iconMode QIcon.Mode
        @param: radius int
        @param: color QColor
        @param: offset QPoint
        '''
        cache = QPixmap()
        pixmapName = 'icon %s %s %s' % (icon.cacheKey(), iconMode,
                                        rect.height())

        cache = QPixmapCache.find(pixmapName)
        if not cache:
            px = icon.pixmap(rect.size(), iconMode)
            px.setDevicePixelRatio(gVar.app.devicePixelRatio())
            cache = QPixmap(px.size() + QSize(radius * 2, radius * 2))
            cache.setDevicePixelRatio(px.devicePixelRatioF())
            cache.fill(Qt.transparent)

            cachePainter = QPainter(cache)

            # Draw shadow
            tmp = QImage(px.size() + QSize(radius * 2, radius * 2 + 1),
                         QImage.Format_ARGB32_Premultiplied)
            tmp.setDevicePixelRatio(px.devicePixelRatioF())
            tmp.fill(Qt.transparent)

            tmpPainter = QPainter(tmp)

            tmpPainter.setCompositionMode(QPainter.CompositionMode_Source)
            tmpPainter.drawPixmap(QPoint(radius, radius), px)
            tmpPainter.end()

            # blur the alpha channel
            blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied)
            blurred.fill(Qt.transparent)
            blurPainter = QPainter(blurred)
            # TODO:
            #qt_blurImage(blurPainter, tmp, radius, False, True)
            blurPainter.end()

            tmp = blurred

            # blacken the image...
            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            # draw the blurred drop shadow...
            cachePainter.drawImage(
                QRect(0, 0,
                      cache.rect().width() / cache.devicePixelRatioF(),
                      cache.rect().height() / cache.devicePixelRatioF()), tmp)
            # Draw the actual pixmap...
            cachePainter.drawPixmap(QPoint(radius, radius) + offset, px)
            if self.usePixmapCache():
                QPixmapCache.insert(pixmapName, cache)

            sip.delete(cachePainter)
            sip.delete(tmpPainter)
            sip.delete(blurPainter)

        targetRect = QRect(cache.rect())
        targetRect.setWidth(cache.rect().width() / cache.devicePixelRatioF())
        targetRect.setHeight(cache.rect().height() / cache.devicePixelRatioF())
        targetRect.moveCenter(rect.center())
        painter.drawPixmap(targetRect.topLeft() - offset, cache)
class MainWindow(QMainWindow, Ui_mainWidget):  # 为了实现窗口的显示和业务逻辑分离,新建另一个调用窗口的文件
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        self.board = QPixmap(865, 485)
        self.board.fill(Qt.white)

        self.is_empty = True  # 空画板
        self.last_pos = QPoint(0, 0)
        self.current_pos = QPoint(0, 0)

        self.painter = QPainter()
        self.painter.setRenderHint(QPainter.Antialiasing)  # 反锯齿

        self.clearButton.clicked.connect(self.clear)
        self.uploadButton.clicked.connect(self.upload)
        self.runButton.clicked.connect(self.run)

    # 在此处识别,调用算法中的识别函数
    def run(self):
        algorithm = self.algorithmCombo.currentText()
        target = self.targetCombo.currentText()
        print(algorithm, target)
        # 先保存图片然后找到该图片识别
        image = self.board.toImage()
        # 这里可以改图片存储路径
        image_save_path = 'images/testImage.jpg'
        image.save(image_save_path)
        # 为了方便,识别时直接去存储路径下获取图片
        img_path = image_save_path
        # 由于尚未尝试用除NN外的算法去同时识别数字+字母,所以当选择其他算法时需要输出提示信息
        try:
            # 需要更名选择不同的model,可能会不存在,先load下来看是否报错
            model_path = model_path_dic[algorithm][target_sub[target]]
            if algorithm == "SVM" or algorithm == "KNN":
                model = joblib.load(model_path)
            else:
                model = load_model(model_path)
        except:  # 如果图片路径下没有相应的图片或是模型路径下没有相应的模型,报错
            QMessageBox.about(self, "提示", "暂不支持")
            self.resultLineEdit.setText("")
            self.board.fill(Qt.white)
        else:
            # 运行并返回预测结果
            prediction = run(img_path, model_path,
                             algorithmName_sub[algorithm], target_sub[target])
            prediction = ' '.join([str(x) for x in prediction])
            print(prediction)
            self.resultLineEdit.setText(prediction)  # 将结果存放在LineEdit中
            self.board.load("result.png")
            self.update()

    def upload(self):
        filename = QFileDialog.getOpenFileName(None, 'open', ".")
        self.board.load(filename[0])
        self.update()

    def clear(self):
        self.board.fill(Qt.white)
        self.update()
        self.is_empty = True
        self.resultLineEdit.setText("")

    def paintEvent(self, paintEvent):
        self.painter.begin(self)
        self.painter.drawPixmap(0, 0, self.board)
        self.painter.end()

    def mouseReleaseEvent(self, QMouseEvent):
        self.is_empty = False

    def mousePressEvent(self, QMouseEvent):
        self.current_pos = QMouseEvent.pos()
        self.last_pos = self.current_pos

    def mouseMoveEvent(self, QMouseEvent):
        self.current_pos = QMouseEvent.pos()
        self.painter.begin(self.board)

        self.painter.setPen(QPen(Qt.black, 6))

        self.painter.drawLine(self.last_pos, self.current_pos)
        self.painter.end()
        self.last_pos = self.current_pos

        self.update()
Beispiel #17
0
class PaintBoard(QWidget):


    def __init__(self):
        QWidget.__init__(self)

        # self.label = QLabel(self)
        # self.gridLayout = QGridLayout(self)
        # self.gridLayout.addWidget(self.label)

        self.pixmap = QPixmap(1,1)
        self.pixmap.fill(Qt.white)
        self.img = QImage(self.pixmap.toImage())

        # self.label.setFrameShape(1)
        # # self.label.setPixmap(self.pixmap)
        # self.label.setScaledContents(True)
        # self.label.setVisible(False)

        self.pen = QPainter()

    def paintEvent(self, paintEvent):
        self.pixmap = self.pixmap.scaled(self.width(), self.height())
        self.pen.begin(self)
        # self.pen.drawPixmap(0, 0, self.pixmap)
        self.img = QImage(self.pixmap.toImage())
        self.pen.drawImage(0, 0, self.img)
        self.pen.end()

    def drawPoints(self, x, y):
        # print(self.width(),self.height())
        m = int(self.width()/2) + x
        n = int(self.height()/2) - y
        self.pen.begin(self.pixmap)
        self.pen.setPen(QPen(Qt.black,1))
        self.pen.drawPoint(m, n)
        self.pen.end()
        self.update()
        # self.repaint()

    def load_img(self, img):
        self.pixmap.load(img)
        self.update()

    #DDA
    def drawLine(self, x0, y0, x1, y1):
        self.Clear()
        dx = x1 - x0
        dy = y1 - y0
        if fabs(dx) > fabs(dy):
            steps = fabs(dx)
        else:
            steps = fabs(dy)
        self.drawPoints(int(x0+0.5), int(y0+0.5))
        xInc = dx/steps
        yInc = dy/steps
        for i in range(int(steps+0.5)):
            x0 += xInc
            y0 += yInc
            self.drawPoints(int(x0+0.5), int(y0+0.5))

    #中点法画圆
    def CirclePlot(self, xc, yc, x, y):
        self.drawPoints(x+xc, y+yc)
        self.drawPoints(-x+xc, y+yc)
        self.drawPoints(x+xc, -y+yc)
        self.drawPoints(-x+xc, -y+yc)
        self.drawPoints(y+xc, x+yc)
        self.drawPoints(y+xc, -x+yc)
        self.drawPoints(-y+xc, x+yc)
        self.drawPoints(-y+xc, -x+yc)
    def drawRound(self, xc, yc, r):
        self.Clear()
        x = 0
        y = r
        d = 3-2*r
        self.CirclePlot(xc, yc, x, y)
        while x<y:
            if d<0:
                d = d+4*x+6
            else:
                d = d+4*(x-y)+10
                y -= 1
            x +=1
            self.CirclePlot(xc, yc, x, y)
            
    '''
    # 边界填充
    def fill(self, x, y):
        w = int(self.width()/2)
        h = int(self.height()/2)
        block = deque([(x, y)])
        while 1:
            if len(block) == 0:
                break
            else:
                # print(block)
                point = block.popleft()
                m = point[0]
                n = point[1]
                # c = self.img.pixel(w+m, h+n)
                # colors = QColor(c).getRgb()
                # if colors != (0, 0, 0, 255):
                self.drawPoints(m, n)
                # result.append((m,n))
    
                c = self.img.pixel(w+m, h+n-1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n-1) not in block:
                        block.append((m,n-1))
    
                c = self.img.pixel(w+m, h+n+1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n+1) not in block:
                        block.append((m,n+1))
    
                c = self.img.pixel(w+m-1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m-1,n) not in block:
                        block.append((m-1,n))
    
                c = self.img.pixel(w+m+1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m+1,n) not in block:
                        block.append((m+1,n))
        print(results)
    '''

    #边界填充
    #种子边界填充
    def fill(self, x, y):
        w = int(self.width()/2)
        h = int(self.height()/2)
        block = deque([(x, y)])
        results = []
        while 1:
            if len(block) == 0:
                break
            else:
                point = block.popleft()
                m = point[0]
                n = point[1]
                results.append((m,n))

                c = self.img.pixel(w+m, h+n-1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n-1) not in block:
                        if (m,n-1) not in results:
                            block.append((m,n-1))

                c = self.img.pixel(w+m, h+n+1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n+1) not in block:
                        if (m,n+1) not in results:
                            block.append((m,n+1))

                c = self.img.pixel(w+m-1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m-1,n) not in block:
                        if (m-1,n) not in results:
                            block.append((m-1,n))

                c = self.img.pixel(w+m+1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m+1,n) not in block:
                        if (m+1,n) not in results:
                            block.append((m+1,n))
        for point in results:
            self.drawPoints(point[0], point[1])

    def Clear(self):
        self.pixmap.fill(Qt.white)
        self.update()
 def paintEvent(self, event):
     qp = QPainter()
     qp.begin(self)
     self.draw(event, qp)
     qp.end()
Beispiel #19
0
class ImageDisplay(QWidget):

    video_infos     = ['vidéo : {}','nb frames : {}','taille : {}','FPS : {}','durée : {:.2f} sec']
    video_keys      = ['videoname','nframes','size','fps','duration']
    algo_traj       = ['barycentre','minmax']

    def __init__(self, mainWindow):

        # acall the base class constructor:
        super().__init__(mainWindow)

        self.mw = mainWindow

        # Attributs (objets persistants)
        self.img_lbl = QLabel(self)           # to display the current image
        self.img_lbl.installEventFilter(self) # filter to catch evenements
        self.selectTargetRect = None          # display a rectangle to show teh target color selection

        self.rubberBand  = QRubberBand(QRubberBand.Line, self)

        # Boutons pour avancer/reculer
        self.btn_prev  = QPushButton(QIcon("icones/go-prev.png"),  "", self)
        self.btn_next  = QPushButton(QIcon("icones/go-next.png"), "", self)
        self.btn_first = QPushButton(QIcon("icones/go-first.png"),  "", self)
        self.btn_last  = QPushButton(QIcon("icones/go-last.png"), "", self)
        self.btn_traj  = QPushButton(QIcon("icones/extract.png"), "Extraire...", self)
        self.btn_clear = QPushButton(QIcon("icones/clear.png"), "Effacer courbes...", self)
        self.btn_exportCSV = QPushButton(QIcon("icones/exportCSV.png"), "Export CSV", self)
        self.btn_algo      = QComboBox(self)
        self.image_index   = QLabel(self)
        
        # widget QSpinBox
        self.images_step      = QSpinBox(parent=self)
        self.images_firstRank = QSpinBox(parent=self) 
        self.images_lastRank  = QSpinBox(parent=self) 

        # QLabel to display the target color
        self.target_color_label = QLabel("target color",parent=self) 
        self.picked_color       = QLabel(self)
    
        self.video_path     = None  # Chemin de la dernière vidéo
        self.images_dir     = None  # Dossier contenant les images
        self.__img_idx      = None  # Rang de l'image affichée
        self.img_path       = None  # nom du chemin de l'image courante
        self.nb_img         = None  # nombre d'images

        self.video_name     = None  # nom de la video ("aaaaaa.mp4")
        self.video_nframes  = None  # nombre d'images dans la video
        self.video_size     = None  # taille (width, height) des images
        self.video_FPS      = None  # nombre d'images par seconde
        self.video_duration = None  # durée de la video en secondes
        self.videoLabels    = []    # liste de QLabel contenant les infos vidéo
        self.dico_video     = {}    # dictionnaire des méta-données

        self.dico_unit      = {}    # dictionary "pixels", "mm"
        self.scale_pixel    = None  # nombre de pixels pour conversion en mm
        self.scale_mm       = None  # nbre de mm pour scale_pixel
        self.valid_scale    = False # données de l'échelle valides ou pas
        self.pix_to_mm_coeff= 1.    # le coefficient de converion pixels -> mm
        self.dicoScale      = {}    # dictionnaire des QWidget d'info scale

        self.lbl_epsilon    = None  # label epsilon
        self.epsi_spin      = None  # boite de choix de epsilon    

        # créer l'onglet de visualisation image """
        self.__initUI()
        self.scaleInfoVisible(False)
        self.__epsilonVisible(False)

    def __initUI(self):

        # Onglet "Visualisation images"
        vbox = QVBoxLayout()

        # Ligne 1 : extraction trajec
        self.picked_color.setFrameStyle(QFrame.StyledPanel | QFrame.Plain);
        
        line1 = QHBoxLayout()
        line1.addStretch(1)
        line1.addWidget(self.btn_algo)
        line1.addWidget(self.btn_traj)
        line1.addWidget(self.target_color_label)
        line1.addWidget(self.picked_color)
        line1.addWidget(self.btn_clear)
        line1.addWidget(self.btn_exportCSV)
        line1.addStretch(1)

        # Ligne 2 : infos video + visu image
        line2 = QHBoxLayout()

        # boîte d'infos sur la vidéo
        infoVBox = QVBoxLayout()
        for _ in ImageDisplay.video_infos:
            label = QLabel(self)
            label.setFrameStyle(QFrame.StyledPanel | QFrame.Plain);
            infoVBox.addWidget(label)
            self.videoLabels.append(label)
        infoVBox.addStretch()

        widget = QLabel("Conversion pixels -> mm", self)
        self.dicoScale['Pixels-mm'] = widget
        infoVBox.addWidget(widget)

        grid = QGridLayout()
        infoVBox.addLayout(grid)

        widget = QLabel("pixels  ",self)
        self.dicoScale['pixels'] = widget
        grid.addWidget(widget,1,1)

        self.scale_pixel = QLineEdit(self)
        self.dicoScale['pixelsForMM'] = self.scale_pixel
        grid.addWidget(self.scale_pixel,1,2)

        widget = QLabel("millimètres ",self)
        self.dicoScale['millimeters'] = widget
        grid.addWidget(widget,2,1)

        self.scale_mm = QLineEdit(self)
        self.dicoScale['mmForPixels'] = self.scale_mm
        grid.addWidget(self.scale_mm,2,2)

        self.lbl_epsilon = QLabel("Epsilon ",self)
        grid.addWidget(self.lbl_epsilon,5,1)

        self.epsi_spin = QSpinBox(self)
        self.epsi_spin.setRange(1,50)
        self.epsi_spin.setSingleStep(1)
        self.epsi_spin.setValue(10)
        grid.addWidget(self.epsi_spin,5,2)
        
        infoVBox.addStretch()

        line2.addLayout(infoVBox)
        line2.addStretch(1)
        line2.addWidget(self.img_lbl) # le QLabel por afficher l'image
        line2.addStretch(1)

        # line 3 : navigation boutons
        self.image_index.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        self.image_index.setText("       ")
        line3 = QHBoxLayout()
        line3.addStretch(1)
        line3.addWidget(self.btn_first)
        line3.addWidget(self.btn_prev)
        line3.addWidget(self.image_index)
        line3.addWidget(self.btn_next)
        line3.addWidget(self.btn_last)
        line3.addStretch(1)

        # line 4 : first , step, last image selection
        line4 = QHBoxLayout()
        line4.addStretch(1)
        line4.addWidget(self.images_firstRank)
        line4.addWidget(self.images_step)
        line4.addWidget(self.images_lastRank)
        line4.addStretch(1)

        vbox.addLayout(line1)
        vbox.addStretch(1)
        vbox.addLayout(line2)
        vbox.addStretch(1)
        vbox.addLayout(line3)
        vbox.addLayout(line4)

        self.setLayout(vbox)

        self.buttonsState()
        self.__buttonsConnect()
        self.__setVideoLabelVisible(False)

    def __setVideoLabelVisible(self, state):
        for label in self.videoLabels:
            label.setVisible(state)

    def __buttonsConnect(self):            
        self.btn_traj.clicked.connect(self.extract_trajectoire)
        self.btn_clear.clicked.connect(self.mw.clearPlots)
        self.btn_exportCSV.clicked.connect(self.mw.ExportCSV)
        self.btn_prev.clicked.connect(self.prev_image)
        self.btn_next.clicked.connect(self.next_image)
        self.btn_first.clicked.connect(self.first_image)
        self.btn_last.clicked.connect(self.last_image)
        self.images_step.valueChanged.connect(self.__step_changed)
        self.images_firstRank.valueChanged.connect(self.__first_rank_changed)
        self.images_lastRank.valueChanged.connect(self.__last_rank_changed)

    def buttonsState(self, importCSV=False):

        self.btn_traj.setEnabled(False)
        self.picked_color.setText("X")
        self.picked_color.setEnabled(False)
        
        self.btn_traj.setStatusTip('Extrait la trajectoire de la cible'+
            'dont la couleur a été choisie')

        self.target_color_label.setEnabled(False)
        self.picked_color.setStyleSheet('background-color : rgb(255, 255, 255)')
        
        self.btn_clear.setEnabled(False)
        self.btn_clear.setStatusTip('Nettoye tous les tracés des onglets'+
            '<trajectoire> et <X(t), Y(t)>')

        self.btn_exportCSV.setEnabled(False)
        texte = "Export des données dans un fichier CSV"
        self.btn_exportCSV.setStatusTip(texte)

        if not importCSV: self.btn_algo.addItems(ImageDisplay.algo_traj)
        self.btn_algo.setEnabled(False)

        self.btn_prev.setEnabled(False)
        self.btn_prev.setStatusTip("affiche l'image précédente")

        self.btn_next.setEnabled(False)
        self.btn_next.setStatusTip("affiche l'image suivante")

        self.btn_first.setEnabled(False)
        self.btn_first.setStatusTip("affiche la première image à traiter")

        self.btn_last.setEnabled(False)
        self.btn_last.setStatusTip("affiche la dernière image à traiter")

        # SpinBoxes parameters:
        self.images_step.setRange(1,1000)
        self.images_step.setSingleStep(1)
        self.images_step.setValue(1)
        self.images_step.setPrefix("step: ")
        self.images_step.setEnabled(False)
        self.images_step.setStatusTip("Fixe le pas pour passer d'une image à l'autre")
        
        self.images_firstRank.setRange(1,1000)
        self.images_firstRank.setSingleStep(1)
        self.images_firstRank.setValue(1)
        self.images_firstRank.setPrefix("first: ")
        self.images_firstRank.setEnabled(False)
        self.images_firstRank.setStatusTip("Fixe le rang de la première image à traiter")
        
        self.images_lastRank.setRange(1,10000)
        self.images_lastRank.setSingleStep(1)
        self.images_lastRank.setValue(1)
        self.images_lastRank.setPrefix("last: ")
        self.images_lastRank.setEnabled(False)
        self.images_lastRank.setStatusTip("Fixe le rang de la dernière image à traiter")

    def __first_rank_changed(self, val):
        if self.img_idx is None: return
        if self.img_idx < val:
            self.img_idx = val
            self.show_image()
            
    def __last_rank_changed(self, val):
        if self.img_idx is None: return
        if self.img_idx > val:
            self.img_idx = val
            self.show_image()

    def __step_changed(self, val):
        if self.img_idx is None: return

    def setTextInfoVideoGrid(self):
        
        for field, name, key in zip(self.videoLabels,
                                    ImageDisplay.video_infos,
                                    ImageDisplay.video_keys):
            mess = name.format(self.dico_video.get(key,'?'))
            field.setText(mess)
        self.__setVideoLabelVisible(True)            

    def scaleInfoVisible(self, state):
        for widget in self.dicoScale.values():
            widget.setVisible(state)

    def __epsilonVisible(self, state):
        self.lbl_epsilon.setVisible(state)
        self.epsi_spin.setVisible(state)

    def open_video(self):
        '''Lance un sélecteur de fichier pour choisir la vidéo à traiter.'''
        fname = QFileDialog.getOpenFileName(None,
                                            'Choisir une vidéo',
                                            self.mw.cur_dir,
                                            'Fichier vidéo (*.mp4)')
        if fname[0]  != '' :
            # un fichier vidéo a été chosi :
            vp = fname[0]
            if self.video_path == vp :
                name = os.path.basename(vp)
                rep = QMessageBox.question(self,        # widget parent de QMessageBox
                    'Question',                     # texte du bandeau de la fenêtre
                    'Voulez-vous recharger le fichier video {} ?'.format(name),
                    QMessageBox.Yes | QMessageBox.No,   # afficher les boutons Yes et No
                    QMessageBox.No)                     # bouton No sélectionné par défaut
                if rep == QMessageBox.No: return
            # fichier vidéo à traiter => faire le split des images :
            self.video_path = vp
            self.extract_images_from_video()


    def load_images_from_directory(self):
        '''Charge les images '*.png' contenue dans le répertoire
           des images choisi avec un sélecteur graphique.'''

        # Choix du répertoire avec un sélecteur de fichier :
        dname = QFileDialog.getExistingDirectory(None,
                                                 'Choisir un dossier images',
                                                 self.mw.image_dir)
        if dname != '' :
            # un répertoire valide a été choisi :
            self.video_path = None
            self.images_dir = dname + "/"

            try:
                # Lecture du fichier ascii des méta-données
                with open(self.images_dir + "metaData.txt", "r") as F:
                    data = F.read()
                exec('self.dico_video = '+data)
            except:
                rep = QMessageBox.critical(
                    None,             # widget parent de QMessageBox
                    'Erreur',    # bandeau de la fenêtre
                    'Pas de fichier de méta-données dans le répertoire'+\
                    ' <{}>'.format(os.path.basename(dname)),
                    QMessageBox.Ok)
                return



            print("méta données :", self.dico_video)

            self.parse_meta_data()
            self.setTextInfoVideoGrid()

            # Mettre à jour l'application avec les nouvelles images chargées :
            self.update_images()


    def extract_trajectoire(self):
        '''Méthode utilisée pour extraire la trajectoire du centre de la
           cible pour toutes les images de la vidéo.'''

        # Récupérer l'algorithme de calcul du centre de la cible :
        algo = self.btn_algo.currentText()

        # Définition de la liste dans laquelle on va récupérer les coordonnées
        # du centre cible pour toutes les images :
        target_pos = []

        # Création d'un objet ProgressBar qui va lancer le travail
        # d'extraction de la cible dans les images tout en affichant une
        # barre d'avancement :
        
        first = self.images_firstRank.value()
        last  = self.images_lastRank.value()
        step  = self.images_step.value()
        
        last = last - (last - first) % step
        first_last_step = (first, last, step)
        pg = ProgressBar(self.images_dir, self)
        pg.configure_for_target_extraction(self.mw.target_RGB,
                                           algo,
                                           self.epsi_spin.value(),
                                           target_pos,
                                           first_last_step)
        ret = pg.exec_() # lance la barre et le travail d'extraction...
        print("retour de pg.exec_() :",ret)

        if ret != 0:
            self.mw.target_pos = None
            return

        target_pos = np.array(target_pos)
        width, height = self.video_size
        # l'axe verticale est retourné et decalé:
        target_pos[1] = height - target_pos[1]
        self.scale_XY()

        self.mw.target_pos = target_pos
        self.display_plots()
        
        # remettre le bouton extraire_trajectoire disabled:
        self.btn_exportCSV.setEnabled(True)

    def display_plots(self):
        self.mw.clearPlots()
        
        # Plot trajectory (X(t), Y(t)) :
        self.mw.onePlot.setEnabled(True)
        self.mw.onePlot.Plot()

        # Plot curves X(t) and Y(t)
        self.mw.twoPlots_xy.setEnabled(True)
        self.mw.tabs.setCurrentWidget(self.mw.twoPlots_xy)
        self.mw.twoPlots_xy.Plot()

        # Plot curves VX(t) and VY(t)
        self.mw.twoPlots_VxVy.setEnabled(True)
        self.mw.tabs.setCurrentWidget(self.mw.twoPlots_xy)
        self.mw.twoPlots_VxVy.Plot()


    def extract_images_from_video(self) :
        # name of the video file without path and suffix:
        videoname = os.path.basename(self.video_path)[:-4]

        # directory where to put extracted iamges:
        self.images_dir = self.mw.image_dir + videoname + "/"

        if os.path.isdir(self.images_dir) :
            print("Effacement de tous les fichiers de '{}'"\
                  .format(self.images_dir))
            for fn in os.listdir(self.images_dir) :
                os.remove(self.images_dir+fn)
        else :
            os.mkdir(self.images_dir)

        video = cv2.VideoCapture(self.video_path)
        
        self.dico_video['nframes']   = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
        self.dico_video['size']      = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)),
                                        int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))    
        self.dico_video['fps']       = int(video.get(cv2.CAP_PROP_FPS))
        self.dico_video['duration']  = video.get(cv2.CAP_PROP_FRAME_COUNT)/video.get(cv2.CAP_PROP_FPS)
        self.dico_video['videoname'] = os.path.basename(self.video_path)
                                            
        self.parse_meta_data()
        self.dico_video["videoname"] = videoname+".mp4"
        self.setTextInfoVideoGrid()

        # Création d'un objet ProgressBar qui va lancer le travail
        # d'extraction des images tout en affichant une barre d'avancement :
        pg = ProgressBar(self.images_dir, self)
        pg.configure_for_video_extraction(video, self.mw.image_fmt)
        ret = pg.exec_()
        print("retour de pg.exec_() :", ret)
        if ret != 0: return

        # MAJ de la liste des fichiers images :
        self.update_images()

        # écriture des méta-data dans le fichier 'nom_video'.info
        with open(self.mw.image_dir+videoname+"/metaData.txt", "w") as F:
            F.write(str(self.dico_video))

    def computeTargetColor(self, draw_selection=False):
        col_min,row_min,col_max,row_max = self.selection.getCoords()
        print("Pixels selectionnés : lignes [{},{}] colonnes [{},{}]".\
              format(row_min, row_max, col_min, col_max))

        tab = imread(self.img_path)
        self.target_pix = tab[row_min:row_max+1, col_min:col_max+1, :]
        R = round(self.target_pix[:,:,0].mean())
        G = round(self.target_pix[:,:,1].mean())
        B = round(self.target_pix[:,:,2].mean())
        self.mw.target_RGB = np.array([R, G, B], dtype=int)
        print("RGB sélection dans <{}> :".format(os.path.basename(self.img_path)),
              self.mw.target_RGB)

        draw_selection = self.mw.flags["drawTargetSelection"]
        if draw_selection:
            self.show_image()
            print("drawTargetSelection")
            #if self.selectTargetRect is not None : del self.selectTargetRect
            # create painter instance with pixmap
            self.selectTargetRect = QPainter(self.img_lbl.pixmap())

            # set rectangle color and thickness
            self.penRectangle = QPen(QColor(0,0,0))
            self.penRectangle.setWidth(2)

            # draw rectangle on painter
            self.selectTargetRect.begin(self)
            self.selectTargetRect.setPen(self.penRectangle)
            self.selectTargetRect.drawRect(col_min,row_min,
                                          col_max-col_min,row_max-row_min)
            self.selectTargetRect.setOpacity(0.1)
            self.selectTargetRect.end()
            #self.show_image()

        self.btn_traj.setEnabled(True)
        self.btn_algo.setEnabled(True)
        self.btn_clear.setEnabled(True)
        self.target_color_label.setEnabled(True)
        self.picked_color.setStyleSheet('background-color : rgb({},{},{})'.format(R, G, B))

    @property
    def img_idx(self): return self.__img_idx

    @img_idx.setter
    def img_idx(self, index):
        self.__img_idx = index
        self.image_index.setText(str(index))
                                 
    def update_images(self) :
        '''Méthode à exécuter quand de nouvelles images sont apparues
           après une extraction d'images depuis une vidéo par exemple.
           Cette méthode :
           - met à jour des attributs qui dépendant de la liste des images,
           - met à jour l'état de certains boutons
           - fait afficher la première image et un message d'information.'''

        if self.images_dir is None :
            self.__img_idx = None
            #self.btn_prev.setEnabled(False)
            self.btn_prev.setStatusTip("")
            #self.btn_next.setEnabled(False)
            self.btn_next.setStatusTip("")
            self.images_step.setEnabled(False)
            self.images_firstRank.setEnabled(False)
            self.images_lastRank.setEnabled(False)
            
        else :
            self.buttonsState()
            self.mw.clearPlots()
            self.mw.twoPlots_VxVy.reset()
            
            # liste des noms des fichiers image pour avoir leur nombre :
            file_names = [ f for f in os.listdir(self.images_dir) \
                           if f.endswith('.png')]
            file_names.sort()
            self.nb_img = len(file_names)

              # Update spinBox:
            self.images_step.setEnabled(True)
            self.images_firstRank.setEnabled(True)
            self.images_lastRank.setEnabled(True)

            self.images_firstRank.setValue(1)
            self.images_step.setValue(1)
            self.images_lastRank.setValue(self.nb_img)

            self.images_firstRank.setMaximum(self.nb_img)
            self.images_lastRank.setMaximum(self.nb_img)
            self.images_step.setMaximum(self.nb_img)

            # MAJ des boutons prev et next
            self.img_idx = self.images_firstRank.value()
            self.btn_prev.setEnabled(True)
            self.btn_first.setEnabled(True)

            self.btn_prev.setStatusTip("charge l'image précédente")

            self.btn_next.setEnabled(True)
            self.btn_last.setEnabled(True)
            self.btn_next.setStatusTip("afficher "+self.mw.image_fmt.format(\
                self.img_idx+self.images_step.value()))
          
            self.show_image()
            self.scaleInfoVisible(True)
            self.__epsilonVisible(True)
            self.mw.tabs.setCurrentWidget(self)

            self.scale_mm.clear()
            self.scale_mm.setText("???")
            self.scale_pixel.clear()
            try:
                text = str(self.video_size[1])
            except:
                text = ""
            self.scale_pixel.setText(text)

            self.mw.twoPlots_VxVy.reset()
            

            if self.mw.flags["displayInfo"]:
                rep = QMessageBox.information(
                    None,             # widget parent de QMessageBox
                    'Information',    # bandeau de la fenêtre
                    'Vous pouvez maintenant sélectionner une couleur de cible'+\
                    'avec la souris...',
                    QMessageBox.Ok)
                

    def show_image(self):
        '''Affiche l'image dont le numéro est donné par l'attribut 'img_idx'.'''
        if self.img_idx is None :
            self.img_path = ''
        else :
            self.img_path = self.images_dir+self.mw.image_fmt.format(self.img_idx)
        pixmap = QPixmap(self.img_path)
        self.img_lbl.setPixmap(pixmap)
        self.img_lbl.setStatusTip(os.path.basename(self.img_path))

    def first_image(self) :
        if self.img_idx == None : return
        self.img_idx = self.images_firstRank.value()
        self.mw.statusBar().showMessage("")
        self.show_image()

    def prev_image(self) :
        if self.img_idx == None : return
        if self.img_idx >= self.images_firstRank.value() + self.images_step.value():
            self.img_idx -= self.images_step.value()
        self.mw.statusBar().showMessage("")
        self.show_image()

    def last_image(self) :
        if self.img_idx == None : return
        self.img_idx = self.images_lastRank.value() # rank of last image to process
        self.mw.statusBar().showMessage("")
        self.show_image()

    def next_image(self) :
        if self.img_idx == None : return
        if self.img_idx <= self.images_lastRank.value()-self.images_step.value():
            self.img_idx += self.images_step.value()
        self.mw.statusBar().showMessage("")
        self.show_image()

    def parse_meta_data(self):
        self.video_nframes  = self.dico_video.get('nframes', None)
        self.video_size     = self.dico_video.get('size', None)
        self.video_FPS      = self.dico_video.get('fps', None)
        self.video_duration = self.dico_video.get('duration', None)
        self.video_name     = self.dico_video.get('videoname',"none.mp4")

        if self.mw.flags["debug"]:
            info= " nb images    : {},\n taille image : {},\n FPS : {} image/sec,\n durée : {.2f} sec."
            info = info.format(self.video_nframes,
                               self.video_size,
                               self.video_FPS,
                               self.video_duration)
            QMessageBox.about(None,     # widget parent de QMessageBox
                              'Informations video {}'.format(self.video_name),
                              info)


    def eventFilter(self, object, event):
        if object == self.img_lbl :
            if event.type() == QEvent.MouseButtonPress:
                self.mousePressInLabel(event)
                return True
            elif event.type() == QEvent.MouseButtonRelease:
                self.mouseReleaseInLabel(event)
                return True
            elif event.type() == QEvent.MouseMove:
                self.mouseMoveInLabel(event)
                return True
        return False

    def mousePressInLabel(self, event):
        if event.button() == Qt.LeftButton:
            self.pt1 = event.pos()
            self.pt1_rect = self.img_lbl.mapTo(self, self.pt1)
            print("\nCoord. pt1 image :",self.pt1)
            self.rubberBand.setGeometry(QRect(self.pt1_rect, QSize()))
            self.rubberBand.show()
            self.mw.statusBar().showMessage('sélection en cours....')

    def mouseMoveInLabel(self, event):
        if not self.pt1.isNull():
            pt = self.img_lbl.mapTo(self,event.pos())
            self.rubberBand.setGeometry(QRect(self.pt1_rect, pt).normalized())

    def mouseReleaseInLabel(self, event):
        if event.button() == Qt.LeftButton:
            self.pt2 = event.pos()
            print("Coord. pt2 image :", self.pt2)
            self.rubberBand.hide()
            self.selection = QRect(self.pt1, self.pt2).normalized()
            print(self.selection)
            self.computeTargetColor()

    def scale_XY(self):

        self.valid_scale = False
        self.pix_to_mm_coeff = 1.
        
        try :
            pixels = float(self.scale_pixel.text())
            mm     = float(self.scale_mm.text())
        except :
            if self.mw.flags["displayInfo"]:
                info = 'Les données de conversion Pixels -> mm n\'ont pas été '
                info += 'complétées.. les ordonnées des tracés seront en pixels.'
                rep = QMessageBox.information(None,  # parent de QMessageBox
                        'Info',               # bandeau de la fenêtre
                        info, QMessageBox.Ok)
            return
        self.valid_scale = True
        self.pix_to_mm_coeff = mm/pixels
        print("valid scale : ", self.pix_to_mm_coeff)
Beispiel #20
0
class PaintBoard(QWidget):
    def __init__(self, Parent=None):

        super().__init__(Parent)

        self.__InitData()  #先初始化数据,再初始化界面
        self.__InitView()

    def __InitData(self):

        self.__size = QSize(1024, 512)

        #新建QPixmap作为画板,尺寸为__size
        self.__board = QPixmap(self.__size)
        self.__board.fill(Qt.white)  #用白色填充画板

        self.__IsEmpty = True  #默认为空画板
        self.EraserMode = False  #默认为禁用橡皮擦模式

        self.__lastPos = QPoint(0, 0)  #上一次鼠标位置
        self.__currentPos = QPoint(0, 0)  #当前的鼠标位置

        self.__painter = QPainter()  #新建绘图工具

        self.__thickness = 6  #默认画笔粗细为6px
        self.__eraser = 20

    def __InitView(self):
        #设置界面的尺寸为__size
        self.setFixedSize(self.__size)

    def Clear(self):
        #清空画板
        self.__board.fill(Qt.white)
        self.update()
        self.__IsEmpty = True

    def ChangePenThickness(self, eraser=20):
        #改变橡皮画笔粗细,默认20px
        self.__eraser = eraser

    def IsEmpty(self):
        #返回画板是否为空
        return self.__IsEmpty

    def GetContentAsQImage(self):
        #获取画板内容(返回QImage)
        image = self.__board.toImage()
        return image

    def paintEvent(self, paintEvent):
        #绘图事件
        #绘图时必须使用QPainter的实例,此处为__painter
        #绘图在begin()函数与end()函数间进行
        #begin(param)的参数要指定绘图设备,即把图画在哪里
        #drawPixmap用于绘制QPixmap类型的对象
        self.__painter.begin(self)
        # 0,0为绘图的左上角起点的坐标,__board即要绘制的图
        self.__painter.drawPixmap(0, 0, self.__board)
        self.__painter.end()

    def mousePressEvent(self, mouseEvent):
        #鼠标按下时,获取鼠标的当前位置保存为上一次位置
        self.__currentPos = mouseEvent.pos()
        self.__lastPos = self.__currentPos

    def mouseMoveEvent(self, mouseEvent):
        #鼠标移动时,更新当前位置,并在上一个位置和当前位置间画线
        self.__currentPos = mouseEvent.pos()
        self.__painter.begin(self.__board)

        if self.EraserMode == False:
            #非橡皮擦模式
            self.__painter.setPen(
                QPen(Qt.red, 6, Qt.SolidLine, Qt.RoundCap,
                     Qt.RoundJoin))  #设置画笔颜色,粗细
        else:
            #橡皮擦模式下画笔为纯白色
            self.__painter.setPen(
                QPen(Qt.white, self.__eraser, Qt.SolidLine, Qt.RoundCap,
                     Qt.RoundJoin))

        #画线
        self.__painter.drawLine(self.__lastPos, self.__currentPos)
        self.__painter.end()
        self.__lastPos = self.__currentPos

        self.update()  #更新显示

    def mouseReleaseEvent(self, mouseEvent):
        self.__IsEmpty = False  #画板不再为空
Beispiel #21
0
class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)

        self.setMouseTracking(True)
        self.imglist = []
        self.ImgFolder = ''
        self.CurImg = ''

        #新建QPixmap作为画板,尺寸为__size
        self.__board = QPixmap()
        self.__board.fill(Qt.white) #用白色填充画板

        self.__IsEmpty = True  # 默认为空画板
        self.EraserMode = False  # 默认为禁用橡皮擦模式

        self.__lastPos = QPoint(0, 0)  # 上一次鼠标位置
        self.__currentPos = QPoint(0, 0)  # 当前的鼠标位置

        self.__painter = QPainter()  # 新建绘图工具

        self.__thickness = 10  # 默认画笔粗细为10px
        self.__penColor = QColor("black")  # 设置默认画笔颜色为黑色
        self.__colorList = QColor.colorNames()  # 获取颜色列表

        # 按键信号与回调函数连接
        self.OpenDir.clicked.connect(self.OpenDirBntClicked)
        self.NextImg.clicked.connect(self.NextImBntClicked)
        self.LastImg.clicked.connect(self.PreImBntClicked)
        self.SaveImg.clicked.connect(self.on_btn_Save_Clicked)
        self.PenThicknessSpinBox.valueChanged.connect(self.on_PenThicknessChange)
        # self.NextImg.clicked.connect(self.NextImBntClicked)

    #########选择图片文件夹#########
    def OpenDirBntClicked(self):
        self.ImgFolder = QtWidgets.QFileDialog.getExistingDirectory(None, "select folder", DefaultImFolder)  # 这个语句有些邪门
        if self.ImgFolder != '':
            ImNameSet = os.listdir(self.ImgFolder)
            self.imglist = glob.glob(self.ImgFolder + '/*.jpg')
            print(self.imglist)
            print(ImNameSet)
            ImNameSet.sort()
            # ImPath = os.path.join(ImFolder, ImNameSet[0])
            ImPath = os.path.join(self.ImgFolder, ImNameSet[1])
            # pix = QtGui.QPixmap(ImPath)
            # self.ImgShowLabel.setPixmap(pix)


            # 画板
            # self.__board = QtGui.QPixmap(r'C:\Users\49942\Pictures\Saved Pictures\t2.jpg')
            self.__board = QtGui.QPixmap(self.imglist[0])
            self.__board = self.__board.scaled(500,500)
            # self.__IsEmpty = True  # 默认为空画板
            # self.EraserMode = False  # 默认为禁用橡皮擦模式
            #
            # self.__lastPos = QPoint(0, 0)  # 上一次鼠标位置
            # self.__currentPos = QPoint(0, 0)  # 当前的鼠标位置
            #
            # self.__painter = QPainter()  # 新建绘图工具
            #
            # self.__thickness = 5  # 默认画笔粗细为10px
            # self.__penColor = QColor("black")  # 设置默认画笔颜色为黑色
            # self.__colorList = QColor.colorNames()  # 获取颜色列表

            # 界面标题
            self.ImNameSet = ImNameSet
            self.CurImId = 0
            _, SelectFolderName = os.path.split(self.ImgFolder)
            CopyImFolderName = 'From{}CopyIm_{}-{}-{}-{}'.format(SelectFolderName, Month, Day, Hour, Minute)
            self.CopyImFolder = os.path.join(CurFolder, CopyImFolderName)

            _translate = QtCore.QCoreApplication.translate
            CurWinTitle = "检测工具                                                " + \
                          "                                                             " + \
                          SelectFolderName + '\\' + ImNameSet[0]
            self.setWindowTitle(_translate("MainWindow", '审查工具 '+self.imglist[0]))
        else:
            print('请重新选择文件夹')

    #########显示下一张图片 #########
    def NextImBntClicked(self):
        ImFolder = self.ImgFolder
        # ImNameSet = self.ImNameSet
        CurImId = self.CurImId
        ImNum = len(self.imglist)
        if CurImId < ImNum - 1:  # 不可循环看图
            ImPath = os.path.join(ImFolder, self.imglist[CurImId + 1])
            self.__board = QtGui.QPixmap(self.imglist[CurImId + 1])
            self.__board = self.__board.scaled(500, 500)
            self.update()
            # self.ImgShowLabel.setPixmap(pix)
            self.CurImId = CurImId + 1

            _, SelectFolderName = os.path.split(ImFolder)
            _translate = QtCore.QCoreApplication.translate
            CurWinTitle = "审查图片                                                " + \
                          "                                                             " + \
                          SelectFolderName + '\\'
            self.setWindowTitle(_translate("MainWindow", self.imglist[CurImId + 1]))

    #########显示前一张图片 #########
    def PreImBntClicked(self):
        ImFolder = self.ImgFolder
        ImNameSet = self.ImNameSet
        CurImId = self.CurImId
        ImNum = len(self.imglist)
        if CurImId > 0:  # 第一张图片没有前一张
            ImPath = os.path.join(ImFolder, ImNameSet[CurImId - 1])
            self.__board = QtGui.QPixmap(self.imglist[CurImId - 1])
            self.__board = self.__board.scaled(500,500)
            self.update()
            # self.ImgShowLabel.setPixmap(pix)
            self.CurImId = CurImId - 1

            _, SelectFolderName = os.path.split(ImFolder)
            _translate = QtCore.QCoreApplication.translate
            CurWinTitle = "看图工具1.0                                                " + \
                          "                                                             " + \
                          SelectFolderName + '\\'
            self.setWindowTitle(_translate("MainWindow", self.imglist[CurImId - 1]))
        if self.CurImId < 0:
            self.CurImId = 0

    def Clear(self):
        # 清空画板
        self.__board.fill(Qt.white)
        self.update()
        self.__IsEmpty = True

    def ChangePenColor(self, color="black"):
        # 改变画笔颜色
        self.__penColor = QColor(color)

    def ChangePenThickness(self, thickness=10):
        # 改变画笔粗细
        self.__thickness = thickness

    def IsEmpty(self):
        # 返回画板是否为空
        return self.__IsEmpty

    def GetContentAsQImage(self):
        # 获取画板内容(返回QImage)
        image = self.__board.toImage()
        return image

    def paintEvent(self, paintEvent):
        # 绘图事件
        # 绘图时必须使用QPainter的实例,此处为__painter
        # 绘图在begin()函数与end()函数间进行
        # begin(param)的参数要指定绘图设备,即把图画在哪里
        # drawPixmap用于绘制QPixmap类型的对象
        self.__painter.begin(self)
        # 0,0为绘图的左上角起点的坐标,__board即要绘制的图
        self.__painter.drawPixmap(0, 0, self.__board)
        self.__painter.end()

    def mousePressEvent(self, mouseEvent):
        # 鼠标按下时,获取鼠标的当前位置保存为上一次位置
        self.__currentPos = mouseEvent.pos()
        self.__lastPos = self.__currentPos

    def mouseMoveEvent(self, mouseEvent):
        # 鼠标移动时,更新当前位置,并在上一个位置和当前位置间画线
        self.__currentPos = mouseEvent.pos()

        if mouseEvent.buttons() == QtCore.Qt.LeftButton:
            self.__painter.begin(self.__board)

            if self.EraserMode == False:
                # 非橡皮擦模式
                self.__painter.setPen(QPen(self.__penColor, self.__thickness))  # 设置画笔颜色,粗细
            else:
                # 橡皮擦模式下画笔为纯白色,粗细为10
                self.__painter.setPen(QPen(Qt.white, 10))

            # 画线
            self.__painter.drawLine(self.__lastPos, self.__currentPos)
            self.__painter.end()
            self.__lastPos = self.__currentPos
            self.update()  # 更新显示

        self.mouseEventpos = mouseEvent.pos()
        # pos = self.mapToGlobal(mouseEvent.pos()) #相對位置轉絕對
        # print(pos)
        pos = QCursor.pos()
        hwnd = win32gui.WindowFromPoint((pos.x(), pos.y()))
        print('x,y', pos.x(), pos.y())
        print(*win32gui.GetWindowRect(hwnd))
        # self.frameWidget.setRect(*win32gui.GetWindowRect(hwnd))
        # 截图
        screen = QApplication.primaryScreen()  # 获取主显示屏对象(QScreen对象)
        if screen is not None:
            image = screen.grabWindow(0, pos.x() - 60, pos.y() - 60, 120, 120)
            if not image.isNull():
                self.EnlargeImg.setPixmap(image.scaled(240, 240))
        #         self.EnlargeImg.update()

    def mouseReleaseEvent(self, mouseEvent):
        self.__IsEmpty = False  # 画板不再为空

    # def leaveEvent(self, event):
    #     # super(Label, self).leaveEvent(event)
    #     # 得到鼠标在屏幕中的位置
    #     print('鼠标离开')
    #     print(event)
    #     pos = QCursor.pos()
    #     print(pos)
    #     hwnd = win32gui.WindowFromPoint((pos.x(), pos.y()))
    #     print('x,y', pos.x(), pos.y())
    #     print(*win32gui.GetWindowRect(hwnd))
    #     # self.frameWidget.setRect(*win32gui.GetWindowRect(hwnd))
    #     # 截图
    #     screen = QApplication.primaryScreen()  # 获取主显示屏对象(QScreen对象)
    #     if screen is not None:
    #         image = screen.grabWindow(0, pos.x() - 60, pos.y() - 60, 120, 120)
    #         if not image.isNull():
    #             self.EnlargeImg.setPixmap(image.scaled(240, 240))
    #     #         self.EnlargeImg.update()

    def on_PenColorChange(self):
        color_index = self.__comboBox_penColor.currentIndex()
        color_str = self.__colorList[color_index]
        self.__paintBoard.ChangePenColor(color_str)

    def on_PenThicknessChange(self):
        penThickness = self.__spinBox_penThickness.value()
        self.__paintBoard.ChangePenThickness(penThickness)

    def on_btn_Save_Clicked(self):
        # savePath = QFileDialog.getSaveFileName(self, 'Save Your Paint', '.\\', '*.png')
        # print(savePath)
        curImg = self.imglist[self.CurImId]
        ImgName = os.path.split(curImg)[-1]
        savePath = os.path.join(r'C:\Users\49942\Pictures', ImgName)
        print('保存')
        print(savePath)
        if savePath == "":
            print("Save cancel")
            return
        image = self.__board.toImage()
        image.save(savePath)

    def on_cbtn_Eraser_clicked(self):
        if self.__cbtn_Eraser.isChecked():
            self.__paintBoard.EraserMode = True  # 进入橡皮擦模式
        else:
            self.__paintBoard.EraserMode = False  # 退出橡皮擦模式

    def Quit(self):
        self.close()
Beispiel #22
0
class PaintBoard(QWidget):

    def __init__(self, Parent=None):
        '''
        Constructor
        '''
        super().__init__(Parent)

        self.__InitData()  # 先初始化数据,再初始化界面
        self.__InitView()

    def __InitData(self):

        self.__size = QSize(480, 460)

        # 新建QPixmap作为画板,尺寸为__size
        self.__board = QPixmap(self.__size)
        self.__board.fill(Qt.white)  # 用白色填充画板

        self.__IsEmpty = True  # 默认为空画板
        self.EraserMode = False  # 默认为禁用橡皮擦模式

        self.__lastPos = QPoint(0, 0)  # 上一次鼠标位置
        self.__currentPos = QPoint(0, 0)  # 当前的鼠标位置

        self.__painter = QPainter()  # 新建绘图工具

        self.__thickness = 10  # 默认画笔粗细为10px
        self.__penColor = QColor("black")  # 设置默认画笔颜色为黑色
        self.__colorList = QColor.colorNames()  # 获取颜色列表

    def __InitView(self):
        # 设置界面的尺寸为__size
        self.setFixedSize(self.__size)

    def Clear(self):
        # 清空画板
        self.__board.fill(Qt.white)
        self.update()
        self.__IsEmpty = True

    def ChangePenColor(self, color="black"):
        # 改变画笔颜色
        self.__penColor = QColor(color)

    def ChangePenThickness(self, thickness=10):
        # 改变画笔粗细
        self.__thickness = thickness

    def IsEmpty(self):
        # 返回画板是否为空
        return self.__IsEmpty

    def GetContentAsQImage(self):
        # 获取画板内容(返回QImage)
        image = self.__board.toImage()
        return image

    def paintEvent(self, paintEvent):
        # 绘图事件
        # 绘图时必须使用QPainter的实例,此处为__painter
        # 绘图在begin()函数与end()函数间进行
        # begin(param)的参数要指定绘图设备,即把图画在哪里
        # drawPixmap用于绘制QPixmap类型的对象
        self.__painter.begin(self)
        # 0,0为绘图的左上角起点的坐标,__board即要绘制的图
        self.__painter.drawPixmap(0, 0, self.__board)
        self.__painter.end()

    def mousePressEvent(self, mouseEvent):
        # 鼠标按下时,获取鼠标的当前位置保存为上一次位置
        self.__currentPos = mouseEvent.pos()
        self.__lastPos = self.__currentPos

    def mouseMoveEvent(self, mouseEvent):
        # 鼠标移动时,更新当前位置,并在上一个位置和当前位置间画线
        self.__currentPos = mouseEvent.pos()
        self.__painter.begin(self.__board)

        if self.EraserMode == False:
            # 非橡皮擦模式
            self.__painter.setPen(QPen(self.__penColor, self.__thickness))  # 设置画笔颜色,粗细
        else:
            # 橡皮擦模式下画笔为纯白色,粗细为10
            self.__painter.setPen(QPen(Qt.white, 10))

        # 画线
        self.__painter.drawLine(self.__lastPos, self.__currentPos)
        self.__painter.end()
        self.__lastPos = self.__currentPos

        self.update()  # 更新显示

    def mouseReleaseEvent(self, mouseEvent):
        self.__IsEmpty = False  # 画板不再为空
Beispiel #23
0
class PaintBoard(QLabel):
    signal_right_mouse = pyqtSignal(int)
    signal_draw = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.__parent = parent
        self.__board = QPixmap(QSize(440, 440))
        self.__board.fill(Qt.transparent)
        self.__board_old = self.__board.copy()
        self.__board_old_old = self.__board.copy()
        self.__board_before_dots = self.__board.copy()
        self.__thickness = 10  # 默认画笔粗细为10px
        self.__penColor = QColor(0, 0, 0, 128)
        self.__painter = QPainter()
        self.__pen = QPen(self.__penColor, self.__thickness)
        self.__pen_seg = QPen(QColor(0, 0, 0, 128))
        self.__brush = QBrush(QColor(0, 0, 0, 128))
        self.__pen.setCapStyle(Qt.RoundCap)
        #self.__painter.setPen(self.__pen)
        self.__lastPos = QPoint(0, 0)  # 上一次鼠标位置
        self.__currentPos = QPoint(0, 0)  # 当前的鼠标位置
        self.__points = []  # dots模式的点集
        self.__mouse_pressed = False
        self.__can_undo = False
        self.__has_seg = False
        self.__mode = 1
        self.__ERASE = 0
        self.__LINE = 1
        self.__RECT = 2
        self.__CIRCLE = 3
        self.__DOTS = 4
        self.__transparent = False
        self.__trans_board = self.__board.copy()
        self.__trans_board.fill(Qt.transparent)

    @staticmethod
    def dist(p1, p2):
        return math.hypot(p1.x() - p2.x(), p1.y() - p2.y())

    # Each time paintEvent is called it clean the space where it is going to draw.
    # So it does not save memory of the previous drawings,
    # A simple solution is to first paint a QPixmap to store what you have painted.
    # And then paint the widget with that QPixmap.

    def set_trans(self, trans):
        self.__transparent = trans
        self.update()

    def is_trans(self):
        return self.__transparent

    def paintEvent(self, paint_event):  # 把board绘制到界面上
        self.__painter.begin(self)
        if not self.__transparent:
            self.__painter.drawPixmap(0, 0, self.__board)
        else:
            self.__painter.drawPixmap(0, 0, self.__trans_board)  #结果图关闭mask
        self.__painter.end()

    def mousePressEvent(self, mouse_event):
        if mouse_event.button() == Qt.LeftButton:
            self.__mouse_pressed = True
            self.__board_old_old = self.__board_old.copy()
            self.__board_old = self.__board.copy()
            self.__currentPos = mouse_event.pos()
            self.__lastPos = self.__currentPos
            if self.__mode == self.__DOTS:
                if len(self.__points) == 0:
                    self.__board_before_dots = self.__board.copy()
                    self.__parent.childAt(740, 0).setEnabled(False)
                    self.__parent.childAt(840, 0).setEnabled(False)
                    self.__parent.childAt(370, 0).setEnabled(False)
                    self.__parent.childAt(300, 610).setEnabled(False)
                if len(self.__points) > 0:
                    print(
                        self.dist(
                            self.__points[0],
                            QPoint(self.__currentPos.x(),
                                   self.__currentPos.y())))
                if len(self.__points) > 2 and \
                        self.dist(self.__points[0], QPoint(self.__currentPos.x(), self.__currentPos.y())) < 5:
                    self.__board = self.__board_before_dots.copy()
                    self.__painter.begin(self.__board)
                    if self.__ERASE:
                        self.__painter.setCompositionMode(
                            QPainter.CompositionMode_Clear)
                    else:
                        self.__painter.setCompositionMode(
                            QPainter.CompositionMode_Source)
                    self.__painter.setPen(Qt.NoPen)
                    self.__painter.setBrush(self.__brush)
                    self.__painter.drawPolygon(QPolygon(self.__points))
                    self.signal_draw.emit()
                    self.__painter.end()
                    self.__points.clear()
                    self.__parent.childAt(740, 0).setEnabled(True)
                    self.__parent.childAt(840, 0).setEnabled(True)
                    self.__parent.childAt(370, 0).setEnabled(True)
                    self.__parent.childAt(300, 610).setEnabled(True)
                    self.update()
                else:
                    self.__points.append(
                        QPoint(self.__currentPos.x(), self.__currentPos.y()))
            if not (self.__mode == self.__DOTS and len(self.__points) == 1):
                self.__can_undo = True
                self.__parent.childAt(70, 610).setEnabled(True)
            else:
                self.__can_undo = False
                self.__parent.childAt(70, 610).setEnabled(False)

    def mouseMoveEvent(self, mouse_event):  # 把线绘制到board上
        self.__currentPos = mouse_event.pos()
        if self.__mode != self.__LINE:
            if len(self.__points) > 0:
                self.__board = self.__board_old.copy()
            elif not self.__mode == self.__DOTS:
                if self.__mouse_pressed:
                    self.__board = self.__board_old.copy()
        self.__painter.begin(self.__board)
        self.__painter.setPen(self.__pen)
        if self.__ERASE:
            self.__painter.setCompositionMode(QPainter.CompositionMode_Clear)
        else:
            self.__painter.setCompositionMode(QPainter.CompositionMode_Source)
        if self.__mode == self.__LINE:
            if self.__mouse_pressed:
                self.__painter.drawLine(self.__lastPos, self.__currentPos)
                self.signal_draw.emit()
        elif self.__mode == self.__RECT:
            self.__painter.setPen(Qt.NoPen)
            self.__painter.setBrush(self.__brush)
            if self.__mouse_pressed:
                self.__painter.drawRect(
                    self.__lastPos.x(), self.__lastPos.y(),
                    (self.__currentPos.x() - self.__lastPos.x()),
                    (self.__currentPos.y() - self.__lastPos.y()))
                self.signal_draw.emit()
        elif self.__mode == self.__CIRCLE:
            self.__painter.setPen(Qt.NoPen)
            self.__painter.setBrush(self.__brush)
            if self.__mouse_pressed:
                self.__painter.drawEllipse(
                    self.__lastPos.x(), self.__lastPos.y(),
                    (self.__currentPos.x() - self.__lastPos.x()),
                    (self.__currentPos.y() - self.__lastPos.y()))
                self.signal_draw.emit()
        elif self.__mode == self.__DOTS:
            if len(self.__points) > 0:
                self.__painter.setCompositionMode(
                    QPainter.CompositionMode_Source)
                self.__painter.setPen(QPen(self.__pen_seg.color(), 1))
                self.__painter.drawLine(self.__points[-1], self.__currentPos)
                self.signal_draw.emit()

        self.__painter.end()
        if self.__mode == self.__LINE:
            self.__lastPos = self.__currentPos
        self.update()  # 触发paintEvent

    def mouseDoubleClickEvent(self, mouse_event):
        if mouse_event.button() == Qt.LeftButton:
            if not self.__mode == self.__DOTS:
                if self.__has_seg:
                    x = mouse_event.pos().x()
                    y = mouse_event.pos().y()
                    value = self.segment[y][x]  # 注意这里x和y要反过来
                    self.__painter.begin(self.__board)
                    self.paint_segment(value, x, y)
                    self.__painter.end()
                    self.signal_draw.emit()
                    self.update()  # 触发paintEvent

    def mouseReleaseEvent(self, mouse_event):
        if mouse_event.button() == Qt.LeftButton:
            self.__mouse_pressed = False
        if mouse_event.button() == Qt.RightButton:
            self.signal_right_mouse.emit(1 - self.__ERASE)
        return

    def undo(self):
        if self.__can_undo:
            if self.__mode != self.__DOTS:
                self.__board = self.__board_old.copy()
            else:
                if len(self.__points) == 0:
                    self.__board = self.__board_before_dots.copy()
                else:
                    self.__points.pop()
                    self.__board = self.__board_old_old.copy()
                    self.__board_old = self.__board_old_old.copy()
            self.signal_draw.emit()
            self.update()
            self.__can_undo = False
            self.__parent.childAt(70, 610).setEnabled(False)

    def update_segment(self, seg):
        self.segment = seg
        self.__parent.childAt(1040, 0).setEnabled(False)
        self.__has_seg = True

    def set_board(self, x, y):
        self.__board = self.__board.scaled(x, y)

    def update_board(self, board):
        self.__board = board
        self.update()

    def paint_segment(self, value, x, y):
        has_painted = np.zeros(self.segment.shape, dtype=np.uint8)
        point_stack = [(x, y)]
        while len(point_stack) > 0:
            point = point_stack.pop()
            x = point[0]
            y = point[1]
            self.__painter.setPen(self.__pen_seg)
            if self.__ERASE:
                self.__painter.setCompositionMode(
                    QPainter.CompositionMode_Clear)
            else:
                self.__painter.setCompositionMode(
                    QPainter.CompositionMode_Source)
            self.__painter.drawPoint(x, y)
            has_painted[y][x] = 1
            if x + 1 < self.segment.shape[1] and has_painted[y][
                    x + 1] == 0 and value == self.segment[y][x + 1]:
                point_stack.append((x + 1, y))
            if x - 1 >= 0 and has_painted[y][
                    x - 1] == 0 and value == self.segment[y][x - 1]:
                point_stack.append((x - 1, y))
            if y + 1 < self.segment.shape[0] and has_painted[
                    y + 1][x] == 0 and value == self.segment[y + 1][x]:
                point_stack.append((x, y + 1))
            if y - 1 >= 0 and has_painted[
                    y - 1][x] == 0 and value == self.segment[y - 1][x]:
                point_stack.append((x, y - 1))

    def Thanos(self, label):
        if len(label) == 0:
            return False
        image = self.__board.copy()
        image.fill(Qt.transparent)
        pixels = image.toImage()
        s = pixels.bits().asstring(pixels.width() * pixels.height() * 4)
        arr = np.fromstring(s, dtype=np.uint8).reshape(
            (pixels.height(), pixels.width(), 4))
        np.set_printoptions(threshold=sys.maxsize)
        mask = arr[..., 3]
        for l in label:
            mask[self.segment == l] = 255
        expand_mask(mask, 5)
        #Image.fromarray(np.uint8(mask)).save('mask_10.jpg')
        return mask

    def set_seg(self):
        self.__has_seg = False

    def set_pen(self, value):
        self.__pen.setWidth(value)

    def pen_black(self):
        self.__pen.setColor(QColor(0, 0, 0, 128))

    def pen_white(self):
        self.__pen.setColor(QColor(255, 255, 255, 128))

    def geo_black(self):
        self.__pen_seg.setColor(QColor(0, 0, 0, 128))
        self.__brush = QBrush(QColor(0, 0, 0, 128))

    def geo_white(self):
        self.__pen_seg.setColor(QColor(255, 255, 255, 128))
        self.__brush = QBrush(QColor(255, 255, 255, 128))

    def switch_mode(self):
        self.__ERASE = 1 - self.__ERASE

    def set_mode(self, mode):
        self.__ERASE = mode

    def tool_pen(self):
        self.__mode = self.__LINE

    def tool_rect(self):
        self.__mode = self.__RECT

    def tool_circle(self):
        self.__mode = self.__CIRCLE

    def tool_dots(self):
        self.__mode = self.__DOTS

    def clear_board(self):
        self.__board.fill(Qt.transparent)
        self.__board_old = self.__board.copy()
        self.__board_before_dots = self.__board.copy()
        self.__board_old_old = self.__board.copy()
        self.__parent.childAt(70, 610).setEnabled(False)
        self.signal_draw.emit()
        self.update()

    def save(self):
        # save_path = QFileDialog.getSaveFileName(self, 'Save Your Paint', '.\\', '*.jpg')
        save_path = 'D:/test.png', '*.png'
        print(save_path)
        if save_path[0] == "":
            print("Save cancel")
            return
        image = self.__board
        pixels = image.toImage()
        s = pixels.bits().asstring(pixels.width() * pixels.height() * 4)
        arr = np.fromstring(s, dtype=np.uint8).reshape(
            (pixels.height(), pixels.width(), 4))
        np.set_printoptions(threshold=sys.maxsize)
        mask = arr[..., 3]
        print(mask)
        # qimage2numpy(pixels)
        # Pixels can only be accessed through QPainter functions or by converting the QPixmap to a QImage.
        image.save(save_path[0])

    def get_mask(self):
        image = self.__board
        pixels = image.toImage()
        s = pixels.bits().asstring(pixels.width() * pixels.height() * 4)
        arr = np.fromstring(s, dtype=np.uint8).reshape(
            (pixels.height(), pixels.width(), 4))
        np.set_printoptions(threshold=sys.maxsize)
        mask = arr[..., 3]  # 取alpha通道,就是不透明度
        mask[mask > 0] = 255
        return mask

    def get_board(self):
        return self.__board.copy()

    def test(self):
        # self.pix = QPixmap("road.jpg")
        self.__painter.begin(self.__board)
        for i in range(301):
            for j in range(301):
                self.__painter.drawPoint(i, j)
        self.__painter.end()
        self.update()