Animated gif with wxpython phoenix - python-2.7

I was trying to put an animated gif in a wxpython panel but apparently there is no animarion nor adv package in my wxpython version:
In [1]: import wx
In [2]: wx.version()
Out[2]: '4.0.1 gtk3 (phoenix)'
Then i tried to use the gif as a wx.Bitmap but of course it would not play. I know that according to phoenix documention:
https://wxpython.org/Phoenix/docs/html/classic_vs_phoenix.html
the gif handler class is MISSING, but i was wondering if there is any way to use a gif (threding maybe?) in phoenix.

wx.adv contains Animation and AnimationCtrl
Ripped out of the demo's
import wx
from wx.adv import Animation, AnimationCtrl
class TestPanel(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1)
sizer = wx.BoxSizer(wx.VERTICAL)
anim = Animation('/home/rolf/loveyourjob5qj.gif')
ctrl = AnimationCtrl(self, -1, anim)
ctrl.Play()
sizer.Add(ctrl)
self.SetSizerAndFit(sizer)
self.Show()
if __name__ == '__main__':
test=wx.App()
TestPanel(None)
test.MainLoop()

Related

Usage of ExportXML and ImportXML using RichTextXMLhandler in Wxpython 4.0

I have building simple application using the Richtextctrl in wxPython 4.0.0a1(Latest version) and using python 2.7.
I have tried to save the buffer content using richtextxmlhandler with savestrem method, but in the latest version wxpython savestrem methon is not available.
so. i used the ExportXML,but i am getting errors. please any example on usage of Exportxml in rich text is helpful.
Thanks in advance.
The RichTextCtrl had the SaveStream method removed in Phoenix. So now you need to use SaveFile:
# wxPython Phoenix / Python 3 Version
import wx
import wx.richtext
from io import BytesIO
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='Richtext Test')
sizer = wx.BoxSizer(wx.VERTICAL)
self.rt = wx.richtext.RichTextCtrl(self)
self.rt.SetMinSize((300,200))
save_button = wx.Button(self, label="Save")
save_button.Bind(wx.EVT_BUTTON, self.on_save)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.rt, 1, wx.EXPAND|wx.ALL, 6)
sizer.Add(save_button, 0, wx.EXPAND|wx.ALL, 6)
self.SetSizer(sizer)
self.Show()
def on_save(self, event):
out = BytesIO()
handler = wx.richtext.RichTextXMLHandler()
rt_buffer = self.rt.GetBuffer()
handler.SaveFile(rt_buffer, out)
self.xml_content = out.getvalue()
print(self.xml_content)
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
You can read more about SaveFile here:
https://wxpython.org/Phoenix/docs/html/wx.richtext.RichTextCtrl.html#wx.richtext.RichTextCtrl.SaveFile
I also updated my blog article on this topic here:
https://www.blog.pythonlibrary.org/2015/07/10/wxpython-extracting-xml-from-the-richtextctrl/

Binding keyboard shortcuts to GLCanvas in wxPython

Is it possible to bind keyboard shortcuts (like Ctrl+z to Undo, Ctrl+Shift+z to Redo, Ctrl+c, Ctrl+v, etc.) to GLCanvas in wxpython? If so, can someone provide a minimal example, maybe something like drawing a sphere on single-click and then Undo and Redo with a shortcut?
import wx
from wx import glcanvas
class myFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='test')
self.gl = MyCanvasBase(self)
self.Show()
class MyCanvasBase(glcanvas.GLCanvas):
def __init__(self, parent):
glcanvas.GLCanvas.__init__(self, parent, -1, style=wx.WANTS_CHARS)
self.Bind(wx.EVT_CHAR, self.OnKeyDown) # for wx.WANTS_CHARS
# self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
def OnKeyDown(self, evt):
keycode = evt.GetKeyCode()
print keycode
if __name__ == '__main__':
app = wx.App(0)
Frame = myFrame()
app.MainLoop()
app.Destroy()
(edit) control+c etc can be captured by setting window style to wx.WANTS_CHARS. I made changes to use that style.
This is my attempt to make a minimum example of capturing key down events but without cube.
Have you looked at wxphython demo? That is one of the best learning sources of wxpython. If you install wxPython2.8-win32-docs-demos-2.8.12.1.exe, you will find an OpenGL sample code with a cube that you can rotate with mouse.

wxPython can't properly position a matplotlib block

I've taken the code to draw a rectangle over image form here, and modified it a little bit to suite my purposes. The only problem I have, it doesn't appear to be full screen, even though I make fr.ShowFullScreen(True). There is a grey area around the image.
Edited code is below (the rectangle part is not relevant):
# Use the wxPython backend of matplotlib
import matplotlib
matplotlib.use('WXAgg')
# Matplotlib elements used to draw the bounding rectangle
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
# wxPython stuff for the demo
import wx
class RectangleSelectImagePanel(wx.Panel):
def __init__(self, parent, pathToImage=None):
# Initialise the parent
wx.Panel.__init__(self, parent)
# Intitialise the matplotlib figure
self.figure = Figure(figsize=(20,15), dpi=80)
# Create an axes, turn off the labels and add them to the figure
self.axes = self.figure.add_subplot(1, 1, 1)
self.axes.set_axis_off()
# Add the figure to the wxFigureCanvas
self.canvas = FigureCanvas(self, -1, self.figure)
# Sizer to contain the canvas
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas, 0, wx.ALL)
self.SetSizer(self.sizer)
self.Fit()
def setImage(self, pathToImage):
'''Sets the background image of the canvas'''
import matplotlib.image as mpimg
# Load the image into matplotlib
image = matplotlib.image.imread(pathToImage)
# left in as anchor for image size
self.imageSize = image.shape[0:2]
print self.imageSize
#
# Add the image to the figure and redraw the canvas. Also ensure the aspect ratio of the image is retained.
self.axes.imshow(image, interpolation="quadric", aspect='auto')
self.canvas.draw()
if __name__ == "__main__":
# Create an demo application
app = wx.App()
# Create a frame and a RectangleSelectorPanel
fr = wx.Frame(None, title='test')
panel = RectangleSelectImagePanel(fr)
# Set the image in the panel
from matplotlib.cbook import get_sample_data
imgpath = get_sample_data('logo2.png', asfileobj=False)
panel.setImage(imgpath)
# Start the demo app
fr.ShowFullScreen(True)
app.MainLoop()
probably what you need is subplots_adjust.
from pylab import *
from matplotlib.cbook import get_sample_data
imgpath = get_sample_data('logo2.png', asfileobj=False)
image = matplotlib.image.imread(imgpath)
imshow(image, aspect='auto')
subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
This will produce a plot that has no margin around the image.
So, if you put
self.figure.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
after imshow line, you will get something closer to what you need.
Then, you will probably have to adjust the figsize parameter too. for my 1920 x 1080 display, I will need 1920.0/80 inch by 1080.0/80 inch so (24,13.5)

How can I make a hyperlink in kivy?

How can I make a link that opens a web browser in Kivy? I've tried just putting the url in a label, but of course that doesn't work. I'd like it to work on the android app specifically and allow users to click it to open a web browser to that link.
Use webbrowser, it works already on Desktop, and our toolchain for iOS / Android have implemented a backend for it. Ie, use it, it will just works everywhere:
import webbrowser
webbrowser.open("http://kivy.org/")
You'll need to make the text clickable with the ref markup tag (see the markup documentation for details), and then bind it to a function that opens a web browser at the right page. On the desktop you could use the webbrowser module, on android you'll want to call android's normal functions with pyjnius. There's a prewritten example of how to do so here.
This is something that will probably go in the plyer project, which would provide a cross-platform way to open the right web browser on any supported system with a single python interface. It's not added yet though.
Now i make It perfact code for hyper link...you just need to use insance and function here is code :
#import necessary library
import webbrowser
def any_Function(instance):
webbrowser.open('http://www.anywebsite.domain')
class TutorialApp(App):
def build(self):
btn1 = Button(text='Open Link' , size=(200,50), size_hint=(None, None))
btn1.bind(on_press=any_Function)
#Bind function with button
return btn1
if __name__ == '__main__':
TutorialApp().run()
I know this is an old thread, but it took me quite a while to work this out so I figured that maybe someone else down the road might benefit. It's far from perfect but I made a hyperlink widget.
from kivy.uix.label import Label
import webbrowser
"""A kivy widget that implements a hyperlink"""
class Hyperlink(Label):
def __init__(self, **kwargs):
self.target = kwargs.pop('target')
kwargs['markup'] = True
kwargs['color'] = (0,0,1,1)
kwargs['text'] = "[u][ref=link]{}[/ref][/u]".format(kwargs['text'])
kwargs['on_ref_press'] = self.link
super().__init__(**kwargs)
def link(self, *args):
webbrowser.open(self.target)
#import necessary library
from tkinter import Button
import webbrowser
from kivy.uix.button import Button
from kivy.app import App
def any_Function(instance):
webbrowser.open('http://www.anywebsite.domain')
class TutorialApp(App):
def build(self):
btn1 = Button(text='Open Link' , size=(200,50), size_hint=(None, None))
btn1.bind(on_press=any_Function)
#Bind function with button
return btn1
if __name__ == '__main__':
TutorialApp().run()

Events with QGraphicsItemGroup

In my application I want to use QGraphicsItemGroup for grouping items into one item.
I played with it a little and not sure using it because when I want to catch events, events are merged together but I want to handle specific event with specific child.
How can I achieve this?
You need to call QGraphicsItemGroup::setHandlesChildEvents(false). This stops the QGraphicsItemGroup trying to handle the event, and lets the child QGraphicsItems handle them instead.
I think that's the point of the QGraphicsItemGroup. Judging from the documentation, this is meant to simplify moving and transforming multiple items at once e.g. imagine the following case: a user draws a selection rectangle around several items in an application because he wants to move all of them. Perhaps what you want more is to create a hierarchy of items, e.g. have one parent item with several child items. This way you'll get the individual events for each item. This can be accomplished by calling QGraphicsItem::setParentItem();
The question doesn't specify which version of Qt is concerned and there is a correct answer for Qt4. Here is an answer for Qt5 (it works for PyQt5 and I guess it'll work also in C++). The solution was to reimplement sceneEvent, reimplementing a specialized event-catcher such as contextMenuEvent was not sufficient.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtWidgets
class GraphicsItem(QtWidgets.QGraphicsItem):
def __init__(self,
rect: QtCore.QRectF,
name: str,
parent: QtWidgets.QGraphicsItem = None):
super().__init__(parent)
self._name = name
self._rect = rect
def boundingRect(self):
return self._rect
def paint(self,
painter: QtGui.QPainter,
option: QtWidgets.QStyleOptionGraphicsItem,
widget: QtWidgets.QWidget = None):
painter.setPen(QtGui.QPen(QtCore.Qt.NoPen))
painter.setBrush(QtGui.QBrush(QtCore.Qt.red))
painter.drawRect(self._rect)
def sceneEvent(self, event: QtCore.QEvent):
if (event.type() == QtCore.QEvent.GraphicsSceneContextMenu):
self.contextMenuEvent(event)
event.accept()
return True
def contextMenuEvent(self, event: QtWidgets.QGraphicsSceneContextMenuEvent):
print(f'contextMenuEvent in "{self._name}"')
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._scene = QtWidgets.QGraphicsScene()
layout = QtWidgets.QHBoxLayout()
self._view = QtWidgets.QGraphicsView(self._scene)
layout.addWidget(self._view)
self._widget = QtWidgets.QWidget()
self._widget.setLayout(layout)
group = QtWidgets.QGraphicsItemGroup()
self._scene.addItem(group)
scene_item = GraphicsItem(QtCore.QRectF(0, 0, 100, 100), 'in scene')
self._scene.addItem(scene_item)
group_item = GraphicsItem(QtCore.QRectF(150, 0, 100, 100), 'in group')
group.addToGroup(group_item)
group_item = GraphicsItem(QtCore.QRectF(300, 0, 100, 100), '2nd in group')
group.addToGroup(group_item)
self.setCentralWidget(self._widget)
self.setWindowTitle('contextMenuEvent with QGraphicsItemGroup')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.setGeometry(100, 100, 800, 500)
mainWindow.show()
sys.exit(app.exec_())