How to put texture on a sphere With Qt3D and PySide6? - pyside6

I am trying to put a texture on a sphere using PyQt3D with PySide6, but I am struggling. I have tried a lot of things, but the documentation is not precise at all about the classes and the methods that are supposed to be used.
Here is my attempt (the earthmap1k.jpg texture comes from here):
import sys
from PySide6.QtCore import QUrl
from PySide6.QtGui import QGuiApplication, QVector3D
from PySide6.Qt3DCore import Qt3DCore
from PySide6.Qt3DExtras import Qt3DExtras
from PySide6.Qt3DRender import Qt3DRender
class Window(Qt3DExtras.Qt3DWindow):
def __init__(self):
super().__init__()
# Camera
self.camera().lens().setPerspectiveProjection(80, 16 / 9, 0.1, 1000)
self.camera().setPosition(QVector3D(2, 0, 0))
self.camera().setViewCenter(QVector3D(0, 0, 0))
# Root entity
self.rootEntity = Qt3DCore.QEntity()
# Charger les images de texture
self.material = Qt3DExtras.QDiffuseSpecularMaterial(self.rootEntity)
diffuseTexture = Qt3DRender.QTextureImage()
diffuseUrl = QUrl('earthmap1k.jpg')
diffuseTexture.setSource(diffuseUrl)
self.material.setDiffuse(diffuseTexture)
# Sphere
self.sphereEntity = Qt3DCore.QEntity(self.rootEntity)
self.sphereMesh = Qt3DExtras.QSphereMesh()
self.sphereEntity.addComponent(self.sphereMesh)
self.sphereEntity.addComponent(self.material)
self.setRootEntity(self.rootEntity)
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
view = Window()
view.show()
sys.exit(app.exec())
This is not working, but I have no idea why at the moment. I want to use QDiffuseSpecularMaterial() because i will add other textures (specular and normal) later, and QDiffuseSpecularMapMaterial() is supposed to be deprecated, and is not working better.

Related

How can I get camera scrolling to work in Lua (using the PlayDate SDK)?

I have three issues with my PlayDate game, one big, two small:
#1 (small): I can't get camera scrolling to work;
#2 (small): I can't figure out how to not get circles to generate inside of eachother;
#3 (big): I have NO IDEA how to make a menu screen and have it change the songs (I haven't added the songs yet, I'm still writing them)
Here's my code:
import "CoreLibs/graphics"
import "CoreLibs/object"
import "CoreLibs/sprites"
import "CoreLibs/nineslice"
import "CoreLibs/timer"
import "CoreLibs/frameTimer"
import "config"
import "core/definitions"
import "core/cotton/all"
import "scripts/index"
import "core/lieb/all"
import "core/CoreGame"
bpm = 60
lastX = math.random(80, 320)
lastY = math.random(80, 160)
circles = {}
tf = playdate.geometry.affineTransform.new()
local circles = {}
local count = 0
function addCircle()
tf:rotate(math.random(360))
x, y = (tf * playdate.geometry.point.new(80, 0)):unpack()
x += lastX
y += lastY
local new_circle = playdate.graphics.drawCircleAtPoint(x, y, 40)
count = count + 1
table.insert(circles, new_circle)
lastX = x
lastY = y
playdate.graphics.setDrawOffset(x, y)
end
beatTimer = playdate.timer.performAfterDelay(60000 / bpm, addCircle)
beatTimer.repeats = true
function playdate.update()
playdate.timer.updateTimers()
end
For the menu, I know I should use grid view, but I don't know how to make things happen when something is selected, and different things when something else is selected.
For the scrolling, I want it so that you're always seeing the circles and they never go off screen, so I'm trying to change the camera's origin point to where the circles are, but it's not working.
And finally, #2 is pretty self explanatory.

Display opencv video with tkinter without recursion method

I have done real time face detection system, but I need to add gui for the program. Instead of using the solution from here. I does not want to read frame in a recursion way.
def show_frame():
_,frame = cap.read()
... #skip
lmain.after(10,show_frame)
It require a lot of refactoring in my previous code. So, I prefer read frame in a while loop way. But it does not work. Thanks for help.
import numpy as np
import cv2
import tkinter as tk
from PIL import Image, ImageTk
window = tk.Tk()
window.wm_title("Test")
imageFrame = tk.Frame(window, width=600, height=500)
imageFrame.grid(row=0, column=0, padx=10, pady=2)
#Capture video frames
lmain = tk.Label(imageFrame)
lmain.grid(row=0, column=0)
cap = cv2.VideoCapture(0)
def show_frame(frame):
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
# lmain.after(10, show_frame)
while True:
_,frame = cap.read()
show_frame(frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
window.mainloop()

Python kivy placing buttons/labels in different places using float layout

i am new to kivy, until now ive only used tkinter, however i want to create a app for android, so now ive moved to kivy.
i've seen that widgets works totally different in kivy, anyway i simply want to place labels and buttons on a screen, i've done this with other layouts but its said that a float layout is kinda like tkinter's .place()..... so i thought that this might work but unfortunately i just can't seem to find out how to place something at my choice on the screen. Here is the program on which i want to add the buttons and labels:
from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
from kivy.core.window import Window
class MyPaintWidget(Widget):
Window.clearcolor = (1, 1, 1, 1)
def on_touch_down(self, touch):
color = (0,0,0)
with self.canvas:
Color(*color, mode='hsv')
d = 10
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
touch.ud['line'] = Line(points=(touch.x, touch.y),width=5)
def on_touch_move(self, touch):
touch.ud['line'].points += [touch.x, touch.y]
class MyPaintApp(App):
def build(self):
parent = Widget()
self.painter = MyPaintWidget()
clearbtn = Button(text='Clear')
clearbtn.bind(on_release=self.clear_canvas)
parent.add_widget(self.painter)
parent.add_widget(clearbtn)
return parent
def clear_canvas(self, obj):
self.painter.canvas.clear()
MyPaintApp().run()
this creates a drawing screen, what i want is a sort of simulated 'contract' on which the user can sighn, but i can't figure out how to place the buttons and labels at my choice.
this question was already answered by zeeMonkeez:
Your example does not use FloatLayout. Have you looked at the documentation and played with the examples?
so for anybody who have the same problem heres the answer:
from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
class MyPaintWidget(Widget):
Window.clearcolor = (1, 1, 1, 1)
def on_touch_down(self, touch):
color = (0,0,0)
with self.canvas:
Color(*color, mode='hsv')
d = 3
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
touch.ud['line'] = Line(points=(touch.x, touch.y),width=1.5)
def on_touch_move(self, touch):
touch.ud['line'].points += [touch.x, touch.y]
class MyPaintApp(App):
def build(self):
parent = FloatLayout()
self.painter = MyPaintWidget()
a_button = Button(text = 'A button',pos=(20,20),size_hint=(.25,.25))
entry_name = TextInput()
parent.add_widget(self.painter)
parent.add_widget(a_button)
return parent
def clear_canvas(self, obj):
self.painter.canvas.clear()
MyPaintApp().run()

Can I check collide_widget using a list?

I am trying to make a game where you can move a character around screen and I had it so that if my character ran into a picture of a tree, the character would stop moving. After getting this to work, What I tried to do was change the code so instead of just using the tree widget, I wanted to iterate through a list of widgets, so that if my character runs into any of these, character stops moving. What's strange is that it works when I have only one widget in the list. I can also put list[0] or list[1] in my code and when my character will stop when encountering those widgets. But again, if I have more than one widget in the list and try to iterate through the list, it does not work, my character does not stop when encountering any of the widgets.
I'm wondering what I did wrong or how to fix this. Ultimately I want it so that if my character runs into any of the images in the list, the character will stop moving.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.behaviors import ButtonBehavior
from kivy.core.audio import SoundLoader
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import FallOutTransition
from kivy.clock import Clock
from kivy.graphics import Color
gamelayout = FloatLayout(size=(300, 300))
bglayout = FloatLayout()
characterselectionlayout = GridLayout(cols=2)
class Game(Screen):
class Bg(Image):
def __init__(self, **kwargs):
super(Bg, self).__init__(**kwargs)
self.allow_stretch = True
self.size_hint = (None, None)
self.size = (1440, 1440)
class Npcs(Image):
def __init__(self, **kwargs):
super(Npcs, self).__init__(**kwargs)
self.allow_stretch=True
class MoveableImage(Image):
def __init__(self, **kwargs):
super(MoveableImage, self).__init__(**kwargs)
self._keyboard = Window.request_keyboard(None, self)
if not self._keyboard:
return
self._keyboard.bind(on_key_down=self.on_keyboard_down)
self._keyboard.bind(on_key_up=self.on_keyboard_up)
self.y = (Window.height/2.1)
self.app = App.get_running_app()
def on_keyboard_down(self, keyboard, keycode, text, modifiers):
if keycode[1] == 'left':
self.source = 'selectionscreen/left.zip'
self.anim_delay=.20
if self.x < (Window.width * .25):
bglayout.x += 4
else:
for i in listofwidgets:
if self.collide_widget(i):
self.x -=0
else:
self.x -=6
elif keycode[1] == 'right':
self.source ='selectionscreen/right.zip'
self.anim_delay=.20
if self.x > (Window.width * .70):
bglayout.x -= 4
else:
for i in listofwidgets:
if self.collide_widget(i):
self.x += 0
else:
self.x += 6
else:
return False
return True
class gameApp(App):
def build(self):
global sm
sm = ScreenManager()
game = Game(name='game')
sm.add_widget(game)
global listofobject
listofobject = []
hero = MoveableImage(source='selectionscreen/right1.png', size_hint=(None,None), allow_stretch = False, size=(40, 65))
self.tree = Npcs(source='selectionscreen/tree.zip', allow_stretch=False, size_hint=(None,None), pos_hint={'x':.20, 'y':.30}, size=(50, 50), pos=(300, 300))
self.testdude = Npcs(source='selectionscreen/testdude.png', allow_stretch=False, size_hint=(None,None), pos_hint={'x':.60, 'y':.70}, size=(100, 124), pos=(800, 900))
listofwidgets.append(self.tree)
listofwidgets.append(self.testdude)
self.background=Bg(source='selectionscreen/background12.png', pos_hint={'x':0, 'y':0})
bglayout.add_widget(self.background)
bglayout.add_widget(self.tree)
bglayout.add_widget(self.testdude)
gamelayout.add_widget(bglayout)
gamelayout.add_widget(hero)
game.add_widget(gamelayout)
return sm
if __name__ == '__main__':
gameApp().run()
To answer your overall question...yes, there's no reason you shouldn't be able to.
Tracking down your problem will need more code though...at the moment your snippet doesn't make sense, because list isn't defined anywhere. Could you maybe post a short example that runs, or at least the full code you're using?
As a side note, list is not a good variable name because it overrides the list class instantiator which can be annoying or actively buggy later.

How to import and use scipy.spatial.distance functions correctly?

from scipy.spatial.distance import seuclidean #imports abridged
import scipy
img = np.asarray(Image.open("testtwo.tif").convert('L'))
img = 1 * (img < 127)
area = (img == 0).sum() # computing white pixel area
print area
areasplit = np.split(img, 24) # splitting image array
print areasplit
for i in areasplit:
result = (i == 0).sum()
print result #computing white pixel area for every single array
minimal = result.min()
maximal = result.max()
dist = seuclidian(minimal, maximal)
print dist
I want to compute distances between array elements, produced from splitting an image. Python can`t recognize the name of a distance functions (I have tried several of them and variuos approaches to importing modules). How to import and call these functions correctly? Thank you
You haven't stated what the error is, but you are using numpy as well and I can't see an import for that
Try
import numpy as np
import scipy
Then try
dist = scipy.spatial.distance.euclidian(minimal, maximal)
dists = scipy.spatial.distance.seuclidian(minimal, maximal, variances)
Note - the standardised euclidean distance takes a third parameter.

Resources