2014-01-06 4 views
2

Я думаю, что это правильное слово, которое я ищу. Надеюсь, мое описание объяснит это должным образом независимо от того, что.python tkinter canvas 'transparent'

У меня есть график временных данных, возвращающихся десятилетиями. Довольно просто настроить отображение одного дня на x-пиксель, если не приблизить его ближе. Я хотел бы иметь коробку, возможно, по строкам 5x100, появляться поверх графика, поэтому, когда я перемещаю мышь над графиком, коробка будет двигаться и идти в ногу с мышью. Еще несколько слов показывают, что происходило в 5 самых последних дней за несколько дней до этого. Еще несколько слов при вычислении среднего продвижения вперед, какие последующие значения будут падать по мере поступления новых данных. Естественно, я хочу, чтобы основные графические данные отображались с прозрачной коробкой поверх нее, в которой были указаны данные дни. Это может быть настолько сумасшедшим, чтобы быть гораздо более широкой коробкой с двумя областями, которые окрашены в светло-серый цвет или что-то в этом роде, чтобы показать эти области, но цветные области разделены многочисленными днями (может быть несколько прозрачных окон, которые также отслеживаются вместе . Является ли это возможно с Tkinter? Из исследования я делал это под вопросом, если используется

root.attributes('alpha', .30) 

будет работать или нет. это не звучит, как я мог бы сделать что-то вроде как бы в конечном итоге сделать график прозрачным для все, что под ним.

self.Graph.create_line() 
self.Box.attributes('alpha', .30) 

Если я правильно понимаю, что я должен использовать

attributes 

прямо на уровне корня в сравнении с индивидуальным уровнем «окна», поэтому вышеприведенный (сильно отрубленный) код не будет работать ... или не будет. У меня не было возможности попробовать что-то еще, чтобы увидеть, что произойдет ... это будет позже этим вечером. Kinda надеясь сэкономить себе немного времени, спросив сейчас, и вы никогда не знаете, кому еще может понадобиться помощь.

+0

Это должно быть с Tkinter? Потому что, если я понимаю, о чем вы просите, это будет очень сложно сделать, и было бы намного проще, например, PySide или wx или почти что-нибудь еще. – abarnert

ответ

2

Если я понимаю, что вы пытаетесь сделать, это будет довольно сложно.

Настройка атрибутов окна прекрасно работает, чтобы сделать окно прозрачным. У вас есть небольшая проблема в коде-атрибутах начинаются с дефисом, но в противном случае вы получили это право:

self.Box.attributes("-alpha", .30) 

Однако, это звучит, как вы хотите, чтобы Box быть внедренной частью графа окно, а не собственное окно верхнего уровня, которое может быть перемещено пользователем и т. д. К сожалению, у Tkinter нет понятия о дочерних окнах, и он не раскрывает почти достаточного количества материала, который вам нужно будет подделать их создавая неподвижное окно и вручную перемещая его, чтобы отслеживать движения другого окна. Таким образом, у вас нет окна, что означает, что у вас нет прозрачности окна.

Очевидно, что для Box будет какой-то виджетов, например Frame или Canvas. Но виджеты не имеют прозрачности.

Box вместо этого может быть просто набором элементов, нарисованных на том же Canvas, что и Graph. Это кажется многообещающим ... но ни один из методов Canvas не обрабатывает альфа-прозрачность. (Некоторые из них обрабатывают прозрачность «все или ничего», но это не помогает.)

Одна вещь, которую делает ручка прозрачности PhotoImage. Итак, если вы нарисуете Box вне экрана, получите полученное содержимое как PhotoImage, добавьте альфа (например, через PIL), затем create_image результат ... закрыть, но не сигары.В зависимости от настроек базовой библиотеки Tk, Tkinter может просто рисовать pixmap с 1-битной прозрачностью или полностью игнорировать прозрачность. (Поэкспериментируйте с загрузкой альфа-прозрачных PNG-файлов в PIL и рисованием их на холсте.) Итак, если вы не хотите, чтобы приложение выглядело правильно на некоторых системах, оно не рисует Box вообще на других и делает его непрозрачным для других , это тупик.

Итак, что осталось? Только ручная компоновка: нарисуйте Graph и Box на отдельных окнах, получайте растровые изображения, используйте PIL для их компоновки и получите результат create_image.

В этот момент вам, вероятно, лучше всего использовать что-то вроде ImageDraw PIL или более мощную библиотеку для создания pixmap в первую очередь. Или, конечно, использование более мощной библиотеки GUI, чем Tk, например Qt или wx.

+0

Я знал из того, что я читал до сих пор, что это звучало очень сомнительно. Это то, с чем мне придется играть, и, возможно, попробовать еще несколько идей. Я бы не прочь остаться с Tk, так как я использовал его до сих пор для чего-то связанного графика, поэтому мне, вероятно, придется попытаться прийти к другому способу делать то, что я пытаюсь сделать с точки зрения того, данные будут выведены из среднего уравнения. – confused

+0

@confused: После того, как я написал это, я обнаружил, что это еще более забавно, чем я думал. Я не могу найти ничего, что позволит вам получить pixmap окна вне экрана в Windows, который работает на Mac, или каким-либо образом преобразовать EPSF (который вы можете получить непосредственно из «Canvas») в pixmap с настройкой по умолчанию Windows PIL/Pillow install, что означает, что я даже не могу найти способ создания композитных материалов вручную. Поэтому я думаю, вам, возможно, придется рисовать график и поле вне Tk (с PIL, GraphicsMagick и т. Д., Что угодно), чтобы вы могли составьте их. – abarnert

1

Может быть, это может дать вам некоторые идеи, чтобы играть с:

from tkinter import * 

root = Tk() 
c = Canvas(root, width=640, height=480, bd=0, highlightthickness=0) 
c.create_line(0,240,640,240, fill='blue') 
c.pack() 

#pil image with transparency 
try: 
    from PIL import Image, ImageTk 
except ImportError: 
    pass 
else: 
    pim = Image.new('RGBA', (5,100), (0,255,0,64)) 
    photo = ImageTk.PhotoImage(pim) 
    c.create_image(200,200, image=photo, anchor='nw') 

#blank standard photoimage with red vertical borders 
im = PhotoImage(width=7, height=480) 
dat = ('red',)*480 
im.put(dat, to=(0,0)) 
im.put(dat, to=(6,0)) 

box = c.create_image(0, 0, image=im, anchor='nw') 

def on_motion(event): 
    left,top = c.coords(box) 
    dx = event.x - (left+7) 
    c.move(box, dx, 0) 

c.bind('<Motion>', on_motion) 
root.mainloop() 
0

Использование модулей из библиотеки PIL, вы можете создать изображение с желаемой прозрачности. (RGBA) И положил его в холст. Прозрачность изображения должна работать, по крайней мере, из того, что я тестировал. Вам нужны только модули Image и ImageTk.