python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序

本文通过Python3+PyQt5实现《python Qt Gui 快速编程》这本书的page Designer应用程序,采用QGraphicsView,QGraphicsScene,QGraphicsItem,这个程序包含有多个文本,图片和框的页面。有些图形类在PyQt5已过时,所以本代码改动幅度比较大。主要的类或方法的改变如下:

QMatrix==>QTransform
setMatrix==>setTransform
rotate ==> setRotation

本例中,由于event.delta()已过时,还重写了wheelEvent方法:

def wheelEvent(self, event):
  #factor = 1.41 ** (-event.delta() / 240.0)
  #factor = 1.41 ** (-abs(event.startX()-event.y()) / 240.0)
  factor = event.angleDelta().y()/120.0
  if event.angleDelta().y()/120.0 > 0:
   factor=2
  else:
   factor=0.5
  self.scale(factor, factor)

为了保持代码可读行,增加了一个类:

class GraphicsPixmapItem(QGraphicsPixmapItem):  #add by yangrongdong
 def __init__(self,pixmap):
  super(QGraphicsPixmapItem, self).__init__(pixmap)

本例中还有包含菜单的按钮:

 if text == "&Align":
  menu = QMenu(self)
  for text, arg in (
     ("Align &Left", Qt.AlignLeft),
     ("Align &Right", Qt.AlignRight),
     ("Align &Top", Qt.AlignTop),
     ("Align &Bottom", Qt.AlignBottom)):
     wrapper = functools.partial(self.setAlignment, arg)
     self.wrapped.append(wrapper)
     menu.addAction(text, wrapper)
    button.setMenu(menu)

本例中还针对QStyleOptionGraphicsItem.levelOfDetail已过时,改写如下:

option.levelOfDetailFromTransform(self.transform())

下面为完整的代码:

#!/usr/bin/env python3

import functools
import random
import sys
from PyQt5.QtCore import (QByteArray, QDataStream, QFile, QFileInfo,
       QIODevice, QPoint, QPointF, QRectF, Qt)
from PyQt5.QtWidgets import (QApplication, QDialog,
        QDialogButtonBox, QFileDialog, QFontComboBox,
        QGraphicsItem, QGraphicsPixmapItem,
        QGraphicsScene, QGraphicsTextItem, QGraphicsView, QGridLayout,
        QHBoxLayout, QLabel, QMenu, QMessageBox,QPushButton, QSpinBox,
        QStyle, QTextEdit, QVBoxLayout)
from PyQt5.QtGui import QFont,QCursor,QFontMetrics,QTransform,QPainter,QPen,QPixmap
from PyQt5.QtPrintSupport import QPrinter,QPrintDialog

MAC = True
try:
 from PyQt5.QtGui import qt_mac_set_native_menubar
except ImportError:
 MAC = False

#PageSize = (595, 842) # A4 in points
PageSize = (612, 792) # US Letter in points
PointSize = 10

MagicNumber = 0x70616765
FileVersion = 1

Dirty = False

class TextItemDlg(QDialog):

 def __init__(self, item=None, position=None, scene=None, parent=None):
  super(QDialog, self).__init__(parent)

  self.item = item
  self.position = position
  self.scene = scene

  self.editor = QTextEdit()
  self.editor.setAcceptRichText(False)
  self.editor.setTabChangesFocus(True)
  editorLabel = QLabel("&Text:")
  editorLabel.setBuddy(self.editor)
  self.fontComboBox = QFontComboBox()
  self.fontComboBox.setCurrentFont(QFont("Times", PointSize))
  fontLabel = QLabel("&Font:")
  fontLabel.setBuddy(self.fontComboBox)
  self.fontSpinBox = QSpinBox()
  self.fontSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
  self.fontSpinBox.setRange(6, 280)
  self.fontSpinBox.setValue(PointSize)
  fontSizeLabel = QLabel("&Size:")
  fontSizeLabel.setBuddy(self.fontSpinBox)
  self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|
           QDialogButtonBox.Cancel)
  self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)

  if self.item is not None:
   self.editor.setPlainText(self.item.toPlainText())
   self.fontComboBox.setCurrentFont(self.item.font())
   self.fontSpinBox.setValue(self.item.font().pointSize())

  layout = QGridLayout()
  layout.addWidget(editorLabel, 0, 0)
  layout.addWidget(self.editor, 1, 0, 1, 6)
  layout.addWidget(fontLabel, 2, 0)
  layout.addWidget(self.fontComboBox, 2, 1, 1, 2)
  layout.addWidget(fontSizeLabel, 2, 3)
  layout.addWidget(self.fontSpinBox, 2, 4, 1, 2)
  layout.addWidget(self.buttonBox, 3, 0, 1, 6)
  self.setLayout(layout)

  self.fontComboBox.currentFontChanged.connect(self.updateUi)
  self.fontSpinBox.valueChanged.connect(self.updateUi)
  self.editor.textChanged.connect(self.updateUi)
  self.buttonBox.accepted.connect(self.accept)
  self.buttonBox.rejected.connect(self.reject)

  self.setWindowTitle("Page Designer - {0} Text Item".format(
    "Add" if self.item is None else "Edit"))
  self.updateUi()

 def updateUi(self):
  font = self.fontComboBox.currentFont()
  font.setPointSize(self.fontSpinBox.value())
  self.editor.document().setDefaultFont(font)
  self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(
    bool(self.editor.toPlainText()))

 def accept(self):
  if self.item is None:
   self.item = TextItem("", self.position, self.scene)
  font = self.fontComboBox.currentFont()
  font.setPointSize(self.fontSpinBox.value())
  self.item.setFont(font)
  self.item.setPlainText(self.editor.toPlainText())
  self.item.update()
  global Dirty
  Dirty = True
  QDialog.accept(self)

class TextItem(QGraphicsTextItem):
 def __init__(self, text, position, scene,
     font=QFont("Times", PointSize), matrix=QTransform()):
  super(TextItem, self).__init__(text)
  self.setFlags(QGraphicsItem.ItemIsSelectable|
      QGraphicsItem.ItemIsMovable)
  self.setFont(font)
  self.setPos(position)
  self.setTransform(matrix)
  scene.clearSelection()
  scene.addItem(self)
  self.setSelected(True)
  global Dirty
  Dirty = True

 def parentWidget(self):
  return self.scene().views()[0]

 def itemChange(self, change, variant):
  if change != QGraphicsItem.ItemSelectedChange:
   global Dirty
   Dirty = True
  return QGraphicsTextItem.itemChange(self, change, variant)

 def mouseDoubleClickEvent(self, event):
  dialog = TextItemDlg(self, self.parentWidget())
  dialog.exec_()

class GraphicsPixmapItem(QGraphicsPixmapItem):  #add by yangrongdong
 def __init__(self,pixmap):
  super(QGraphicsPixmapItem, self).__init__(pixmap)

class BoxItem(QGraphicsItem):

 def __init__(self, position, scene, style=Qt.SolidLine,
     rect=None, matrix=QTransform()):
  super(BoxItem, self).__init__()
  self.setFlags(QGraphicsItem.ItemIsSelectable|
      QGraphicsItem.ItemIsMovable|
      QGraphicsItem.ItemIsFocusable)
  if rect is None:
   rect = QRectF(-10 * PointSize, -PointSize, 20 * PointSize,
       2 * PointSize)
  self.rect = rect
  self.style = style
  self.setPos(position)
  self.setTransform(matrix)
  scene.clearSelection()
  scene.addItem(self)
  self.setSelected(True)
  self.setFocus()
  global Dirty
  Dirty = True

 def parentWidget(self):
  return self.scene().views()[0]

 def boundingRect(self):
  return self.rect.adjusted(-2, -2, 2, 2)

 def paint(self, painter, option, widget):
  pen = QPen(self.style)
  pen.setColor(Qt.black)
  pen.setWidth(1)
  if option.state & QStyle.State_Selected:
   pen.setColor(Qt.blue)
  painter.setPen(pen)
  painter.drawRect(self.rect)

 def itemChange(self, change, variant):
  if change != QGraphicsItem.ItemSelectedChange:
   global Dirty
   Dirty = True
  return QGraphicsItem.itemChange(self, change, variant)

 def contextMenuEvent(self, event):
  wrapped = []
  menu = QMenu(self.parentWidget())
  for text, param in (
    ("&Solid", Qt.SolidLine),
    ("&Dashed", Qt.DashLine),
    ("D&otted", Qt.DotLine),
    ("D&ashDotted", Qt.DashDotLine),
    ("DashDo&tDotted", Qt.DashDotDotLine)):
   wrapper = functools.partial(self.setStyle, param)
   wrapped.append(wrapper)
   menu.addAction(text, wrapper)
  menu.exec_(event.screenPos())

 def setStyle(self, style):
  self.style = style
  self.update()
  global Dirty
  Dirty = True

 def keyPressEvent(self, event):
  factor = PointSize / 4
  changed = False
  if event.modifiers() & Qt.ShiftModifier:
   if event.key() == Qt.Key_Left:
    self.rect.setRight(self.rect.right() - factor)
    changed = True
   elif event.key() == Qt.Key_Right:
    self.rect.setRight(self.rect.right() + factor)
    changed = True
   elif event.key() == Qt.Key_Up:
    self.rect.setBottom(self.rect.bottom() - factor)
    changed = True
   elif event.key() == Qt.Key_Down:
    self.rect.setBottom(self.rect.bottom() + factor)
    changed = True
  if changed:
   self.update()
   global Dirty
   Dirty = True
  else:
   QGraphicsItem.keyPressEvent(self, event)

class GraphicsView(QGraphicsView):

 def __init__(self, parent=None):
  super(GraphicsView, self).__init__(parent)
  self.setDragMode(QGraphicsView.RubberBandDrag)
  self.setRenderHint(QPainter.Antialiasing)
  self.setRenderHint(QPainter.TextAntialiasing)

 def wheelEvent(self, event):
  #factor = 1.41 ** (-event.delta() / 240.0)
  factor = event.angleDelta().y()/120.0
  if event.angleDelta().y()/120.0 > 0:
   factor=2
  else:
   factor=0.5
  self.scale(factor, factor)

class MainForm(QDialog):

 def __init__(self, parent=None):
  super(MainForm, self).__init__(parent)

  self.filename = ""
  self.copiedItem = QByteArray()
  self.pasteOffset = 5
  self.prevPoint = QPoint()
  self.addOffset = 5
  self.borders = []

  self.printer = QPrinter(QPrinter.HighResolution)
  self.printer.setPageSize(QPrinter.Letter)

  self.view = GraphicsView()
  self.scene = QGraphicsScene(self)
  self.scene.setSceneRect(0, 0, PageSize[0], PageSize[1])
  self.addBorders()
  self.view.setScene(self.scene)

  self.wrapped = [] # Needed to keep wrappers alive
  buttonLayout = QVBoxLayout()
  for text, slot in (
    ("Add &Text", self.addText),
    ("Add &Box", self.addBox),
    ("Add Pi&xmap", self.addPixmap),
    ("&Align", None),
    ("&Copy", self.copy),
    ("C&ut", self.cut),
    ("&Paste", self.paste),
    ("&Delete...", self.delete),
    ("&Rotate", self.rotate),
    ("Pri&nt...", self.print_),
    ("&Open...", self.open),
    ("&Save", self.save),
    ("&Quit", self.accept)):
   button = QPushButton(text)
   if not MAC:
    button.setFocusPolicy(Qt.NoFocus)
   if slot is not None:
    button.clicked.connect(slot)
   if text == "&Align":
    menu = QMenu(self)
    for text, arg in (
      ("Align &Left", Qt.AlignLeft),
      ("Align &Right", Qt.AlignRight),
      ("Align &Top", Qt.AlignTop),
      ("Align &Bottom", Qt.AlignBottom)):
     wrapper = functools.partial(self.setAlignment, arg)
     self.wrapped.append(wrapper)
     menu.addAction(text, wrapper)
    button.setMenu(menu)
   if text == "Pri&nt...":
    buttonLayout.addStretch(5)
   if text == "&Quit":
    buttonLayout.addStretch(1)
   buttonLayout.addWidget(button)
  buttonLayout.addStretch()

  layout = QHBoxLayout()
  layout.addWidget(self.view, 1)
  layout.addLayout(buttonLayout)
  self.setLayout(layout)

  fm = QFontMetrics(self.font())
  self.resize(self.scene.width() + fm.width(" Delete... ") + 50,
     self.scene.height() + 50)
  self.setWindowTitle("Page Designer")

 def addBorders(self):
  self.borders = []
  rect = QRectF(0, 0, PageSize[0], PageSize[1])
  self.borders.append(self.scene.addRect(rect, Qt.yellow))
  margin = 5.25 * PointSize
  self.borders.append(self.scene.addRect(
    rect.adjusted(margin, margin, -margin, -margin),
    Qt.yellow))

 def removeBorders(self):
  while self.borders:
   item = self.borders.pop()
   self.scene.removeItem(item)
   del item

 def reject(self):
  self.accept()

 def accept(self):
  self.offerSave()
  QDialog.accept(self)

 def offerSave(self):
  if (Dirty and QMessageBox.question(self,
       "Page Designer - Unsaved Changes",
       "Save unsaved changes?",
       QMessageBox.Yes|QMessageBox.No) ==
   QMessageBox.Yes):
   self.save()

 def position(self):
  point = self.mapFromGlobal(QCursor.pos())
  if not self.view.geometry().contains(point):
   coord = random.randint(36, 144)
   point = QPoint(coord, coord)
  else:
   if point == self.prevPoint:
    point += QPoint(self.addOffset, self.addOffset)
    self.addOffset += 5
   else:
    self.addOffset = 5
    self.prevPoint = point
  return self.view.mapToScene(point)

 def addText(self):
  dialog = TextItemDlg(position=self.position(),
        scene=self.scene, parent=self)
  dialog.exec_()

 def addBox(self):
  BoxItem(self.position(), self.scene)

 def addPixmap(self):
  path = (QFileInfo(self.filename).path()
   if self.filename else ".")
  fname,filetype = QFileDialog.getOpenFileName(self,
    "Page Designer - Add Pixmap", path,
    "Pixmap Files (*.bmp *.jpg *.png *.xpm)")
  if not fname:
   return
  self.createPixmapItem(QPixmap(fname), self.position())

 def createPixmapItem(self, pixmap, position, matrix=QTransform()):
  item = GraphicsPixmapItem(pixmap)
  item.setFlags(QGraphicsItem.ItemIsSelectable|
      QGraphicsItem.ItemIsMovable)
  item.setPos(position)
  item.setTransform(matrix)
  self.scene.clearSelection()
  self.scene.addItem(item)
  item.setSelected(True)
  global Dirty
  Dirty = True
  return item

 def selectedItem(self):
  items = self.scene.selectedItems()
  if len(items) == 1:
   return items[0]
  return None

 def copy(self):
  item = self.selectedItem()
  if item is None:
   return
  self.copiedItem.clear()
  self.pasteOffset = 5
  stream = QDataStream(self.copiedItem, QIODevice.WriteOnly)
  self.writeItemToStream(stream, item)

 def cut(self):
  item = self.selectedItem()
  if item is None:
   return
  self.copy()
  self.scene.removeItem(item)
  del item

 def paste(self):
  if self.copiedItem.isEmpty():
   return
  stream = QDataStream(self.copiedItem, QIODevice.ReadOnly)
  self.readItemFromStream(stream, self.pasteOffset)
  self.pasteOffset += 5

 def setAlignment(self, alignment):
  # Items are returned in arbitrary order
  items = self.scene.selectedItems()
  if len(items) <= 1:
   return
  # Gather coordinate data
  leftXs, rightXs, topYs, bottomYs = [], [], [], []
  for item in items:
   rect = item.sceneBoundingRect()
   leftXs.append(rect.x())
   rightXs.append(rect.x() + rect.width())
   topYs.append(rect.y())
   bottomYs.append(rect.y() + rect.height())
  # Perform alignment
  if alignment == Qt.AlignLeft:
   xAlignment = min(leftXs)
   for i, item in enumerate(items):
    item.moveBy(xAlignment - leftXs[i], 0)
  elif alignment == Qt.AlignRight:
   xAlignment = max(rightXs)
   for i, item in enumerate(items):
    item.moveBy(xAlignment - rightXs[i], 0)
  elif alignment == Qt.AlignTop:
   yAlignment = min(topYs)
   for i, item in enumerate(items):
    item.moveBy(0, yAlignment - topYs[i])
  elif alignment == Qt.AlignBottom:
   yAlignment = max(bottomYs)
   for i, item in enumerate(items):
    item.moveBy(0, yAlignment - bottomYs[i])
  global Dirty
  Dirty = True

 def rotate(self):
  for item in self.scene.selectedItems():
   item.setRotation(item.rotation()+30)

 def delete(self):
  items = self.scene.selectedItems()
  if (len(items) and QMessageBox.question(self,
    "Page Designer - Delete",
    "Delete {0} item{1}?".format(len(items),
    "s" if len(items) != 1 else ""),
    QMessageBox.Yes|QMessageBox.No) ==
    QMessageBox.Yes):
   while items:
    item = items.pop()
    self.scene.removeItem(item)
    del item
   global Dirty
   Dirty = True

 def print_(self):
  dialog = QPrintDialog(self.printer)
  if dialog.exec_():
   painter = QPainter(self.printer)
   painter.setRenderHint(QPainter.Antialiasing)
   painter.setRenderHint(QPainter.TextAntialiasing)
   self.scene.clearSelection()
   self.removeBorders()
   self.scene.render(painter)
   self.addBorders()

 def open(self):
  self.offerSave()
  path = (QFileInfo(self.filename).path()
    if self.filename else ".")
  fname,filetype = QFileDialog.getOpenFileName(self,
    "Page Designer - Open", path,
    "Page Designer Files (*.pgd)")
  if not fname:
   return
  self.filename = fname
  fh = None
  try:
   fh = QFile(self.filename)
   if not fh.open(QIODevice.ReadOnly):
    raise IOError(str(fh.errorString()))
   items = self.scene.items()
   while items:
    item = items.pop()
    self.scene.removeItem(item)
    del item
   self.addBorders()
   stream = QDataStream(fh)
   stream.setVersion(QDataStream.Qt_5_7)
   magic = stream.readInt32()
   if magic != MagicNumber:
    raise IOError("not a valid .pgd file")
   fileVersion = stream.readInt16()
   if fileVersion != FileVersion:
    raise IOError("unrecognised .pgd file version")
   while not fh.atEnd():
    self.readItemFromStream(stream)
  except IOError as e:
   QMessageBox.warning(self, "Page Designer -- Open Error",
     "Failed to open {0}: {1}".format(self.filename, e))
  finally:
   if fh is not None:
    fh.close()
  global Dirty
  Dirty = False

 def save(self):
  if not self.filename:
   path = "."
   fname,filetype = QFileDialog.getSaveFileName(self,
     "Page Designer - Save As", path,
     "Page Designer Files (*.pgd)")
   if not fname:
    return
   self.filename = fname
  fh = None
  try:
   fh = QFile(self.filename)
   if not fh.open(QIODevice.WriteOnly):
    raise IOError(str(fh.errorString()))
   self.scene.clearSelection()
   stream = QDataStream(fh)
   stream.setVersion(QDataStream.Qt_5_7)
   stream.writeInt32(MagicNumber)
   stream.writeInt16(FileVersion)
   for item in self.scene.items():
    self.writeItemToStream(stream, item)
  except IOError as e:
   QMessageBox.warning(self, "Page Designer -- Save Error",
     "Failed to save {0}: {1}".format(self.filename, e))
  finally:
   if fh is not None:
    fh.close()
  global Dirty
  Dirty = False

 def readItemFromStream(self, stream, offset=0):
  type = ""
  position = QPointF()
  matrix = QTransform()
  rotateangle=0#add by yangrongdong
  type=stream.readQString()
  stream >> position >> matrix
  if offset:
   position += QPointF(offset, offset)
  if type == "Text":
   text = ""
   font = QFont()
   text=stream.readQString()
   stream >> font
   rotateangle=stream.readFloat()
   tx=TextItem(text, position, self.scene, font, matrix)
   tx.setRotation(rotateangle)
  elif type == "Box":
   rect = QRectF()
   stream >> rect
   style = Qt.PenStyle(stream.readInt16())
   rotateangle=stream.readFloat()
   bx=BoxItem(position, self.scene, style, rect, matrix)
   bx.setRotation(rotateangle)
  elif type == "Pixmap":
   pixmap = QPixmap()
   stream >> pixmap
   rotateangle=stream.readFloat()
   px=self.createPixmapItem(pixmap, position, matrix)
   px.setRotation(rotateangle)

 def writeItemToStream(self, stream, item):
  if isinstance(item, TextItem):
   stream.writeQString("Text")
   stream<<item.pos()<< item.transform()
   stream.writeQString(item.toPlainText())
   stream<< item.font()
   stream.writeFloat(item.rotation())#add by yangrongdong
  elif isinstance(item, GraphicsPixmapItem):
   stream.writeQString("Pixmap")
   stream << item.pos() << item.transform() << item.pixmap()
   stream.writeFloat(item.rotation())#add by yangrongdong
  elif isinstance(item, BoxItem):
   stream.writeQString("Box")
   stream<< item.pos() << item.transform() << item.rect
   stream.writeInt16(item.style)
   stream.writeFloat(item.rotation())#add by yangrongdong

app = QApplication(sys.argv)
form = MainForm()
rect = QApplication.desktop().availableGeometry()
form.resize(int(rect.width() * 0.6), int(rect.height() * 0.9))
form.show()
app.exec_()

运行结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2018-04-19

对Python信号处理模块signal详解

Python中对信号处理的模块主要是使用signal模块,但signal主要是针对Unix系统,所以在Windows平台上Python不能很好的发挥信号处理的功能. 要查看Python中的信号量,可以使用dir(signal)来查看. signal.signal() 在signal模块中,主要是使用signal.signal()函数来预设信号处理函数 singnal.signal(signalnum, handler) 其中第一个参数是信号量,第二个参数信号处理函数. 下面看个简单的例子,其中

PYTHON实现SIGN签名的过程解析

sign签名是用于提供给外部(第三方)调用的接口,调用方需要提供正确的appkey钥匙才能调用,确保了接口的安全性. 签名参数sign生成方法: 假设有请求参数如下: appkey = "111222333" body = { "username": "Test", "Password": "123456", "mail": "", "sign":

python3+PyQt5+Qt Designer实现扩展对话框

本文是对<Python Qt GUI快速编程>的第9章的扩展对话框例子Find and replace用Python3+PyQt5+Qt Designer进行改写. 第一部分无借用Qt Designer,完全用代码实现. 第二部分则借用Qt Designer,快速实现. 第一部分: import sys from PyQt5.QtCore import Qt,pyqtSignal from PyQt5.QtWidgets import (QApplication, QCheckBox, QDi

python之线程通过信号pyqtSignal刷新ui的方法

第一部分:UI界面设计 界面效果图如下: ui文件(可拉动控件自行创建一个button和text) <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <pr

python3+PyQt5+Qt Designer实现堆叠窗口部件

本文是对<Python Qt GUI快速编程>的第9章的堆叠窗口例子Vehicle Rental用Python3+PyQt5+Qt Designer进行改写. 第一部分无借用Qt Designer,完全用代码实现. 第二部分则借用Qt Designer,快速实现. 第一部分: import sys from PyQt5.QtCore import (Qt) from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog, QDialo

浅析Python中signal包的使用

在liunx系统中要想每隔一分钟执行一个命令,最普遍的方法就是crontab了,如果不想使用crontab,经同事指点在程序中可以用定时器实现这种功能,于是就开始摸索了,发现需要一些信号的知识... 查看你的linux支持哪些信号:kill -l 即可 root@server:~# kill -l 1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP  6) SIGABRT  7) SIGBUS   8) SIGFPE   9) S

详解利用Python scipy.signal.filtfilt() 实现信号滤波

本文将以实战的形式基于scipy模块使用Python实现简单滤波处理,包括内容有1.低通滤波,2.高通滤波,3.带通滤波,4.带阻滤波器.具体的含义大家可以查阅大学课程,信号与系统.简单的理解就是低通滤波指的是去除高于某一阈值频率的信号:高通滤波去除低于某一频率的信号:带通滤波指的是类似低通高通的结合保留中间频率信号:带阻滤波也是低通高通的结合只是过滤掉的是中间部分.上面所说的内容会在实战部分加以介绍,可以对比理解一下. 如何实现的呢?我的理解,是通过时域转换为频域,在频域信号中去除相应频域信号

Python Web框架Flask信号机制(signals)介绍

信号(signals) Flask信号(signals, or event hooking)允许特定的发送端通知订阅者发生了什么(既然知道发生了什么,那我们可以知道接下来该做什么了). Flask提供了一些信号(核心信号)且其它的扩展提供更多的信号.信号是用于通知订阅者,而不应该鼓励订阅者修改数据.相关信号请查阅文档. 信号依赖于Blinker库. 钩子(hooks) Flask钩子(通常出现在蓝图或应用程序现存的方法中,比如一些内置装饰器,例如before_request)不需要Blinker

python web框架Flask实现图形验证码及验证码的动态刷新实例

下列代码都是以自己的项目实例讲述的,相关的文本内容很少,主要说明全在代码注释中 自制图形验证码 这里所说的图形验证码都是自制的图形,通过画布.画笔.画笔字体的颜色绘制而成的.将验证码封装成一个类比较好管理,代码里有绝对详细的注释,当然大家可以直接复制. 里面涉及的字体都是从系统电脑上自带的,大家直接复制当前目录下就可以了. 主目录/utils/captcha/__init__.py import random import string # Image:一个画布 # ImageDraw:一个画笔

Python Web框架Flask下网站开发入门实例

一.Flask简介 Flask 是一个 Python 实现的 Web 开发微框架.官网:http://flask.pocoo.org/ 二.Demo 1.代码结构 复制代码 代码如下: . ├── blog.py ├── static │   ├── css │   │   └── index.css │   ├── images │   │   ├── cat.jpg │   │   └── sheying1229.jpg │   └── js └── templates     ├── in

Python Web框架Flask中使用百度云存储BCS实例

对于部署在百度应用引擎BAE上的项目,使用百度云存储BCS(Baidu Cloud Storage)是不错的存储方案. 百度云存储已有Python SDK,对它进行简单封装后,就可以直接在Flask中使用了,项目代码见GitHub上Flask-BCS. 使用示例代码: 复制代码 代码如下: from flask import Flask from flask_bcs import BCS   BCS_HOST = 'BCS HOST' BCS_ACCESS_KEY = 'BCS Access K

Python Web框架Flask中使用七牛云存储实例

对于小型站点,使用七牛云存储的免费配额已足够为站点提供稳定.快速的存储服务 七牛云存储已有Python SDK,对它进行简单封装后,就可以直接在Flask中使用了,项目代码见GitHub上Flask-QiniuStorage. 使用示例代码: 复制代码 代码如下: from flask import Flask from flask_qiniustorage import Qiniu   QINIU_ACCESS_KEY = '七牛 Access Key' QINIU_SECRET_KEY =

Python Web框架Flask中使用新浪SAE云存储实例

对于部署在新浪应用引擎SAE上的项目,使用新浪SAE云存储是不错的存储方案. 新浪SAE云存储仅能在SAE环境中正常使用,对它进行简单封装后,可以直接在Flask中使用,项目代码见GitHub上Flask-SaeStorage. 使用示例代码: 复制代码 代码如下: from flask import Flask from flask_saestorage import SaeStorage   SAE_ACCESS_KEY = 'SAE Access Key' SAE_SECRET_KEY =

Python Web框架之Django框架Model基础详解

本文实例讲述了Python Web框架之Django框架Model基础.分享给大家供大家参考,具体如下: model是关于你的数据的单一的,确定的信息来源. 它包含您正在存储的数据的基本字段和行为.Django通过抽象化的模型层(models)为你的网络应用提供对于数据的结构化处理和操作处理,数据库相关的代码一般写在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,使用数据库API对数据库进行增删改查的操作. 使用哪种数据库,只需要在se

Python Web框架之Django框架cookie和session用法分析

本文实例讲述了Python Web框架之Django框架cookie和session用法.分享给大家供大家参考,具体如下: part 1 概念 在Django里面,cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话. 两者最大的区别是cookie的信息是存放在浏览器客户端的,而session是存放在服务器端的. 两者使用的方式都是request.COOKIES[XXX]和request.session[XXX],其中XXX是您想要取得的东西的key. Cooki

Python Web框架Tornado运行和部署

本文实例为大家分享了Python Web框架Tornado运行和部署的详细内容,供大家参考,具体内容如下 一.运行和部署 因为Tornado内置了自己的HTTPServer,运行和部署它与其他Python web框架不太一样.你需要写一个main()函数来启动服务,而不是配置一个WSGI容器来运行你的应用: def main(): app = make_app() app.listen(8888) IOLoop.current().start() if __name__ == '__main__

Python Web框架之Django框架Form组件用法详解

本文实例讲述了Python Web框架之Django框架Form组件用法.分享给大家供大家参考,具体如下: Form简介 在HTTP中,表单(form标签),是用来提交数据的,其action属性说明了其传输数据的方法:如何传.如何接收. 访问网站时,表单可以实现客户端与服务器之间的通信.例如查询,就用到了表单(其属性中,action=get). 再比如说注册与登陆,也是要用到表单的.但这里由于涉及到隐私问题,需要保证数据传输的安全性,因此其传输方法就应当使用post而非get. 总之,对客户端来