def __init__(self, develop=False): self.drawn_once = False self.develop = develop self.title_font = f = QFont() f.setPointSize(self.TITLE_SIZE) f.setBold(True) self.title_height = QFontMetrics(f).lineSpacing() + 2 self.body_font = f = QFont() f.setPointSize(self.BODY_SIZE) self.line_height = QFontMetrics(f).lineSpacing() self.total_height = max(self.LOGO_SIZE, self.title_height + 3 * self.line_height) self.num_font = f = QFont() f.setPixelSize(self.total_height) f.setItalic(True), f.setBold(True) f = QFontMetrics(f) self.num_ch = str(max(3, numeric_version[0])) self.footer_font = f = QFont() f.setPointSize(self.FOOTER_SIZE) f.setItalic(True) self.dpr = QApplication.instance().devicePixelRatio() self.pmap = QPixmap(I('library.png', allow_user_override=False)) self.pmap.setDevicePixelRatio(self.dpr) self.pmap = self.pmap.scaled(int(self.dpr * self.LOGO_SIZE), int(self.dpr * self.LOGO_SIZE), transformMode=Qt.SmoothTransformation) self.light_brush = QBrush(QColor('#F6F3E9')) self.dark_brush = QBrush(QColor('#39322B')) pmap = QPixmap(int(self.WIDTH * self.dpr), int(self.WIDTH * self.dpr)) pmap.setDevicePixelRatio(self.dpr) pmap.fill(Qt.transparent) QSplashScreen.__init__(self, pmap) self.setWindowTitle(__appname__)
def render_emblems(item, emblems): emblems = tuple(emblems) if not emblems: return icon = self.rendered_emblem_cache.get(emblems, None) if icon is None: pixmaps = [] for emblem in emblems: pm = self.emblem_cache.get(emblem, None) if pm is None: pm = self.emblem_cache[emblem] = QIcon(I(emblem)).pixmap(self.iconSize()) pixmaps.append(pm) num = len(pixmaps) w, h = pixmaps[0].width(), pixmaps[0].height() if num == 1: icon = self.rendered_emblem_cache[emblems] = QIcon(pixmaps[0]) else: canvas = QPixmap((num * w) + ((num-1)*2), h) canvas.setDevicePixelRatio(pixmaps[0].devicePixelRatio()) canvas.fill(Qt.transparent) painter = QPainter(canvas) for i, pm in enumerate(pixmaps): painter.drawPixmap(int(i * (w + 2)/canvas.devicePixelRatio()), 0, pm) painter.end() icon = self.rendered_emblem_cache[emblems] = canvas item.setData(0, Qt.DecorationRole, icon)
def inicio_splash(self, develop="false"): self.drawn_once = False self.develop = develop self.title_font = f = QFont() f.setPointSize(self.TITLE_SIZE) f.setBold(True) self.title_height = QFontMetrics(f).lineSpacing() self.body_font = f = QFont() f.setPointSize(self.BODY_SIZE) self.line_height = QFontMetrics(f).lineSpacing() self.total_height = max(self.LOGO_SIZE, self.title_height + 3 * self.line_height) self.num_font = f = QFont() f.setPixelSize(self.total_height) f.setItalic(True), f.setBold(True) f = QFontMetrics(f) self.num_ch = str(max(3, numeric_version[0])) self.footer_font = f = QFont() f.setPointSize(self.FOOTER_SIZE) f.setItalic(True) self.dpr = QApplication.instance().devicePixelRatio() self.pmap = QPixmap(I('library.png', allow_user_override=False)) self.pmap.setDevicePixelRatio(self.dpr) self.pmap = self.pmap.scaled(int(self.dpr * self.LOGO_SIZE), int(self.dpr * self.LOGO_SIZE), transformMode=Qt.SmoothTransformation) self.light_brush = QBrush(QColor('#F6F3E9')) self.dark_brush = QBrush(QColor('#39322B')) pmap = QPixmap(int(self.WIDTH * self.dpr), int(self.WIDTH * self.dpr)) pmap.setDevicePixelRatio(self.dpr) pmap.fill(Qt.transparent) QSplashScreen.__init__(self, pmap) self.setWindowTitle('Sistema Biblioteca Nacional')
class ColorButton(QToolButton): def __init__(self, color, parent=None): QToolButton.__init__(self, parent) self.setIconSize(QSize(50, 25)) self.pix = QPixmap(self.iconSize()) self._color = QColor('#' + color) self.pix.fill(self._color) self.setIcon(QIcon(self.pix)) self.clicked.connect(self.choose_color) @dynamic_property def color(self): def fget(self): return self._color.name(QColor.HexRgb)[1:] def fset(self, val): self._color = QColor('#' + val) return property(fget=fget, fset=fset) def update_display(self): self.pix.fill(self._color) self.setIcon(QIcon(self.pix)) def choose_color(self): c = QColorDialog.getColor(self._color, self, _('Choose color')) if c.isValid(): self._color = c self.update_display()
def initToolBar(self): tb = QToolBar(self) self.addToolBar(Qt.LeftToolBarArea, tb) tb.actionTriggered[QAction].connect(self.toolAction) deleteAction = QAction(QIcon('ppf/ui/icons/delete.png'), 'delete all', self) deleteAction.a = lambda: self.graphics.deleteAll() tb.addAction(deleteAction) self.penCombo = QComboBox() tb.addWidget(self.penCombo) pixmap = QPixmap(20, 20) for pen in self.graphics.PENS: pixmap.fill(pen.color()) self.penCombo.addItem(QIcon(pixmap), '') self.penCombo.currentIndexChanged.connect(lambda: self.penChanged()) self.linewidthCombo = QComboBox() tb.addWidget(self.linewidthCombo) pixmap = QPixmap(20, 20) for w in self.graphics.LINEWIDTH: qp = QPainter() pixmap.fill(Qt.white) qp.begin(pixmap) qp.fillRect(0, 0, 20, w, Qt.black) qp.end() self.linewidthCombo.addItem(QIcon(pixmap), '') self.linewidthCombo.currentIndexChanged.connect( lambda: self.linewidthChanged())
class ColorButton(QToolButton): def __init__(self, color, parent=None): QToolButton.__init__(self, parent) self.setIconSize(QSize(50, 25)) self.pix = QPixmap(self.iconSize()) self._color = QColor('#' + color) self.pix.fill(self._color) self.setIcon(QIcon(self.pix)) self.clicked.connect(self.choose_color) @property def color(self): return self._color.name(QColor.NameFormat.HexRgb)[1:] @color.setter def color(self, val): self._color = QColor('#' + val) def update_display(self): self.pix.fill(self._color) self.setIcon(QIcon(self.pix)) def choose_color(self): c = QColorDialog.getColor(self._color, self, _('Choose color')) if c.isValid(): self._color = c self.update_display()
def _updateButtons(self): """ Update button icons. """ sz = QSize(32, 32) if self.orientation() == Qt.Vertical: sz.setHeight(sz.height() / 2) pix = QPixmap(sz) pix.fill(Qt.transparent) pnt = QPainter(pix) pnt.setPen(Qt.black) path = QPainterPath() arrowwidth = pix.width() - 2 * 2 arrowheight = min(arrowwidth / 2, pix.height() - 2 * 2) path.moveTo((pix.width() - arrowwidth) / 2, (pix.height() - arrowheight) / 2) path.lineTo((pix.width() + arrowwidth) / 2, (pix.height() - arrowheight) / 2) path.lineTo(pix.width() / 2, (pix.height() + arrowheight) / 2) path.lineTo((pix.width() - arrowwidth) / 2, (pix.height() - arrowheight) / 2) pnt.fillPath(path, Qt.black) pnt.end() self._inc.setIcon(QIcon(pix)) self._dec.setIcon(QIcon(QPixmap.fromImage(pix.toImage().mirrored())))
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
def data(self, index: QModelIndex, role: int, parent: QModelIndex = QModelIndex()): if role == Qt.DisplayRole: return str(self.get_word(index)) if role == Qt.DecorationRole: pixmap = QPixmap(self.ICON_DEFAULT_SIZE, self.ICON_DEFAULT_SIZE) quality = self.get_word(index).get_quality() green = max(min((quality * 255 * self.ICON_DEFAULT_BRIGHTNESS), 255), 0) red = max(min(((1.0 - quality) * 255 * self.ICON_DEFAULT_BRIGHTNESS), 255), 0) color = QColor(red, green, 0) pixmap.fill(color) icon = QIcon(pixmap) return icon
def __fillColorList(self, comboBox): index_black = 0 index = 0 for color in self.__colorList: if color == "black": index_black = index index += 1 pix = QPixmap(70, 20) pix.fill(QColor(color)) comboBox.addItem(QIcon(pix), None) comboBox.setIconSize(QSize(70, 20)) comboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents) comboBox.setCurrentIndex(index_black)
def missing_icon(): global _missing_icon if _missing_icon is None: p = QPixmap(ICON_SIZE, ICON_SIZE) p.fill(Qt.transparent) painter = QPainter(p) pal = QApplication.instance().palette() painter.setPen(QPen(pal.color(pal.Text), 0, Qt.DashLine)) margin = 3 r = p.rect().adjusted(margin, margin, -margin, -margin) painter.drawRect(r) painter.end() _missing_icon = QIcon(p) return _missing_icon
def _get_scaled_icon(self, icon): if icon.isNull(): return self.blank_icon # We need the icon scaled to 16x16 src = icon.pixmap(ICON_SIZE, ICON_SIZE) if src.width() == ICON_SIZE and src.height() == ICON_SIZE: return icon # Need a new version of the icon pm = QPixmap(ICON_SIZE, ICON_SIZE) pm.fill(Qt.transparent) p = QPainter(pm) p.drawPixmap(QPoint((ICON_SIZE - src.width()) / 2, (ICON_SIZE - src.height()) / 2), src) p.end() return QIcon(pm)
def color(self, val): val = unicode_type(val or '') col = QColor(val) orig = self._color if col.isValid(): self._color = val self.setText(val) p = QPixmap(self.iconSize()) p.fill(col) self.setIcon(QIcon(p)) else: self._color = None self.setText(self.choose_text) self.setIcon(QIcon()) if orig != col: self.color_changed.emit(self._color)
def fset(self, val): val = unicode(val or '') col = QColor(val) orig = self._color if col.isValid(): self._color = val self.setText(val) p = QPixmap(self.iconSize()) p.fill(col) self.setIcon(QIcon(p)) else: self._color = None self.setText(self.choose_text) self.setIcon(QIcon()) if orig != col: self.color_changed.emit(self._color)
def _generate_loading_map(self): text = 'Loading...' pixmap = QPixmap(self._w, self._h) pixmap.fill(self.palette().dark().color()) painter = QPainter(pixmap) painter.setRenderHint(QPainter.TextAntialiasing) font = QFont() font.setPixelSize(60) painter.setFont(font) painter.setPen(self.palette().text().color()) text_size = painter.fontMetrics().size(0, text) painter.drawText((self._w - text_size.width()) / 2, (self._h - text_size.height()) / 2, text_size.width(), text_size.height(), Qt.AlignCenter, text) painter.end() return pixmap
def fill_color_list(self, comboBox, valList, defVal): ''' 填充下拉菜单中的菜单项,使用colorList填充 ''' index_default = self.colorList.index(config.paint.DefaultColor) index = 0 for color in valList: if color == defVal: index_default = index index += 1 pix = QPixmap(70, 20) pix.fill(QColor(color)) comboBox.addItem(QIcon(pix), None) comboBox.setIconSize(QSize(70, 20)) comboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents) assert default_color != -1, '默认颜色在颜色列表中不存在!' comboBox.setCurrentIndex(index_default)
class ColorButton(QPushButton): changed = pyqtSignal() def __init__(self, data, name, text, parent): QPushButton.__init__(self, text, parent) self.ic = QPixmap(self.iconSize()) color = data[name] self.data, self.name = data, name if color is not None: self.current_color = read_color(color).color() self.ic.fill(self.current_color) else: self.ic.fill(Qt.transparent) self.current_color = color self.update_tooltip() self.setIcon(QIcon(self.ic)) self.clicked.connect(self.choose_color) def clear(self): self.current_color = None self.update_tooltip() self.ic.fill(Qt.transparent) self.setIcon(QIcon(self.ic)) self.data[self.name] = self.value self.changed.emit() def choose_color(self): col = QColorDialog.getColor(self.current_color or Qt.black, self, _("Choose color")) if col.isValid(): self.current_color = col self.update_tooltip() self.ic.fill(col) self.setIcon(QIcon(self.ic)) self.data[self.name] = self.value self.changed.emit() def update_tooltip(self): self.setToolTip( _("Red: {0} Green: {1} Blue: {2}").format(*self.current_color.getRgb()[:3]) if self.current_color else _("No color") ) @property def value(self): if self.current_color is None: return None return col_to_string(self.current_color)
class ColorButton(QPushButton): changed = pyqtSignal() def __init__(self, data, name, text, parent): QPushButton.__init__(self, text, parent) self.ic = QPixmap(self.iconSize()) color = data[name] self.data, self.name = data, name if color is not None: self.current_color = read_color(color).color() self.ic.fill(self.current_color) else: self.ic.fill(Qt.transparent) self.current_color = color self.update_tooltip() self.setIcon(QIcon(self.ic)) self.clicked.connect(self.choose_color) def clear(self): self.current_color = None self.update_tooltip() self.ic.fill(Qt.transparent) self.setIcon(QIcon(self.ic)) self.data[self.name] = self.value self.changed.emit() def choose_color(self): col = QColorDialog.getColor(self.current_color or Qt.black, self, _('Choose color')) if col.isValid(): self.current_color = col self.update_tooltip() self.ic.fill(col) self.setIcon(QIcon(self.ic)) self.data[self.name] = self.value self.changed.emit() def update_tooltip(self): self.setToolTip( _('Red: {0} Green: {1} Blue: {2}').format( *self.current_color.getRgb()[:3]) if self. current_color else _('No color')) @property def value(self): if self.current_color is None: return None return col_to_string(self.current_color)
class PlaybackSlider(QSlider, EntityBinder): _default = ''' PlaybackSlider { height: 60px } PlaybackSlider::add-page, PlaybackSlider::sub-page { background: none; } PlaybackSlider::handle { margin: -4px 0px -8px 0px; } ''' _deadline_color = { TaskState.QUEUED: QColor('#a3a3a3'), TaskState.SUSPENDED: QColor('#212121'), TaskState.RENDERING: QColor('#057907'), TaskState.COMPLETED: QColor('#055679'), TaskState.FAILED: QColor('#791e05'), TaskState.PENDDING: QColor('#795c05') } _crop_size = (8, 8, 10) _bar_height = 10 _handle_width = 8 def __init__(self): super().__init__(Qt.Horizontal) self._tasks = {} self._crop_path = None self._crop_brush = None self._bar_map = None self._setup_ui() state.on_changed('crop_range', self._update) state.on_changed('loop_range', self._update) state.on_changed('Crop', self._update) state.on_changed('Loop', self._update) state.on_changed('key', self._on_key_pressed) state.on_changed('caching', self._update_progress) state.on_changed('closeup_camera', self._update_progress) def _on_key_pressed(self): if not self.isVisible(): return key = state.get('key') if key == Qt.Key_Left: self._change_slider_position(-1) elif key == Qt.Key_Right: self._change_slider_position(1) else: return def _change_slider_position(self, step): slider_position = self.sliderPosition() slider_position += step if slider_position < self.minimum(): slider_position = self.maximum() elif slider_position > self.maximum(): slider_position = self.minimum() self.setSliderPosition(slider_position) def _update(self): if not state.get('caching') and self.isVisible(): self.update() def _setup_ui(self): self.setStyleSheet(self._default) self.setFocusPolicy(Qt.NoFocus) self._create_crop_elements() self._create_bar_map() def on_entity_changed(self, entity): self.bind_entity(entity, self._update_progress, modify=False) self._update_progress() def _create_crop_elements(self): cw, ch, _ = self._crop_size path = QPainterPath() path.moveTo(0, ch) path.lineTo(cw / 2, 0) path.lineTo(cw, ch) path.lineTo(0, ch) self._crop_path = path self._crop_brush = QBrush(self.palette().light().color()) def _create_bar_map(self): self._bar_map = QPixmap(self.width(), self.height()) self._paint_progress() def resizeEvent(self, event): self._create_bar_map() def _update_progress(self): if state.get('caching') or not self.isVisible(): return progress = self._entity.get_cache_progress() if isinstance(progress, tuple): offset_tasks = {} offset_frame = state.get('offset_frame') for k, v in progress[1].items(): offset_tasks[k - offset_frame] = v self._tasks = offset_tasks self._paint_progress() self._update() def _paint_progress(self): if self._bar_map is None: return self._bar_map.fill(Qt.transparent) painter = QPainter(self._bar_map) w = self.width() hw = self._handle_width w -= hw h = self.height() if self.maximum() == 0: tw = 0 else: tw = w / self.maximum() hh = self._bar_height painter.translate(hw / 2, 0) painter.fillRect( QRect(0, (h - hh) / 2, w, hh), self.palette().dark().color() ) shot = state.get('current_shot') job = state.get('current_job') body_mode = state.get('body_mode') if shot is not None and body_mode is BodyMode.PLAYBACK: progress = self._entity.get_cache_progress() t_color = self.palette().midlight().color() c_color = QColor('#DB2A71') sf, ef = shot.frame_range closeup_camera = state.get('closeup_camera') if isinstance(progress, tuple): progress = {} progress_thumb = progress.get(CameraCacheType.THUMBNAIL, []) progress_origin = progress.get(CameraCacheType.ORIGINAL, []) is_closeup = closeup_camera and closeup_camera in progress_origin i = 0 for f in range(sf, ef + 1): if f in progress_thumb: alpha = progress_thumb[f] if alpha > 1.0: alpha = 1.0 t_color.setAlphaF(float(alpha)) painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), t_color ) if is_closeup and f in progress_origin[closeup_camera]: painter.fillRect( QRect(i * tw, (h - hh) / 2 - 2, math.ceil(tw), 2), c_color ) i += 1 elif job is not None and body_mode is BodyMode.MODEL: progress, tasks = self._entity.get_cache_progress() t_color = self.palette().midlight().color() i = 0 for f in job.frames: if f in progress: painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), t_color ) elif f in tasks: task_state = tasks[f] painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), self._deadline_color[task_state] ) i += 1 painter.end() def paintEvent(self, evt): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) w = self.width() hw = self._handle_width w -= hw h = self.height() if self.maximum() == 0: tw = 0 else: tw = w / self.maximum() # bar map painter.drawPixmap(0, 0, self._bar_map) # crop painter.translate(hw / 2, 0) body_mode = state.get('body_mode') if state.get('Crop') or state.get('Loop'): cw, ch, oh = self._crop_size clip_range = 'crop_range' if body_mode is BodyMode.MODEL: clip_range = 'loop_range' sc, ec = state.get(clip_range) if sc is not None and ec is not None: painter.fillRect( tw * sc, h - ch - oh, tw * (ec - sc), ch / 2, self.palette().base().color() ) if sc is not None: painter.fillPath( self._crop_path.translated(tw * sc - cw / 2, h - ch - oh), self._crop_brush ) if ec is not None: painter.fillPath( self._crop_path.translated(tw * ec - cw / 2, h - ch - oh), self._crop_brush ) painter.translate(-hw / 2, 0) # normal super().paintEvent(evt) frames = state.get('frames') fm = painter.fontMetrics() text = str(frames[self.value()]) width = fm.width(text) x = self.value() * tw - width / 2 + hw / 2 x_max_width = self.width() - width if x < 0: x = 0 elif x > x_max_width: x = x_max_width painter.drawText( x, 0, width, 20, Qt.AlignCenter, text )
def update_color(self): # self.setPalette(QPalette(color)); # This variant does not work for TableWidgetItems pixmap = QPixmap(self.width(), self.height()) pixmap.fill(self.color) self.setPixmap(pixmap)
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): ''' 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 # 画板不再为空
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()
def _set_color(self, color): pixmap = QPixmap(self.iconSize()) pixmap.fill(color) self.setIcon(QIcon(pixmap)) self.valueChanged.emit(color.getRgb())
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
def __init__(self, noun: Noun, option: WordWidgetOption = None, parent: QObject = None, **kwargs): super().__init__(noun, option, parent, **kwargs) self.l_gender_title = QLabel(self.NOUN_GENDER_LABEL_TEXT) self.l_nounsn_title = QLabel(self.NOUNSN_LABEL_TEXT) self.l_nounpl_title = QLabel(self.NOUNPL_LABEL_TEXT) self.cmb_gender = QComboBox() self.le_nounsn = QLineEdit() self.le_nounpl = QLineEdit() self.lgr_word = QGridLayout() px_red = QPixmap(self.ICON_DEFAULT_SIZE, self.ICON_DEFAULT_SIZE) px_green = QPixmap(self.ICON_DEFAULT_SIZE, self.ICON_DEFAULT_SIZE) px_blue = QPixmap(self.ICON_DEFAULT_SIZE, self.ICON_DEFAULT_SIZE) px_yellow = QPixmap(self.ICON_DEFAULT_SIZE, self.ICON_DEFAULT_SIZE) px_red.fill(Qt.red) px_green.fill(Qt.green) px_blue.fill(Qt.blue) px_yellow.fill(Qt.yellow) ico_red = QIcon(px_red) ico_green = QIcon(px_green) ico_blue = QIcon(px_blue) ico_yellow = QIcon(px_yellow) ico_red.addPixmap(px_red, QIcon.Disabled) ico_green.addPixmap(px_green, QIcon.Disabled) ico_blue.addPixmap(px_blue, QIcon.Disabled) ico_yellow.addPixmap(px_yellow, QIcon.Disabled) self.cmb_gender.addItem(ico_blue, GrammaticalGender.MASCULINE.name) self.cmb_gender.addItem(ico_green, GrammaticalGender.NEUTRAL.name) self.cmb_gender.addItem(ico_red, GrammaticalGender.FEMININE.name) self.cmb_gender.addItem(ico_yellow, GrammaticalGender.PLURAL.name) self.lgr_word.addWidget(self.l_wordedit_title, 0, 0, 1, 3, Qt.AlignHCenter) self.lgr_word.addLayout(self.lhb_cmdbtns, 1, 0, 1, 3) self.lgr_word.addWidget(self.l_guid_title, 2, 0) self.lgr_word.addWidget(self.l_gender_title, 3, 0) self.lgr_word.addWidget(self.l_nounsn_title, 4, 0) self.lgr_word.addWidget(self.l_nounpl_title, 5, 0) self.lgr_word.addWidget(self.l_guid, 2, 1, 1, 2) self.lgr_word.addWidget(self.cmb_gender, 3, 1, 1, 2) self.lgr_word.addWidget(self.le_nounsn, 4, 1, 1, 2) self.lgr_word.addWidget(self.le_nounpl, 5, 1, 1, 2) self.lgr_word.setColumnStretch(0, 10) self.lgr_word.setColumnStretch(1, 12) self.lgr_word.setColumnStretch(2, 12) self.lgr_word.setColumnStretch(3, 66) self.lgr_word.setRowStretch(0, 10) self.lgr_word.setRowStretch(6, 90) self.setLayout(self.lgr_word) self.noun = noun self.init_editmode() self.cmb_gender.currentIndexChanged.connect(self.handle_cmb_gender_textchange)
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()
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 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 #画板不再为空
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
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()
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): 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
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