[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyQt] Fwd: QAbstractVideoSurface RTP player
From:       Dennis Jensen <djensen () pgcontrols ! com>
Date:       2019-11-18 14:40:15
Message-ID: 6f0d08dc-3b02-23fb-b65c-53d9b50d4b3c () pgcontrols ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hey Fran while I cannot help you personally with this issue I have a 
couple of advanced students that have already resolved much of this 
video implementation in python-pyqt5 and if you shoot me a message on 
Discord at either `DenniO#8137` and/or `DeJoker#1460` I can get you 
introduced to them and they can probably help you get everything sorted 
out.  Otherwise good luck in solving this.

On 11/18/2019 3:24 AM, Fran Raga wrote:
> hi all
>
> I'm trying to play a video via RTP but strange things happen.
>
> The video plays but not always and does not return any error message. 
> Sometimes when I open it it works and another does not
>
> I don't know if I'm missing a flag or I'm doing it wrong.
>
> Any suggestion about this?
>
> this is my code
>
> import sys
> import os
> from PyQt5.QtGui import *
> from PyQt5.QtWidgets import *
> from PyQt5.QtCore import *
> from PyQt5.QtNetwork import *
> from PyQt5.QtMultimedia import *
> from PyQt5.QtMultimediaWidgets import *
> import time
>
> fileName = 'rtp://127.0.0.1:8888 <http://127.0.0.1:8888>'
>
>
> class VideoWidgetSurface(QAbstractVideoSurface):
>
>     def __init__(self, widget, parent=None):
>         super(VideoWidgetSurface, self).__init__(parent)
>
>         self.widget = widget
>         self.imageFormat = QImage.Format_Invalid
>
>     def supportedPixelFormats(self, 
> handleType=QAbstractVideoBuffer.NoHandle):
>         formats = [QVideoFrame.PixelFormat()]
>         if (handleType == QAbstractVideoBuffer.NoHandle):
>             for f in [QVideoFrame.Format_RGB32,
>             QVideoFrame.Format_ARGB32,
>             QVideoFrame.Format_ARGB32_Premultiplied,
>             QVideoFrame.Format_RGB565,
>             QVideoFrame.Format_RGB555
>             ]:
>                 formats.append(f)
>         return formats
>
>     def isFormatSupported(self, _format):
>         imageFormat = 
> QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat())
>         size = _format.frameSize()
>         _bool = False
>         if (imageFormat != QImage.Format_Invalid and not \
>         size.isEmpty() and _format.handleType() == 
> QAbstractVideoBuffer.NoHandle):
>             _bool = True
>         return _bool
>
>     def start(self, _format):
>         imageFormat = 
> QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat())
>         size = _format.frameSize()
>         if (imageFormat != QImage.Format_Invalid and not size.isEmpty()):
>             self.imageFormat = imageFormat
>             self.imageSize = size
>             self.sourceRect = _format.viewport()
>             QAbstractVideoSurface.start(self, _format)
>             self.widget.updateGeometry()
>             self.updateVideoRect()
>             return True
>         else:
>             return False
>
>     def stop(self):
>         self.currentFrame = QVideoFrame()
>         self.targetRect = QRect()
>         QAbstractVideoSurface.stop(self)
>         self.widget.update()
>
>     def present(self, frame):
>         if (self.surfaceFormat().pixelFormat() != frame.pixelFormat() 
> or self.surfaceFormat().frameSize() != frame.size()):
> self.setError(QAbstractVideoSurface.IncorrectFormatError)
>             self.stop()
>             return False
>         else:
>             self.currentFrame = frame
>             self.widget.repaint(self.targetRect)
>             return True
>
>     def videoRect(self):
>         return self.targetRect
>
>     def updateVideoRect(self):
>         size = self.surfaceFormat().sizeHint()
>         size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio)
>         self.targetRect = QRect(QPoint(0, 0), size)
> self.targetRect.moveCenter(self.widget.rect().center())
>
>     def paint(self, painter):
>         try:  # maybe raise no �cruuentFrame� error
>             if (self.currentFrame.map(QAbstractVideoBuffer.ReadOnly)):
>                 oldTransform = painter.transform()
>
>             if (self.surfaceFormat().scanLineDirection() == 
> QVideoSurfaceFormat.BottomToTop):
>                 painter.scale(1, -1);
>                 painter.translate(0, -self.widget.height())
>
>             image = QImage(self.currentFrame.bits(), 
> self.currentFrame.width(), \
>                 self.currentFrame.height(), 
> self.currentFrame.bytesPerLine(), self.imageFormat)
>
>             painter.drawImage(self.targetRect, image, self.sourceRect)
>             painter.setTransform(oldTransform)
>
>             self.currentFrame.unmap()
>         except Exception as e:
>             print("Error paint : " , str(e))
>             pass
>
>
> class VideoWidget(QWidget):
>
>     def __init__(self, parent=None):
>         super(VideoWidget, self).__init__(parent)
>
>         self.setAutoFillBackground(False)
>         self.setAttribute(Qt.WA_NoSystemBackground, True)
>         self.setAttribute(Qt.WA_PaintOnScreen, True)
>         palette = self.palette()
>         palette.setColor(QPalette.Background, Qt.black)
>         self.setPalette(palette)
>         self.setSizePolicy(QSizePolicy.MinimumExpanding, 
> QSizePolicy.MinimumExpanding)
>         self.surface = VideoWidgetSurface(self)
>
>     def videoSurface(self):
>         return self.surface
>
>     def closeEvent(self, event):
>         del self.surface
>
>     def sizeHint(self):
>         return self.surface.surfaceFormat().sizeHint()
>
>     def paintEvent(self, event):
>         painter = QPainter(self)
> painter.setRenderHint(QPainter.HighQualityAntialiasing)
>         print ("surface active : ", self.surface.isActive())
>         if (self.surface.isActive()):
>             self.surface.paint(painter)
>         else:
>             painter.fillRect(event.rect(), self.palette().window())
>
>     def resizeEvent(self, event):
>         QWidget.resizeEvent(self, event)
>         self.surface.updateVideoRect()
>
>
> class VideoPlayer(QWidget):
>
>     def __init__(self, parent=None):
>         super(VideoPlayer, self).__init__(parent)
>
>         self.mediaPlayer = QMediaPlayer(None, 
> QMediaPlayer.VideoSurface or QMediaPlayer.StreamPlayback)
>         self.videoWidget = VideoWidget()
>         self.openButton = QPushButton("Open...")
>         self.openButton.clicked.connect(self.openFile)
>         self.playButton = QPushButton()
>         self.playButton.setEnabled(False)
> self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
>         self.playButton.clicked.connect(self.play)
>
>         self.positionSlider = QSlider(Qt.Horizontal)
>         self.positionSlider.setRange(0, 0)
> self.positionSlider.sliderMoved.connect(self.setPosition)
>         self.controlLayout = QHBoxLayout()
>         self.controlLayout.setContentsMargins(0, 0, 0, 0)
>         self.controlLayout.addWidget(self.openButton)
>         self.controlLayout.addWidget(self.playButton)
>         self.controlLayout.addWidget(self.positionSlider)
>         layout = QVBoxLayout()
>         layout.addWidget(self.videoWidget)
>         layout.addLayout(self.controlLayout)
>
>         self.setLayout(layout)
>
> self.mediaPlayer.setVideoOutput(self.videoWidget.videoSurface())
> self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
> self.mediaPlayer.positionChanged.connect(self.positionChanged)
> self.mediaPlayer.durationChanged.connect(self.durationChanged)
>
>         url = QUrl(fileName)
>         media = QMediaContent(url)
>
>         self.mediaPlayer.setMedia(media)
>         self.playButton.setEnabled(True)
>         time.sleep(.300)
>         self.mediaPlayer.play()
>
>     def openFile(self):
>         file_name = QFileDialog.getOpenFileName(self, "Open Movie", 
> QDir.homePath())[0]
>         if os.path.exists(file_name):
> self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(file_name)))
>             self.playButton.setEnabled(True)
>
>     def play(self):
>         if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
>             self.mediaPlayer.pause()
>         else:
>             self.mediaPlayer.play()
>
>     def mediaStateChanged(self, state):
>         if state == QMediaPlayer.PlayingState:
> self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
>         else:
> self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
>
>     def positionChanged(self, position):
>         self.positionSlider.setValue(position)
>
>     def durationChanged(self, duration):
>         self.positionSlider.setRange(0, duration)
>
>     def setPosition(self, position):
>         self.mediaPlayer.setPosition(position)
>
>
> if __name__ == '__main__':
>     app = QApplication(sys.argv)
>
>     player = VideoPlayer()
>     player.setGeometry(100, 300, 600, 380)
>     player.setFixedSize(QSize(600, 600))  # setFixedSize(QSize)
>     player.show()
>
>     sys.exit(app.exec_())
>
>
> And for start server I'm using
>
> ffmpeg -fflags +genpts -stream_loop -1 -re -i "C:\Users\Fran 
> Raga\Desktop\video_test\Cheyenne.ts" -f rtp_mpegts -c copy -map 0:v 
> -map 0:a -map 0:d rtp://127.0.0.1:8888 <http://127.0.0.1:8888>
>
> thanks
>
> *Francisco Raga** | *Full-Stack Open Source GIS Developer
> Móvil: (+34) 654275432*| *e-Mail: franka1986@gmail.com 
> <mailto:franka1986@gmail.com> *| *skype: francisco_raga
> Github: https://goo.gl/ydNTjY*|*Linkedin: 
> https://goo.gl/TCfj8S*|*Site: https://goo.gl/qiypDj
>
> "La vida real no tiene ningún mapa.."  Ivy Compton Burnett
>
> _______________________________________________
> PyQt mailing list    PyQt@riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt

[Attachment #5 (text/html)]

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Hey Fran while I cannot help you personally with this issue I
      have a couple of advanced students that have already resolved much
      of this video implementation in python-pyqt5 and if you shoot me a
      message on Discord at either `DenniO#8137` and/or `DeJoker#1460` I
      can get you introduced to them and they can probably help you get
      everything sorted out.  Otherwise good luck in solving this.<br>
    </p>
    <div class="moz-cite-prefix">On 11/18/2019 3:24 AM, Fran Raga wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAKuFJPpU2jbTbp-PPXzLw_CfOmW+r0DBjFAnCDCQ5xfnGpUm3A@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div class="gmail_quote">
          <div dir="ltr">hi all
            <div><br>
            </div>
            <div>I'm trying to play a video via RTP but strange things
              happen.<br>
              <br>
            </div>
            <div>The video plays but not always and does not return any
              error message. Sometimes when I open it it works and
              another does not<br>
              <br>
              I don't know if I'm missing a flag or I'm doing it wrong.</div>
            <div><br>
              Any suggestion about this?</div>
            <div><br>
            </div>
            <div>this is my code</div>
            <div><br>
            </div>
            <div>import sys<br>
              import os<br>
              from PyQt5.QtGui import *<br>
              from PyQt5.QtWidgets import *<br>
              from PyQt5.QtCore import *<br>
              from PyQt5.QtNetwork import *<br>
              from PyQt5.QtMultimedia import *<br>
              from PyQt5.QtMultimediaWidgets import *<br>
              import time<br>
              <br>
              fileName = 'rtp://<a href="http://127.0.0.1:8888"
                target="_blank" moz-do-not-send="true">127.0.0.1:8888</a>'<br>
              <br>
              <br>
              class VideoWidgetSurface(QAbstractVideoSurface):<br>
              <br>
                  def __init__(self, widget, parent=None):<br>
                      super(VideoWidgetSurface, self).__init__(parent)<br>
                      <br>
                      self.widget = widget<br>
                      self.imageFormat = QImage.Format_Invalid<br>
                  <br>
                  def supportedPixelFormats(self,
              handleType=QAbstractVideoBuffer.NoHandle):<br>
                      formats = [QVideoFrame.PixelFormat()]<br>
                      if (handleType == QAbstractVideoBuffer.NoHandle):<br>
                          for f in [QVideoFrame.Format_RGB32,<br>
                          QVideoFrame.Format_ARGB32,<br>
                          QVideoFrame.Format_ARGB32_Premultiplied,<br>
                          QVideoFrame.Format_RGB565,<br>
                          QVideoFrame.Format_RGB555<br>
                          ]:<br>
                              formats.append(f)<br>
                      return formats<br>
                  <br>
                  def isFormatSupported(self, _format):<br>
                      imageFormat =
              QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat())<br>
                      size = _format.frameSize()<br>
                      _bool = False<br>
                      if (imageFormat != QImage.Format_Invalid and not \<br>
                      size.isEmpty() and _format.handleType() ==
              QAbstractVideoBuffer.NoHandle):<br>
                          _bool = True<br>
                      return _bool<br>
                  <br>
                  def start(self, _format):<br>
                      imageFormat =
              QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat())<br>
                      size = _format.frameSize()<br>
                      if (imageFormat != QImage.Format_Invalid and not
              size.isEmpty()):<br>
                          self.imageFormat = imageFormat<br>
                          self.imageSize = size<br>
                          self.sourceRect = _format.viewport()<br>
                          QAbstractVideoSurface.start(self, _format)<br>
                          self.widget.updateGeometry()<br>
                          self.updateVideoRect()<br>
                          return True<br>
                      else:<br>
                          return False<br>
                  <br>
                  def stop(self):<br>
                      self.currentFrame = QVideoFrame()<br>
                      self.targetRect = QRect()<br>
                      QAbstractVideoSurface.stop(self)<br>
                      self.widget.update()<br>
                  <br>
                  def present(self, frame):<br>
                      if (self.surfaceFormat().pixelFormat() !=
              frame.pixelFormat() or self.surfaceFormat().frameSize() !=
              frame.size()):<br>
                         
              self.setError(QAbstractVideoSurface.IncorrectFormatError)<br>
                          self.stop()<br>
                          return False<br>
                      else:<br>
                          self.currentFrame = frame<br>
                          self.widget.repaint(self.targetRect)<br>
                          return True<br>
                  <br>
                  def videoRect(self):<br>
                      return self.targetRect<br>
                  <br>
                  def updateVideoRect(self):<br>
                      size = self.surfaceFormat().sizeHint()<br>
                      size.scale(self.widget.size().boundedTo(size),
              Qt.KeepAspectRatio)<br>
                      self.targetRect = QRect(QPoint(0, 0), size)<br>
                     
              self.targetRect.moveCenter(self.widget.rect().center())<br>
                  <br>
                  def paint(self, painter):<br>
                      try:  # maybe raise no �cruuentFrame� error<br>
                          if
              (self.currentFrame.map(QAbstractVideoBuffer.ReadOnly)):<br>
                              oldTransform = painter.transform()<br>
                      <br>
                          if (self.surfaceFormat().scanLineDirection()
              == QVideoSurfaceFormat.BottomToTop):<br>
                              painter.scale(1, -1);<br>
                              painter.translate(0,
              -self.widget.height())<br>
                      <br>
                          image = QImage(self.currentFrame.bits(),
              self.currentFrame.width(), \<br>
                              self.currentFrame.height(),
              self.currentFrame.bytesPerLine(), self.imageFormat)<br>
                      <br>
                          painter.drawImage(self.targetRect, image,
              self.sourceRect)<br>
                          painter.setTransform(oldTransform)<br>
                      <br>
                          self.currentFrame.unmap()<br>
                      except Exception as e:<br>
                          print("Error paint : " , str(e))<br>
                          pass<br>
              <br>
              <br>
              class VideoWidget(QWidget):<br>
              <br>
                  def __init__(self, parent=None):<br>
                      super(VideoWidget, self).__init__(parent)<br>
                      <br>
                      self.setAutoFillBackground(False)<br>
                      self.setAttribute(Qt.WA_NoSystemBackground, True)<br>
                      self.setAttribute(Qt.WA_PaintOnScreen, True)<br>
                      palette = self.palette()<br>
                      palette.setColor(QPalette.Background, Qt.black)<br>
                      self.setPalette(palette)<br>
                      self.setSizePolicy(QSizePolicy.MinimumExpanding,
              QSizePolicy.MinimumExpanding)<br>
                      self.surface = VideoWidgetSurface(self)<br>
                  <br>
                  def videoSurface(self):<br>
                      return self.surface<br>
                  <br>
                  def closeEvent(self, event):<br>
                      del self.surface<br>
                  <br>
                  def sizeHint(self):<br>
                      return self.surface.surfaceFormat().sizeHint()<br>
                  <br>
                  def paintEvent(self, event):<br>
                      painter = QPainter(self)<br>
                     
              painter.setRenderHint(QPainter.HighQualityAntialiasing)<br>
                      print ("surface active : ",
              self.surface.isActive())<br>
                      if (self.surface.isActive()):<br>
                          self.surface.paint(painter)<br>
                      else:<br>
                          painter.fillRect(event.rect(),
              self.palette().window())<br>
                      <br>
                  def resizeEvent(self, event):<br>
                      QWidget.resizeEvent(self, event)<br>
                      self.surface.updateVideoRect()<br>
              <br>
              <br>
              class VideoPlayer(QWidget):<br>
              <br>
                  def __init__(self, parent=None):<br>
                      super(VideoPlayer, self).__init__(parent)<br>
                      <br>
                      self.mediaPlayer = QMediaPlayer(None,
              QMediaPlayer.VideoSurface or QMediaPlayer.StreamPlayback)<br>
                      self.videoWidget = VideoWidget()<br>
                      self.openButton = QPushButton("Open...")<br>
                      self.openButton.clicked.connect(self.openFile)<br>
                      self.playButton = QPushButton()<br>
                      self.playButton.setEnabled(False)<br>
                     
              self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))<br>
  self.playButton.clicked.connect(self.play)<br>
                      <br>
                      self.positionSlider = QSlider(Qt.Horizontal)<br>
                      self.positionSlider.setRange(0, 0)<br>
                     
              self.positionSlider.sliderMoved.connect(self.setPosition)<br>
                      self.controlLayout = QHBoxLayout()<br>
                      self.controlLayout.setContentsMargins(0, 0, 0, 0)<br>
                      self.controlLayout.addWidget(self.openButton)<br>
                      self.controlLayout.addWidget(self.playButton)<br>
                      self.controlLayout.addWidget(self.positionSlider)<br>
                      layout = QVBoxLayout()<br>
                      layout.addWidget(self.videoWidget)<br>
                      layout.addLayout(self.controlLayout)<br>
              <br>
                      self.setLayout(layout)<br>
              <br>
                     
              self.mediaPlayer.setVideoOutput(self.videoWidget.videoSurface())<br>
                     
              self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)<br>
                     
              self.mediaPlayer.positionChanged.connect(self.positionChanged)<br>
                     
              self.mediaPlayer.durationChanged.connect(self.durationChanged)<br>
              <br>
                      url = QUrl(fileName)<br>
                      media = QMediaContent(url)<br>
              <br>
                      self.mediaPlayer.setMedia(media)<br>
                      self.playButton.setEnabled(True)<br>
                      time.sleep(.300)<br>
                      self.mediaPlayer.play()<br>
              <br>
                  def openFile(self):<br>
                      file_name = QFileDialog.getOpenFileName(self,
              "Open Movie", QDir.homePath())[0]<br>
                      if os.path.exists(file_name):<br>
                         
              self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(file_name)))<br>
  self.playButton.setEnabled(True)<br>
              <br>
                  def play(self):<br>
                      if self.mediaPlayer.state() ==
              QMediaPlayer.PlayingState:<br>
                          self.mediaPlayer.pause()<br>
                      else:<br>
                          self.mediaPlayer.play()<br>
                  <br>
                  def mediaStateChanged(self, state):<br>
                      if state == QMediaPlayer.PlayingState:<br>
                         
              self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))<br>
  else:<br>
                         
              self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))<br>
  <br>
                  def positionChanged(self, position):<br>
                      self.positionSlider.setValue(position)<br>
                  <br>
                  def durationChanged(self, duration):<br>
                      self.positionSlider.setRange(0, duration)<br>
                  <br>
                  def setPosition(self, position):<br>
                      self.mediaPlayer.setPosition(position)<br>
              <br>
              <br>
              if __name__ == '__main__':<br>
                  app = QApplication(sys.argv)<br>
                  <br>
                  player = VideoPlayer()<br>
                  player.setGeometry(100, 300, 600, 380)<br>
                  player.setFixedSize(QSize(600, 600))  #
              setFixedSize(QSize)<br>
                  player.show()<br>
                  <br>
                  sys.exit(app.exec_())<br>
              <br>
              <br>
              And for start server I'm using </div>
            <div><br>
            </div>
            <div>ffmpeg -fflags +genpts -stream_loop -1 -re -i
              "C:\Users\Fran Raga\Desktop\video_test\Cheyenne.ts" -f
              rtp_mpegts -c copy -map 0:v -map 0:a -map 0:d rtp://<a
                href="http://127.0.0.1:8888" target="_blank"
                moz-do-not-send="true">127.0.0.1:8888</a></div>
            <div><br>
            </div>
            <div>thanks</div>
            <div><br>
              <div>
                <div dir="ltr" data-smartmail="gmail_signature">
                  <div dir="ltr">
                    <div dir="ltr">
                      <div dir="ltr">
                        <div dir="ltr">
                          <div dir="ltr">
                            <div dir="ltr">
                              <div><font size="1"><b>Francisco Raga</b></font><b
                                  style="font-size:x-small"> | </b><span
                                  style="font-size:x-small">Full-Stack </span><span
                                  style="font-size:x-small">Open Source </span><span
                                  style="font-size:x-small">GIS
                                  Developer </span></div>
                              <div><span style="font-size:x-small">    </span></div>
                              <div><font size="1">Móvil: (+34) 654275432<b>
                                    | </b>e-Mail: <a
                                    href="mailto:franka1986@gmail.com"
                                    target="_blank"
                                    moz-do-not-send="true">franka1986@gmail.com</a>
                                  <b>| </b>skype: francisco_raga<br>
                                  Github: <a
                                    href="https://goo.gl/ydNTjY"
                                    target="_blank"
                                    \
                moz-do-not-send="true">https://goo.gl/ydNTjY</a></font><span
                                  style="font-size:x-small"> </span><b><span
                                    style="font-size:x-small">|</span><span
                                    style="font-size:x-small"> </span></b><span
                                  style="font-size:x-small">Linkedin: </span><a
                                  href="https://goo.gl/TCfj8S"
                                  style="font-size:x-small"
                                  target="_blank" \
                moz-do-not-send="true">https://goo.gl/TCfj8S</a><span
                                  style="font-size:x-small"> </span><b><span
                                    style="font-size:x-small">|</span><span
                                    style="font-size:x-small"> </span></b><span
                                  style="font-size:x-small">Site: </span><a
                                  href="https://goo.gl/qiypDj"
                                  style="font-size:x-small"
                                  target="_blank" \
moz-do-not-send="true">https://goo.gl/qiypDj</a></div>  <div><font size="1"><br>
                                  "La vida real no tiene ningún mapa.."
                                   Ivy Compton Burnett</font></div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" \
wrap="">_______________________________________________ PyQt mailing list    <a \
class="moz-txt-link-abbreviated" \
href="mailto:PyQt@riverbankcomputing.com">PyQt@riverbankcomputing.com</a> <a \
class="moz-txt-link-freetext" \
href="https://www.riverbankcomputing.com/mailman/listinfo/pyqt">https://www.riverbankcomputing.com/mailman/listinfo/pyqt</a>
 </pre>
    </blockquote>
  </body>
</html>


[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic