2016-02-24 16 views
11

Tôi đang thử nghiệm tạo GUI bằng mô-đun Tkinter. Tôi đã cố gắng để thêm một hình ảnh vào GUI bằng cách sử dụng PIL. Mã của tôi trông giống như sau:Vấn đề triển khai thực hiện khung TK hai

import Tkinter as tk 
from PIL import Image, ImageTk 

root = tk.Tk() 
root.title('background image') 

imfile = "foo.png" 
im = Image.open(imfile) 
im1 = ImageTk.PhotoImage(im) 

Khi tôi chạy mã này, tôi sẽ gặp một số lỗi dẫn đến sự phân đoạn.

objc[5431]: Class TKApplication is implemented in both/Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
objc[5431]: Class TKMenu is implemented in both /Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
objc[5431]: Class TKContentView is implemented in both /Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
objc[5431]: Class TKWindow is implemented in both /Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
Segmentation fault: 11 

Tôi đã xem trực tuyến và có vẻ như là vấn đề với khung Tk trong thư viện Hệ thống của tôi và thư viện khác trong thư viện anaconda. Tuy nhiên, không có giải pháp nào thực sự có hiệu quả. Bất kỳ giải pháp hoặc cách giải quyết nào có thể?

Sự cố xảy ra khi chạy ImageTk.Photoimage. Nếu tôi xóa dòng mã đó, không có vấn đề gì.

+0

bạn có thể chạy cùng một mã trong 'IDLE' hoặc Thiết bị đầu cuối không? Nếu đây là câu hỏi cụ thể của 'anaconda', bạn có thể cần cung cấp thêm thông tin cụ thể về cách thiết lập –

+0

Chỉ để chắc chắn, bạn có đang sử dụng PIL hoặc Gối gốc không? –

Trả lời

9

Tôi biết tôi đã tạo ra tiền thưởng, nhưng tôi đã mất kiên nhẫn, quyết định điều tra, và bây giờ tôi đã có một cái gì đó mà làm việc cho tôi. Tôi có một ví dụ python rất giống như của bạn, trong đó khá nhiều không có gì khác hơn là cố gắng sử dụng Tkinter để hiển thị một hình ảnh thông qua trên dòng lệnh, như vậy:

calebhattingh $ python imageview.py a.jpg 
objc[84696]: Class TKApplication is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
objc[84696]: Class TKMenu is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
objc[84696]: Class TKContentView is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
objc[84696]: Class TKWindow is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. 
Segmentation fault: 11 

gì đang xảy ra là nhị phân tập tin , ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL/_imagingtk.so đã được liên kết với một khung công tác chứ không phải là thư mục Tcl/Tk trong env. Bạn có thể thấy điều này bằng cách sử dụng otool để xem thiết lập liên kết:

(py35) ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL 
calebhattingh $ otool -L _imagingtk.so 
_imagingtk.so: 
     /System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl (compatibility version 8.5.0, current version 8.5.9) 
     /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk (compatibility version 8.5.0, current version 8.5.9) 
     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0) 
     /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 

Xem hai dòng "khung" đó? Với anaconda chúng tôi không muốn điều đó. Chúng tôi muốn sử dụng các thư viện trong env. Vì vậy, hãy thay đổi chúng!

Đầu tiên tạo một bản sao lưu của bạn nhị phân (trong trường hợp bạn muốn trở lại):

$ cp _imagingtk.so _imagingtk.so.bak 

Bây giờ chạy trên dòng lệnh (giả sử bạn đang ở trong cùng một thư mục như envname/lib của bạn):

$ install_name_tool -change "/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk" "@rpath/libtk8.5.dylib" _imagingtk.so 
$ install_name_tool -change "/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl" "@rpath/libtcl8.5.dylib" _imagingtk.so 

Bạn thấy rằng @rpath bit trong đó? Điều đó có nghĩa là bất kỳ điều gì bạn tìm thấy trên đường dẫn. Những công trình tuyệt vời cho anaconda. Liên kết trong thư viện _imagingtk.so bây giờ trông giống như sau:

(py35) ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL 
calebhattingh $ otool -L _imagingtk.so 
_imagingtk.so: 
     @rpath/libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.9) 
     @rpath/libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.9) 
     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0) 
     /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 

Sau này, mã của bạn sẽ chạy. Ai đó có lẽ nên cố gắng để có được điều này ngược dòng.

Phụ Lục: Các Tkinter ràng buộc trong việc phân phối trăn, ví dụ, hiện đang chủ động conda env, có liên kết sau đây:

~/anaconda/envs/py35/lib/python3.5/lib-dynload 
calebhattingh $ otool -L _tkinter.cpython-35m-darwin.so 
_tkinter.cpython-35m-darwin.so: 
     @loader_path/../../libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.18) 
     @loader_path/../../libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.18) 
     /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 
     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0) 

Nếu bạn thích, bạn có thay vì có thể sử dụng install_name_tool sử dụng @loader_path/../../ thay về những gì tôi đã sử dụng ở trên, ví dụ: @rpath/. Điều đó sẽ có lẽ cũng hoạt động và thậm chí có thể tốt hơn.

+1

Nó làm việc cho tôi, cảm ơn! Ngoài ra, bạn có thể tìm thấy các tệp nhị phân, được liên kết với hệ thống Tkinter bằng các lệnh đơn giản: 'grep -rnw 'Tk.framework'' và 'grep -rnw 'Tcl.framework'' – lucidyan

+0

Cảm ơn bạn rất nhiều về điều này. Vậy đây có phải là lỗi trong Conda không? – Gus

+0

Không, tôi nghĩ nó liên quan đến Gối. Nếu gói là một gói conda, thì lỗi là pkg đó không được xây dựng đúng. Nếu gói được cài đặt pip (tôi không thể nhớ), thì lỗi là tôi mong đợi rằng một gói không phải conda đang được cài đặt vào môi trường conda sẽ hoạt động;) –

2

tôi cố gắng tiến hành điều tra riêng của tôi về vấn đề này (trong trường hợp của tôi đó là vấn đề với matplotlib)

  • tôi cố gắng nhị phân tìm thấy, liên kết với các đường dẫn hệ thống Tcl/Tk Thư viện
  • Với thư viện i tìm thấy tập tin, mà có vẻ thực sự thú vị. Nó có tên tên osx-tk.patch và được đặt trong ~/anaconda/pkgs/matplotlib-1.5.1-np111py35_0/info/recipe/
  • Tìm thấy osx-tk.patch nguồn vào GitHub

  • Sau khi đọc các bản vá và Conda documentation tôi trở thành cuối cùng thuyết phục về cài đặt gói sai, và tôi nhớ, mà tôi sử dụng pip để cài đặt matplotlib !

  • Tôi đã xóa gói cũ với pip và cài đặt mới với conda install matplotlib lệnh

  • Bây giờ tất cả mọi thứ bắt đầu làm việc như một nét duyên dáng!

Giới thiệu tóm tắt Tóm lại:

Sử dụng pip quản lý gói với môi trường conda, tôi sai lầm phụ thuộc của tôi, bởi vì conda có thể sử dụng đặc biệt recipes, điểm đó cài đặt như thế nào để cài đặt gói một cách chính xác trong môi trường ảo conda

Tóm tắt siêu tóm tắt:

Xóa gói đầy đủ với phụ thuộc và cài đặt nó ain với quản lý gói conda (chỉ sử dụng rebinding trong trường hợp khó khăn)

+0

Đây là một điểm rất thú vị mà tôi đã không xem xét. Tôi khá chắc chắn rằng tôi cài đặt Pillow thông qua conda mặc dù, nhưng nó vẫn đáng xem xét cho các tình huống khác, nơi các gói được cài đặt vào cùng một env với cả conda và pip. –

0

Tôi đã làm chính xác những gì @cjrh nói cho _imagetk.so, nhưng thay vì _tkinter.so trong ~/anaconda/lib/python3.5/lib-dynload/ và nó hoạt động tuyệt vời!

cd ~/anaconda/lib/python3.5/lib-dynload 

$ install_name_tool -change "/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk" "@rpath/libtk8.5.dylib" _tkinter.so 
$ install_name_tool -change "/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl" "@rpath/libtcl8.5.dylib" _tkinter.so 
Các vấn đề liên quan