I'm new to Kivy so still learning how to make content with the library. My question is related to the widgets and layouts. I'm trying to create some kind of 3D visualizer with OpenGL and just started looking at the built-in examples 3DRendering you can check it here.
I've changed the Original Example and in the class Renderer(Widget) i've added a method for reposition the widget itself:
def reposition_b1(self, *args):
self.pos = self.x, self.height / 2 - self.height / 2
and in the RendererApp Class within the build method:
def build(self):
b = BoxLayout(orientation='horizontal')
r1= Renderer()
r1.reposition_b1(500)
r2= Renderer()
b.add_widget(r1)
b.add_widget(r2)
return b
So from what I understand about Kivy it should give the next result (The magenta color in the background is just a reference):expected result
But instead I just got a single 3D model in the visualizer. Any Hints about what I'm missing?
Related
i want know how to connect two QSpinBox with condition when we change the value of one of them the second one changed
i tried this using Qt designer
self.spinA.valueChanged['int'].connect(self.spinB.setValue)
the value is always the same ; i tried to connect label to spinA and use its value to get new value for spinB but i don't know how to do the same to change spinA value based on spinB value
and sorry for my english ; i can explain better with my native language
Add action to the first spin box for every value changed in the spin box, inside the action change the value of second spin box according to the relation between the values, do same for the second spin box as well below is the sample code.
importing libraries
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
# setting title
self.setWindowTitle("Python ")
# setting geometry
self.setGeometry(100, 100, 600, 400)
# calling method
self.UiComponents()
# showing all the widgets
self.show()
# method for widgets
def UiComponents(self):
# creating spin box
self.spin1 = QSpinBox(self)
# setting geometry to spin box
self.spin1.setGeometry(100, 100, 150, 40)
# setting prefix to spin
self.spin1.setPrefix("Width : ")
# add action to this spin box
self.spin1.valueChanged.connect(self.action_spin1)
# creating another spin box
self.spin2 = QSpinBox(self)
# setting geometry to spin box
self.spin2.setGeometry(300, 100, 150, 40)
# setting prefix to spin box
self.spin2.setPrefix("Height : ")
# add action to this spin box
self.spin2.valueChanged.connect(self.action_spin2)
# method called after editing finished
def action_spin1(self):
# getting current value of spin box
current = self.spin1.value()
self.spin2.setValue(current)
# method called after editing finished
def action_spin2(self):
# getting current value of spin box
current = self.spin2.value()
self.spin1.setValue(current)
create pyqt5 app
App = QApplication(sys.argv)
create the instance of our Window
window = Window()
start the app
sys.exit(App.exec())
While playing around with different ways to show a webcam feed (obtained using imageio/ffmpeg) in a PyQt4 window, I stumbled upon this answer. After implementing this in Python 2.7 as an ImageDisplayWidget class (as summarized below), everything seems to work just fine: A window opens, showing my webcam feed without a glitch. If I close the window, everything is stopped and closed neatly.
But... Whenever I click anywhere outside this PyQt window (while it is showing the webcam feed), causing it to lose focus, Python.exe crashes with an unhandled win32 exception. The same happens when I try to resize the window.
I am probably making some kind of exceedingly silly beginner's mistake, but I just don't see it. Can anyone point me in the right direction? Am I breaking some basic rule of (Py)Qt or even Python?
Here's a minimal example:
import sys
import numpy
from PIL import Image, ImageQt # pillow
from PyQt4 import QtGui, QtCore
class DummyVideoGrabber(QtCore.QTimer):
signal_image_available = QtCore.pyqtSignal(QtGui.QImage)
def __init__(self):
super(DummyVideoGrabber, self).__init__()
self.timeout.connect(self.update_image)
self.counter = 0
def update_image(self):
# Dummy rgb image (in reality we get a numpy array from imageio's Reader)
self.counter += 1
numpy_image = numpy.zeros(shape=(480, 640, 3), dtype=numpy.int8)
numpy_image[:, :, self.counter%3] = 255
qt_image = ImageQt.ImageQt(Image.fromarray(numpy_image, mode='RGB'))
# Emit image
self.signal_image_available.emit(qt_image)
class ImageDisplayWidget(QtGui.QWidget):
"""
Custom widget that displays an image using QPainter.
Mostly copied from: https://stackoverflow.com/a/22355028/4720018
"""
def __init__(self, size_wxh=None, parent=None):
super(ImageDisplayWidget, self).__init__(parent)
self.image = QtGui.QImage()
def set_image(self, qimage, resize_window=False):
self.image = qimage
self.repaint()
def paintEvent(self, QPaintEvent):
if not self.image:
return
painter = QtGui.QPainter(self)
painter.drawImage(self.rect(), self.image, self.image.rect())
app = QtGui.QApplication(sys.argv)
# instantiate a display object
display = ImageDisplayWidget()
display.resize(640, 480)
display.show()
# instantiate a grabber object
grabber = DummyVideoGrabber()
grabber.signal_image_available.connect(display.set_image)
grabber.start(100) # timer interval in ms
# start the event loop
app.exec_()
I found that the crash can be prevented by adding a wasActiveWindow flag (initialized to True in the constructor) and encapsulating the drawImage() call in some logic like so:
if self.isActiveWindow():
if self.wasActiveWindow:
painter.drawImage(self.rect(), self.image, self.image.rect())
self.wasActiveWindow = True
else:
self.wasActiveWindow = False
However, resizing the window still crashes python.
Problem solved by keeping a reference to the qt_image as self.qt_image:
...
# Emit image
self.qt_image = ImageQt.ImageQt(Image.fromarray(numpy_image, mode='RGB'))
self.signal_image_available.emit(self.qt_image)
...
This way it works as it should. Don't need the self.wasActiveWindow workaround anymore.
Still not sure why not keeping a reference would lead to a low-level python crash though...
im trying to make tkinter window that shows an image
but when i opens the image in the tkinter window - part of the image is shown below the taskbar of windows,
and because of that i can`t see the bottom part of the image
im showing the photo with label (its a part of screen - sharing program, every second another image is showed on the tkinter window)
** the size of the photo is as the size of the all screen
im not sure that my code is really necessary, my question is just how to set tkinter above the taskbar of windows.. :)
def ShowImage():
global root
root = Tkinter.Tk()
try:
label = Tkinter.Label(root)
label.pack()
img = None
tkimg = [None] # This, or something like it, is necessary because if you do not keep a reference to PhotoImage instances, they get garbage collected.
delay = 2 # in milliseconds
def loopCapture():
#print "capturing"
global im
while im==None:
continue
img = im
tkimg[0] = ImageTk.PhotoImage(img)
label.config(image=tkimg[0])
root.update_idletasks()
root.after(delay, loopCapture)
loopCapture()
I'd recommend you to read about toplevel in Tkinter. Add a top level from the root, and it will be on top of everything else on the screen.
Hopefully this will help you, Yahli.
Am currently learning kivy, and am working on a simple ToDo list app just to build my knowledge about kivy but am stuck i need help please. Here is the full python codes and kv codes file link respectively, https://pastebin.com/92eMd776 (python codes), https://pastebin.com/g5cgUJ94 (kv file). My problem is on line 55 of the python file the "list_button" method in the "InputListWidget" class.
def list_button(self, list_):
print list_
self.remove_widget(self.input_layout_property)#removes the box_layout widget that contains the
list_view = Factory.ListUnEditedMode() #create an instance of the dynamic class ListUnEditedMode from #Factory
list_view.item_strings = list_ #then update the item_strings with the list_ values
self.add_widget(list_view) #To add the list_view widget
Then the kv file.:
<ListUnEditedMode#BoxLayout>:
show_list_property: list_view
ListView:
id: list_view
color: [0, 0, 0, 1]
item_strings: []
When the list button is clicked it clears the "box_layout" that contains the "text_input" field widget, then adds the "ListUneditedMode(Box_layout)" widget that contains the "ListView" widget, i succeeded in doing that, the instance of the kivy dynamic class - "ListUneditedMode" is created from Factory. The main problem is, i want the list values contained in the "list_" argument of the "list_button" method to update the "item_strings" variable.. Please any help will be greatly appreciated. Thanks (please forgive the unorganized way my codes are written, am just a newbie in kivy, python and programming as a whole)
Did you not write all that pretty code yourself? Right now it just seems to me you want to change line 59 to ist_view.item_strings = list_. Otherwise, explain what you want in more detail.
In my application a user interacts with a 3D volumetric rendering. The data is quite noisy, but there are objects of interest buried in the noise. My users are able to get a good geometric sense of these objects by rotating and panning the scene.
Resolution is still crucial and I might be willing to trade it off for smoothness of interaction. Can I disable or at least modify this downsampling/lowering-of-resolution that accompanies scene interaction?
I've been asked to show my code.. I'll show some pieces.
class Display(HasTraits)
def __init__(self, list_of_MySourceObjects , list_of_corresponding_MyScenes )
...
def default_traits_view(self):
traits_view=View(HGroup( *list_ofMyScenes ) ##Allows variable number of scenes in view
...
class SomeSensibleCoordinateClass(HasTraits):
#Some logic for coordinate callbacks and manipulation
...
####Custom class that knows how to plot on scenes####
class MySourceObject(SomeSensibleCoordinateClass):
...
###I'll show a sample plotting function
def display_on_small_scene(self,scene):
self.origin=-self.radius.__array__()*self.spacing
print 'origin is',self.origin
self.small_array_src=ArraySource(scene,spacing=self.spacing,origin=self.origin)
self.scene=scene#for debug
self.set_scene_patch()### (re)sets self.array_src data
scene.mayavi_scene.add_child(self.array_src)
self.volume=self.array_src.add_module(self.vol_module)
scene.draw_axes(self.array_src.scalar_data.shape)
...
class MyScene(MlabSceneModel):
volume=Instance(Volume,())
some_other_custom_parameters = Any()
...
##Some default picking behavior
def picker_callback(self...):
...
##Some default aesthetics
def draw_axes(self,...):