2015-11-05 72 views
0

我試圖在kivy中製作一種基本的照片編輯器。它應該允許放置和轉換基本圖像以及添加文本標籤。我正在使用scatters來實現這個功能,但是我遇到了一個問題,我無法獲得根分散符以匹配其子標籤或圖像的大小。這使得實際拖拽和縮放圖像和標籤變得困難,因爲每個圖像和標籤周圍都有不可見的散射空間,使得實際上不可能拖拽和調整所需的散射。Kivy:使散點圖的大小與小孩的標籤或圖像相同

這裏是我的Python代碼:

from kivy.app import App 
from kivy.uix.scatter import Scatter 
from kivy.uix.button import Button 
from kivy.uix.popup import Popup 
from kivy.uix.scatterlayout import ScatterLayout 
from kivy.uix.label import Label 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.anchorlayout import AnchorLayout 
from kivy.uix.textinput import TextInput 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.screenmanager import ScreenManager, Screen 
from kivy.uix.colorpicker import ColorPicker 
from kivy.logger import Logger 
from kivy.graphics import Color, Ellipse, Line 
from kivy.properties import ListProperty 
from kivy.properties import NumericProperty 
from kivy.properties import ObjectProperty 
from kivy.core.window import Window 
import os 
#from editor import PhotoEditor 
import random 

#Each class def is a different screen. 
class WelcomeScreen(Screen): 
    pass 

class PhoneSelection(Screen): 
    pass 

class StyleSelection(Screen): 
    pass 

class ColorSelection(Screen): 
    pass 

class DesignSelection(Screen): 
    pass 

class UploadPhoto(Screen): 
    pass 

class PatternSelection(Screen): 
    pass 

class PhotoEditor(Screen): 
    color = ListProperty([1,1,1,1]) 
    word = 'Enter Text' 
    font_size = 14 
    font_type = '' 
    image_path = 'Mike1.png' 
    erase = False 
    def open_popup(self): 
     popup = ColorPopup() 
     popup.open() 
    def close_popup(self): 
     color_bttn = self.ids['color_bttn'] 
     color_bttn.background_color = self.color 
     color_bttn.color = [1 - self.color[0], 1 - self.color[1], 1 - self.color[2], 1] 
    def open_text_entry(self): 
     al = AnchorLayout(anchor_x='center',anchor_y='top') 
     popup = TextLabelEntry() 
     al.add_widget(popup) 
     popup.open() 
    def close_text_entry(self): 
     l = Label(text=self.word,color=self.color,font_size=40) 
     t = TextLabel() 
     t.add_widget(l) 
     t.size = l.size 
     self.ids['il'].add_widget(t) 

class Confirm(Screen): 
    pass 

class Pay(Screen): 
    pass 

class ThankYou(Screen): 
    pass 

#These classes are used as parts of the UI for other screens. 
class ColorPopup(Popup): 
    pass 
class TextLabel(Scatter): 
    pass 
class TextLabelEntry(Popup): 
    fonts = [] 
    def font_selector(self): 
     for file in os.listdir("/mydir"): 
      if file.endswith(".tff"): 
       fonts.append(file) 

class ImageLabel(ScatterLayout): 
    pass 
class Variables(): 
    #used for storing info about the case to be printed 
    phone_type = "" 
    phone_color = "" 
    phone_style = "" 
    phone_design_option = "" 
    total_price = 0.0 

#This is the main class that has all the app info. 
class MainApp(App): 
    #Window.size = (1920, 1080) 
    #Window.fullscreen = True 
    #list of names for each screen. Each name is used as an ID when changing the current screen. 
    screens = ["welcome","choose_phone","choose_style","choose_color","choose_design","upload_photo","choose_pattern","photo_edit","confirm","pay","thanks"] 
    vars = Variables() 
    #The manager that holds all the screens and allows transitioning between them. 
    SM = ScreenManager() 
    def build(self): 
     #list of names for each screen. Each name is used as an ID when changing the current screen. 
     screens = ["welcome","choose_phone","choose_style","choose_color","choose_design","upload_photo","choose_pattern","photo_edit","confirm","pay","thanks"] 

     #Add all screens to the manager and assign the corresponding ID. 
     self.SM.add_widget(WelcomeScreen(name=screens[0])) 
     self.SM.add_widget(PhoneSelection(name=screens[1])) 
     self.SM.add_widget(StyleSelection(name=screens[2])) 
     self.SM.add_widget(ColorSelection(name=screens[3])) 
     self.SM.add_widget(DesignSelection(name=screens[4])) 
     self.SM.add_widget(UploadPhoto(name=screens[5])) 
     self.SM.add_widget(PatternSelection(name=screens[6])) 
     self.SM.add_widget(PhotoEditor(name=screens[7])) 
     self.SM.add_widget(Confirm(name=screens[8])) 
     self.SM.add_widget(Pay(name=screens[9])) 
     self.SM.add_widget(ThankYou(name=screens[10])) 

     #Set the current screen to the welcome screen. 
     self.SM.current = screens[0] 
     return self.SM 

#Runs the app. 
if __name__ == "__main__": 
    t = MainApp(); 
    t.run() 

大部分動作發生在PhotoEditor類。

這是我的kivy代碼:

<WelcomeScreen>: 
    AnchorLayout: 
     anchor_x: 'center' 
     anchor_y: 'bottom' 
     Button: 
      text: "Welcome!" 
      size_hint: 0.1,0.1 
      on_press: root.manager.current = app.screens[7] 

<PhoneSelection>: 
    BoxLayout: 
     Button: 
      text: "iPhone 4/4s" 
      on_press: 
       root.manager.current = app.screens[1] 
       app.vars.phone_type = "iPhone YAYAYA" 
       self.text = str(app.vars.phone_type) 

<PhotoEditor> 
    id: PhotoEditor 
    FloatLayout: 
     id: il 
     ImageLabel: 
      auto_bring_to_front: False 
      scale_min: 100/img.width 
      scale_max: 5000/img.width 
      id: ilr 
      Image: 
       id: img 
       source: root.image_path 
       #width: il.width 
       #height: il.height/self.image_ratio 
       on_touch_up: 
        if int(ilr.rotation % 15) < 8: ilr.rotation = int(ilr.rotation - int(ilr.rotation % 15)) 
        if int(ilr.rotation % 15) >= 8: ilr.rotation = int(ilr.rotation - int(ilr.rotation % 15)) + 15 
    Image: 
     id: ovrly 
     source: 'overlay/iphone6.png' 
    AnchorLayout: 
     anchor_x: 'left' 
     anchor_y: 'center' 
     BoxLayout: 
      size_hint: 0.1, 0.5 
      orientation: 'vertical' 
      Button: 
       text: 'Color' 
       color: [1 - root.color[0], 1 - root.color[1], 1 - root.color[2], 1] 
       background_color: root.color 
       background_normal: '' 
       id: color_bttn 
       on_press: root.open_popup() 
      Button: 
       group: 'text' 
       text: 'Text' 
       on_press: root.open_text_entry() 

<ColorPopup> 
    size_hint: .5, .5 
    auto_dismiss: False 
    title: 'Hello world' 
    on_open: 
     r.value = int(r.max * app.SM.get_screen('photo_edit').color[0]) 
     g.value = int(g.max * app.SM.get_screen('photo_edit').color[1]) 
     b.value = int(b.max * app.SM.get_screen('photo_edit').color[2]) 
    AnchorLayout: 
     anchor_x: 'center' 
     anchor_y: 'center' 
     AnchorLayout: 
      anchor_x: 'center' 
      anchor_y: 'center' 
      BoxLayout: 
       orientation: 'vertical' 
       Slider: 
        id: r 
        on_value: 
         app.SM.get_screen('photo_edit').color[0] = self.value_normalized 
         bttn.background_color = app.SM.get_screen('photo_edit').color 
         bttn.color = [1 - app.SM.get_screen('photo_edit').color[0], 1 - app.SM.get_screen('photo_edit').color[1], 1 - app.SM.get_screen('photo_edit').color[2], 1] 
       Slider: 
        id: g 
        on_value: 
         app.SM.get_screen('photo_edit').color[1] = self.value_normalized 
         bttn.background_color = app.SM.get_screen('photo_edit').color 
         bttn.color = [1 - app.SM.get_screen('photo_edit').color[0], 1 - app.SM.get_screen('photo_edit').color[1], 1 - app.SM.get_screen('photo_edit').color[2], 1] 
       Slider: 
        id: b 
        on_value: 
         app.SM.get_screen('photo_edit').color[2] = self.value_normalized 
         bttn.background_color = app.SM.get_screen('photo_edit').color 
         bttn.color = [1 - app.SM.get_screen('photo_edit').color[0], 1 - app.SM.get_screen('photo_edit').color[1], 1 - app.SM.get_screen('photo_edit').color[2], 1] 
       Button: 
        text: 'Close' 
        id: bttn 
        background_normal: '' 
        on_press: 
         app.SM.get_screen('photo_edit').close_popup() 
         root.dismiss() 


<ImageLabel> 

<TextLabel> 
    size: lbl.size 
    on_touch_down: if app.SM.get_screen('photo_edit').erase == True: app.SM.get_screen('photo_edit').remove_widget(self) 
    Label: 
     id: lbl 
     #on_size: root.size = self.size 

<TextLabelEntry> 
    size_hint: 0.5,0.5 
    title: 'Text Entry' 
    auto_dismiss: True 
    on_open: 
     app.SM.get_screen('photo_edit').word = 'Enter Text' 
    BoxLayout: 
     size_hint: 0.5,0.2 
     orientation: 'horizontal' 
     TextInput: 
      id: txt 
      text: 'Enter Text' 
      on_text: app.SM.get_screen('photo_edit').word = self.text 
     Button: 
      on_press: 
       app.SM.get_screen('photo_edit').close_text_entry() 
       root.dismiss() 

這一直是我的問題了一會兒,也不管我試過,我不能把它修好。任何幫助這樣做將不勝感激。

+0

我在視頻[這裏](https://www.youtube.com/watch?v=2Gc8iYJQ_qk)中討論這個問題,也許這可以提供幫助。 – inclement

回答

0

一切都在你的標題!

The Scatter必須具有與圖片相同的尺寸。 這意味着它是定義分散大小的圖像。

ScatterLayout: 
    size: img.size 
    size_hint: (None,None) 
    Image: 
     id: img 
     size: (500, 500/self.image_ratio)  
     # Here I fix the width to 500p, 
     # You could fix the height or make them 
     # related to the size of your screen. 

你知道你有你可以在你的kivy安裝文件夾中做什麼的例子嗎?你尤其應該感興趣你在kivy34 \ examples \ demo \圖片

BR。 PS:對於我的部分,我必須用「ovrly」id刪除你的圖像才能看到一些東西。