tkinter --- Giao diện Python với Tcl/Tk¶
Source code: Lib/tkinter/__init__.py
Gói tkinter ("giao diện Tk") là giao diện Python tiêu chuẩn cho bộ công cụ Tcl/Tk GUI. Cả Tk và tkinter đều có sẵn trên hầu hết các nền tảng Unix, bao gồm macOS, cũng như trên hệ thống Windows.
Chạy python -m tkinter từ dòng lệnh sẽ mở ra một cửa sổ trình bày giao diện Tk đơn giản, cho bạn biết rằng tkinter đã được cài đặt đúng cách trên hệ thống của bạn và cũng hiển thị phiên bản Tcl/Tk nào đã được cài đặt, vì vậy bạn có thể đọc tài liệu Tcl/Tk cụ thể cho phiên bản đó.
Tkinter hỗ trợ nhiều phiên bản Tcl/Tk, được xây dựng có hoặc không có hỗ trợ luồng. Gói phát hành nhị phân Python chính thức theo luồng Tcl/Tk 8.6. Xem mã nguồn của mô-đun _tkinter để biết thêm thông tin về các phiên bản được hỗ trợ.
Tkinter không phải là một trình bao bọc mỏng, nhưng bổ sung một lượng logic hợp lý của riêng nó để làm cho trải nghiệm Pythonic hơn. Tài liệu này sẽ tập trung vào những bổ sung và thay đổi này, đồng thời tham khảo tài liệu Tcl/Tk chính thức để biết các chi tiết không thay đổi.
Ghi chú
Tcl/Tk 8.5 (2007) đã giới thiệu một bộ thành phần giao diện người dùng theo chủ đề hiện đại cùng với API mới để sử dụng chúng. Cả API cũ và mới vẫn có sẵn. Hầu hết tài liệu bạn tìm thấy trên mạng vẫn sử dụng API cũ và có thể đã lỗi thời.
Đây là một optional module. Nếu nó bị thiếu trong bản sao CPython của bạn, hãy tìm tài liệu từ nhà phân phối của bạn (nghĩa là bất kỳ ai đã cung cấp Python cho bạn). Nếu bạn là nhà phân phối, hãy xem Yêu cầu đối với các mô-đun tùy chọn.
Xem thêm
- TkDocs
Hướng dẫn mở rộng về cách tạo giao diện người dùng với Tkinter. Giải thích các khái niệm chính và minh họa các phương pháp được đề xuất bằng cách sử dụng API hiện đại.
- Tkinter 8.5 reference: a GUI for Python
Tài liệu tham khảo về Tkinter 8.5 nêu chi tiết các lớp, phương thức và tùy chọn có sẵn.
Tài nguyên Tcl/Tk:
- Tk commands
Tham chiếu toàn diện về từng lệnh Tcl/Tk cơ bản được Tkinter sử dụng.
- Tcl/Tk Home Page
Tài liệu bổ sung và các liên kết đến quá trình phát triển cốt lõi Tcl/Tk.
Sách:
- Modern Tkinter for Busy Python Developers
của Mark Roseman. (ISBN 978-1999149567)
- Python GUI programming with Tkinter
Bởi Alan D. Moore. (ISBN 978-1788835886)
- Programming Python
Bởi Mark Lutz; có phạm vi bảo hiểm tuyệt vời của Tkinter. (ISBN 978-0596158101)
- Tcl and the Tk Toolkit (2nd edition)
Bởi John Ousterhout, người phát minh ra Tcl/Tk và Ken Jones; không bao gồm Tkinter. (ISBN 978-0321336330)
Kiến trúc¶
Tcl/Tk không phải là một thư viện đơn lẻ mà bao gồm một vài mô-đun riêng biệt, mỗi mô-đun có chức năng riêng biệt và tài liệu chính thức riêng. Các bản phát hành nhị phân của Python cũng gửi kèm một mô-đun bổ trợ cùng với nó.
- tcl
Tcl là ngôn ngữ lập trình được diễn giải động, giống như Python. Mặc dù nó có thể được sử dụng riêng như một ngôn ngữ lập trình có mục đích chung, nhưng nó thường được nhúng vào các ứng dụng C dưới dạng công cụ tạo tập lệnh hoặc giao diện cho bộ công cụ Tk. Thư viện Tcl có giao diện C để tạo và quản lý một hoặc nhiều phiên bản của trình thông dịch Tcl, chạy các lệnh và tập lệnh Tcl trong các phiên bản đó, đồng thời thêm các lệnh tùy chỉnh được triển khai trong Tcl hoặc C. Mỗi trình thông dịch có một hàng đợi sự kiện và có các phương tiện để gửi sự kiện tới nó và xử lý chúng. Không giống như Python, mô hình thực thi của Tcl được thiết kế dựa trên đa nhiệm hợp tác và Tkinter thu hẹp sự khác biệt này (xem Threading model để biết chi tiết).
- Tk
Tk là một Tcl package được triển khai trong C có thêm các lệnh tùy chỉnh để tạo và thao tác các tiện ích GUI. Mỗi đối tượng
Tknhúng phiên bản trình thông dịch Tcl của riêng nó với Tk được tải vào đó. Các vật dụng của Tk có khả năng tùy chỉnh rất cao, mặc dù phải trả giá bằng vẻ ngoài lỗi thời. Tk sử dụng hàng đợi sự kiện của Tcl để tạo và xử lý các sự kiện GUI.- Ttk
Tk theo chủ đề (Ttk) là một dòng tiện ích Tk mới hơn mang lại giao diện đẹp hơn nhiều trên các nền tảng khác nhau so với nhiều tiện ích Tk cổ điển. Ttk được phân phối như một phần của Tk, bắt đầu từ phiên bản Tk 8.5. Các liên kết Python được cung cấp trong một mô-đun riêng biệt,
tkinter.ttk.
Trong nội bộ, Tk và Ttk sử dụng các tiện ích của hệ điều hành cơ bản, tức là Xlib trên Unix/X11, Cocoa trên macOS, GDI trên Windows.
Khi ứng dụng Python của bạn sử dụng một lớp trong Tkinter, ví dụ: để tạo một tiện ích, trước tiên, mô-đun tkinter sẽ tập hợp chuỗi lệnh Tcl/Tk. Nó chuyển chuỗi lệnh Tcl đó đến mô-đun nhị phân _tkinter bên trong, sau đó gọi trình thông dịch Tcl để đánh giá nó. Sau đó, trình thông dịch Tcl sẽ gọi các gói Tk và/hoặc Ttk, sau đó sẽ thực hiện các lệnh gọi tới Xlib, Cocoa hoặc GDI.
Mô-đun Tkinter¶
Hỗ trợ cho Tkinter được trải rộng trên nhiều mô-đun. Hầu hết các ứng dụng sẽ cần mô-đun tkinter chính, cũng như mô-đun tkinter.ttk, cung cấp bộ tiện ích theo chủ đề hiện đại và API:
từ nhập tkinter *
từ tkinter nhập ttk
- class tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None)¶
Xây dựng một tiện ích Tk cấp cao nhất, thường là cửa sổ chính của ứng dụng và khởi tạo trình thông dịch Tcl cho tiện ích này. Mỗi phiên bản có trình thông dịch Tcl liên quan riêng.
Lớp
Tkthường được khởi tạo bằng tất cả các giá trị mặc định. Tuy nhiên, các đối số từ khóa sau hiện được công nhận:- screenName
Khi được cung cấp (dưới dạng chuỗi), hãy đặt biến môi trường
DISPLAY. (chỉ X11)- baseName
Tên của tập tin hồ sơ. Theo mặc định, baseName được lấy từ tên chương trình (
sys.argv[0]).- className
Tên của lớp tiện ích. Được sử dụng làm tệp hồ sơ và cũng là tên mà Tcl được gọi (argv0 trong interp).
- useTk
Nếu
True, khởi tạo hệ thống con Tk. Hàmtkinter.Tcl()đặt giá trị này thànhFalse.- sync
Nếu
True, hãy thực thi đồng bộ tất cả các lệnh của máy chủ X để lỗi được báo cáo ngay lập tức. Có thể được sử dụng để gỡ lỗi. (chỉ X11)- use
Chỉ định id của cửa sổ để nhúng ứng dụng vào đó, thay vì nó được tạo dưới dạng cửa sổ cấp cao độc lập. id phải được chỉ định theo cách tương tự như giá trị cho tùy chọn -use cho các tiện ích cấp cao nhất (nghĩa là nó có dạng giống như được trả về bởi
winfo_id()).Lưu ý rằng trên một số nền tảng, điều này sẽ chỉ hoạt động chính xác nếu id đề cập đến khung Tk hoặc cấp cao nhất đã bật tùy chọn -container.
Tkđọc và giải thích các tệp hồ sơ, có tên là.className.tclvà.baseName.tcl, vào trình thông dịch Tcl và gọiexec()theo nội dung của.className.pyvà.baseName.py. Đường dẫn cho các tệp hồ sơ là biến môi trườngHOMEhoặc, nếu biến đó không được xác định thìos.curdir.- tk¶
Đối tượng ứng dụng Tk được tạo bằng cách khởi tạo
Tk. Điều này cung cấp quyền truy cập vào trình thông dịch Tcl. Mỗi tiện ích được đính kèm cùng một phiên bảnTkcó cùng giá trị cho thuộc tínhtkcủa nó.
- master¶
Đối tượng widget chứa widget này. Đối với
Tk,masterlàNonevì đây là cửa sổ chính. Các thuật ngữ master và parent tương tự nhau và đôi khi được sử dụng thay thế cho nhau làm tên đối số; tuy nhiên, việc gọiwinfo_parent()trả về một chuỗi tên widget trong khimastertrả về đối tượng. parent/child phản ánh mối quan hệ dạng cây trong khi master (hoặc container)/content phản ánh cấu trúc vùng chứa.
- tkinter.Tcl(screenName=None, baseName=None, className='Tk', useTk=False)¶
Hàm
Tcl()là một hàm xuất xưởng tạo ra một đối tượng giống như đối tượng được tạo bởi lớpTk, ngoại trừ việc nó không khởi tạo hệ thống con Tk. Điều này thường hữu ích nhất khi điều khiển trình thông dịch Tcl trong môi trường mà người ta không muốn tạo các cửa sổ cấp cao không liên quan hoặc nơi không thể (chẳng hạn như hệ thống Unix/Linux không có máy chủ X). Một đối tượng được tạo bởi đối tượngTcl()có thể tạo cửa sổ Toplevel (và hệ thống con Tk được khởi tạo) bằng cách gọi phương thứcloadtk()của nó.
Các mô-đun cung cấp hỗ trợ Tk bao gồm:
tkinterMô-đun Tkinter chính.
tkinter.colorchooserHộp thoại cho phép người dùng chọn màu.
tkinter.commondialogLớp cơ sở cho các hộp thoại được xác định trong các mô-đun khác được liệt kê ở đây.
tkinter.filedialogCác hộp thoại chung cho phép người dùng chỉ định một tệp để mở hoặc lưu.
tkinter.fontCác tiện ích hỗ trợ làm việc với font chữ.
tkinter.messageboxTruy cập vào hộp thoại Tk tiêu chuẩn.
tkinter.scrolledtextTiện ích văn bản có thanh cuộn dọc được tích hợp sẵn.
tkinter.simpledialogCác hộp thoại cơ bản và các chức năng tiện lợi.
tkinter.ttkBộ tiện ích theo chủ đề được giới thiệu trong Tk 8.5, cung cấp các lựa chọn thay thế hiện đại cho nhiều tiện ích cổ điển trong mô-đun
tkinterchính.
Các mô-đun bổ sung:
_tkinterMột mô-đun nhị phân chứa giao diện cấp thấp tới Tcl/Tk. Nó được mô-đun
tkinterchính tự động nhập và không bao giờ được sử dụng trực tiếp bởi các lập trình viên ứng dụng. Nó thường là một thư viện dùng chung (hoặc DLL), nhưng trong một số trường hợp có thể được liên kết tĩnh với trình thông dịch Python.idlelibMôi trường học tập và phát triển tích hợp của Python (IDLE). Dựa trên
tkinter.tkinter.constantsCác hằng số tượng trưng có thể được sử dụng thay cho chuỗi khi truyền các tham số khác nhau cho lệnh gọi Tkinter. Tự động được nhập bởi mô-đun
tkinterchính.tkinter.dnd(thử nghiệm) Hỗ trợ kéo và thả cho
tkinter. Điều này sẽ không còn được dùng nữa khi nó được thay thế bằng Tk DND.turtleĐồ họa rùa trong cửa sổ Tk.
Máy bảo vệ sự sống Tkinter¶
Phần này không được thiết kế để trở thành một hướng dẫn đầy đủ về Tk hoặc Tkinter. Để làm được điều đó, hãy tham khảo một trong những tài nguyên bên ngoài đã được lưu ý trước đó. Thay vào đó, phần này cung cấp định hướng rất nhanh về giao diện của ứng dụng Tkinter, xác định các khái niệm Tk cơ bản và giải thích cách cấu trúc trình bao bọc Tkinter.
Phần còn lại của phần này sẽ giúp bạn xác định các lớp, phương thức và tùy chọn bạn sẽ cần trong ứng dụng Tkinter của mình và nơi để tìm tài liệu chi tiết hơn về chúng, kể cả trong sổ tay tham khảo Tcl/Tk chính thức.
Chương trình Hello World¶
Chúng ta sẽ bắt đầu bằng cách xem qua ứng dụng "Hello World" trong Tkinter. Đây không phải là bài viết nhỏ nhất mà chúng tôi có thể viết nhưng cũng đủ để minh họa một số khái niệm chính mà bạn cần biết.
từ nhập tkinter *
từ tkinter nhập ttk
gốc = Tk()
frm = ttk.Frame(gốc, phần đệm=10)
frm.grid()
ttk.Label(frm, text="Xin chào thế giới!").grid(column=0, row=0)
ttk.Button(frm, text="Quit", command=root.destroy).grid(column=1, row=0)
root.mainloop()
Sau khi nhập, dòng tiếp theo sẽ tạo một phiên bản của lớp Tk, khởi tạo Tk và tạo trình thông dịch Tcl liên quan của nó. Nó cũng tạo ra một cửa sổ cấp cao nhất, được gọi là cửa sổ gốc, đóng vai trò là cửa sổ chính của ứng dụng.
Dòng sau đây tạo một tiện ích khung, trong trường hợp này sẽ chứa nhãn và nút mà chúng ta sẽ tạo tiếp theo. Khung vừa khít bên trong cửa sổ gốc.
Dòng tiếp theo tạo tiện ích nhãn chứa chuỗi văn bản tĩnh. Phương thức grid() được sử dụng để chỉ định bố cục (vị trí) tương đối của nhãn trong tiện ích khung chứa nó, tương tự như cách hoạt động của các bảng trong HTML.
Sau đó, một tiện ích nút sẽ được tạo và đặt ở bên phải nhãn. Khi nhấn, nó sẽ gọi phương thức destroy() của cửa sổ gốc.
Cuối cùng, phương thức mainloop() hiển thị mọi thứ và phản hồi dữ liệu nhập của người dùng cho đến khi chương trình kết thúc.
Khái niệm Tk quan trọng¶
Ngay cả chương trình đơn giản này cũng minh họa các khái niệm Tk chính sau đây:
- vật dụng
Giao diện người dùng Tkinter được tạo thành từ widgets riêng lẻ. Mỗi tiện ích được biểu diễn dưới dạng một đối tượng Python, được khởi tạo từ các lớp như
ttk.Frame,ttk.Labelvàttk.Button.- hệ thống phân cấp tiện ích
Các widget được sắp xếp theo kiểu hierarchy. Nhãn và nút được chứa trong một khung, khung này lại được chứa trong cửa sổ gốc. Khi tạo mỗi tiện ích child, tiện ích parent của nó được chuyển làm đối số đầu tiên cho hàm tạo tiện ích.
- tùy chọn cấu hình
Các tiện ích có configuration options, có chức năng sửa đổi giao diện và hoạt động của chúng, chẳng hạn như văn bản sẽ hiển thị trong nhãn hoặc nút. Các lớp vật dụng khác nhau sẽ có các bộ tùy chọn khác nhau.
- quản lý hình học
Các widget không được tự động thêm vào giao diện người dùng khi chúng được tạo. Một geometry manager như
gridkiểm soát vị trí chúng được đặt trong giao diện người dùng.- vòng lặp sự kiện
Tkinter phản ứng với thông tin đầu vào của người dùng, những thay đổi từ chương trình của bạn và thậm chí chỉ làm mới màn hình khi chủ động chạy event loop. Nếu chương trình của bạn không chạy vòng lặp sự kiện, giao diện người dùng của bạn sẽ không cập nhật.
Hiểu cách Tkinter kết hợp Tcl/Tk¶
Khi ứng dụng của bạn sử dụng các lớp và phương thức của Tkinter, Tkinter nội bộ sẽ tập hợp các chuỗi đại diện cho các lệnh Tcl/Tk và thực thi các lệnh đó trong trình thông dịch Tcl được đính kèm với phiên bản Tk của ứng dụng của bạn.
Cho dù đó là cố gắng điều hướng tài liệu tham khảo, cố gắng tìm phương pháp hoặc tùy chọn phù hợp, điều chỉnh một số mã hiện có hoặc gỡ lỗi ứng dụng Tkinter của bạn, đôi khi sẽ rất hữu ích nếu hiểu được các lệnh Tcl/Tk cơ bản đó trông như thế nào.
Để minh họa, đây là Tcl/Tk tương đương với phần chính của tập lệnh Tkinter ở trên.
ttk::frame .frm -padding 10
lưới .frm
lưới [ttk::label .frm.lbl -text "Xin chào thế giới!"] -column 0 -row 0
lưới [ttk::button .frm.btn -text "Thoát" -command "hủy ."] -column 1 -row 0
Cú pháp của Tcl tương tự như nhiều ngôn ngữ shell, trong đó từ đầu tiên là lệnh được thực thi, với các đối số cho lệnh đó theo sau nó, được phân tách bằng dấu cách. Không đi sâu vào chi tiết, hãy chú ý những điều sau:
Các lệnh được sử dụng để tạo widget (như
ttk::frame) tương ứng với các lớp widget trong Tkinter.Các tùy chọn tiện ích Tcl (như
-text) tương ứng với các đối số từ khóa trong Tkinter.Các widget được tham chiếu bằng pathname trong Tcl (như
.frm.btn), trong khi Tkinter không sử dụng tên mà sử dụng tham chiếu đối tượng.Vị trí của tiện ích trong hệ thống phân cấp tiện ích được mã hóa theo tên đường dẫn (phân cấp) của nó, sử dụng
.(dấu chấm) làm dấu phân cách đường dẫn. Tên đường dẫn cho cửa sổ gốc chỉ là.(dấu chấm). Trong Tkinter, hệ thống phân cấp được xác định không phải bằng tên đường dẫn mà bằng cách chỉ định tiện ích mẹ khi tạo từng tiện ích con.Các hoạt động được triển khai dưới dạng commands riêng biệt trong Tcl (như
gridhoặcdestroy) được biểu diễn dưới dạng methods trên các đối tượng tiện ích Tkinter. Như bạn sẽ thấy ngay sau đây, đôi khi Tcl sử dụng những gì dường như là lệnh gọi phương thức trên các đối tượng widget, phản ánh chặt chẽ hơn những gì được sử dụng trong Tkinter.
Làm sao tôi...? Lựa chọn nào...?¶
Nếu bạn không chắc chắn về cách thực hiện điều gì đó trong Tkinter và không thể tìm thấy ngay điều đó trong hướng dẫn hoặc tài liệu tham khảo mà bạn đang sử dụng thì có một số chiến lược có thể hữu ích.
Trước tiên, hãy nhớ rằng chi tiết về cách hoạt động của từng tiện ích con có thể khác nhau giữa các phiên bản khác nhau của cả Tkinter và Tcl/Tk. Nếu bạn đang tìm kiếm tài liệu, hãy đảm bảo rằng nó tương ứng với phiên bản Python và Tcl/Tk được cài đặt trên hệ thống của bạn.
Khi tìm kiếm cách sử dụng API, việc biết chính xác tên của lớp, tùy chọn hoặc phương thức bạn đang sử dụng sẽ giúp ích. Việc xem xét nội tâm, trong trình bao Python tương tác hoặc với print(), có thể giúp bạn xác định những gì bạn cần.
Để tìm hiểu các tùy chọn cấu hình nào có sẵn trên bất kỳ tiện ích nào, hãy gọi phương thức configure() của nó, phương thức này trả về một từ điển chứa nhiều thông tin khác nhau về từng đối tượng, bao gồm các giá trị mặc định và hiện tại của nó. Sử dụng keys() để lấy tên của từng tùy chọn.
btn = ttk.Button(frm, ...)
print(btn.configure().keys())
Vì hầu hết các tiện ích đều có nhiều tùy chọn cấu hình chung, nên có thể hữu ích khi tìm ra tùy chọn nào dành riêng cho một lớp tiện ích cụ thể. So sánh danh sách các tùy chọn với danh sách của một tiện ích đơn giản hơn, chẳng hạn như khung, là một cách để thực hiện điều đó.
print(set(btn.configure().keys()) - set(frm.configure().keys()))
Tương tự, bạn có thể tìm thấy các phương thức có sẵn cho một đối tượng widget bằng hàm dir() tiêu chuẩn. Nếu bạn thử nó, bạn sẽ thấy có hơn 200 phương thức widget phổ biến, vì vậy một lần nữa việc xác định những phương thức cụ thể cho một lớp widget là rất hữu ích.
in(dir(btn))
print(set(dir(btn)) - set(dir(frm)))
Mô hình luồng¶
Python và Tcl/Tk có các mô hình luồng rất khác nhau mà tkinter cố gắng kết nối. Nếu bạn sử dụng chủ đề, bạn có thể cần phải biết điều này.
Trình thông dịch Python có thể có nhiều luồng liên kết với nó. Trong Tcl, nhiều luồng có thể được tạo, nhưng mỗi luồng có một phiên bản trình thông dịch Tcl riêng biệt được liên kết với nó. Các luồng cũng có thể tạo nhiều phiên bản trình thông dịch, mặc dù mỗi phiên bản trình thông dịch chỉ có thể được sử dụng bởi một luồng đã tạo ra nó.
Mỗi đối tượng Tk được tạo bởi tkinter đều chứa trình thông dịch Tcl. Nó cũng theo dõi luồng nào đã tạo trình thông dịch đó. Các lệnh gọi tới tkinter có thể được thực hiện từ bất kỳ luồng Python nào. Trong nội bộ, nếu lệnh gọi đến từ một luồng không phải luồng đã tạo đối tượng Tk, thì một sự kiện sẽ được đăng lên hàng đợi sự kiện của trình thông dịch và khi được thực thi, kết quả sẽ được trả về luồng Python đang gọi.
Các ứng dụng Tcl/Tk thường hướng sự kiện, nghĩa là sau khi khởi tạo, trình thông dịch sẽ chạy một vòng lặp sự kiện (tức là Tk.mainloop()) và phản hồi các sự kiện. Vì là đơn luồng nên trình xử lý sự kiện phải phản hồi nhanh, nếu không chúng sẽ chặn các sự kiện khác được xử lý. Để tránh điều này, mọi tính toán chạy trong thời gian dài không được chạy trong trình xử lý sự kiện mà được chia thành các phần nhỏ hơn bằng cách sử dụng bộ tính giờ hoặc chạy trong một luồng khác. Điều này khác với nhiều bộ công cụ GUI trong đó GUI chạy trong một luồng hoàn toàn riêng biệt với tất cả mã ứng dụng bao gồm cả trình xử lý sự kiện.
Nếu trình thông dịch Tcl không chạy vòng lặp sự kiện và xử lý các sự kiện thì mọi lệnh gọi tkinter được thực hiện từ các luồng không phải luồng đang chạy trình thông dịch Tcl sẽ không thành công.
Có một số trường hợp đặc biệt:
Thư viện Tcl/Tk có thể được xây dựng để chúng không nhận biết luồng. Trong trường hợp này,
tkintergọi thư viện từ luồng Python gốc, ngay cả khi luồng này khác với luồng đã tạo trình thông dịch Tcl. Khóa toàn cầu đảm bảo chỉ có một cuộc gọi xảy ra tại một thời điểm.Mặc dù
tkintercho phép bạn tạo nhiều phiên bản của một đối tượngTk(với trình thông dịch riêng của nó), nhưng tất cả các trình thông dịch thuộc một phần của cùng một luồng đều chia sẻ một hàng sự kiện chung, điều này diễn ra rất nhanh. Trong thực tế, không tạo nhiều phiên bảnTkcùng một lúc. Nếu không, tốt nhất bạn nên tạo chúng trong các luồng riêng biệt và đảm bảo bạn đang chạy bản dựng Tcl/Tk nhận biết luồng.Chặn các trình xử lý sự kiện không phải là cách duy nhất để ngăn trình thông dịch Tcl quay lại vòng lặp sự kiện. Thậm chí có thể chạy nhiều vòng lặp sự kiện lồng nhau hoặc loại bỏ hoàn toàn vòng lặp sự kiện. Nếu bạn đang làm bất cứ điều gì phức tạp liên quan đến sự kiện hoặc chủ đề, hãy lưu ý đến những khả năng này.
Có một số hàm
tkinterchọn lọc hiện chỉ hoạt động khi được gọi từ chuỗi đã tạo trình thông dịch Tcl.
Tài liệu tham khảo tiện dụng¶
Tùy chọn cài đặt¶
Các tùy chọn kiểm soát những thứ như màu sắc và độ rộng đường viền của tiện ích. Các tùy chọn có thể được đặt theo ba cách:
- Tại thời điểm tạo đối tượng, sử dụng đối số từ khóa
fred = Nút(self, fg="red", bg="blue")
- Sau khi tạo đối tượng, xử lý tên tùy chọn như chỉ mục từ điển
fred["fg"] = "đỏ" fred["bg"] = "màu xanh"
- Sử dụng phương thức config() để cập nhật nhiều attr sau khi tạo đối tượng
fred.config(fg="red", bg="blue")
Để có giải thích đầy đủ về một tùy chọn nhất định và hành vi của nó, hãy xem các trang Tk man cho tiện ích được đề cập.
Lưu ý rằng trang man liệt kê "STANDARD OPTIONS" và "WIDGET SPECIFIC OPTIONS" cho mỗi tiện ích. Cái trước là danh sách các tùy chọn phổ biến cho nhiều tiện ích, cái sau là các tùy chọn mang phong cách riêng cho tiện ích cụ thể đó. Tùy chọn tiêu chuẩn được ghi lại trên trang man options(3).
Không có sự phân biệt giữa các tùy chọn tiêu chuẩn và tùy chọn dành riêng cho tiện ích trong tài liệu này. Một số tùy chọn không áp dụng cho một số loại vật dụng. Việc một tiện ích nhất định có phản hồi với một tùy chọn cụ thể hay không phụ thuộc vào loại của tiện ích đó; các nút có tùy chọn command, nhãn thì không.
Các tùy chọn được hỗ trợ bởi một tiện ích nhất định được liệt kê trong trang man của tiện ích đó hoặc có thể được truy vấn trong thời gian chạy bằng cách gọi phương thức config() mà không có đối số hoặc bằng cách gọi phương thức keys() trên tiện ích đó. Giá trị trả về của các lệnh gọi này là một từ điển có khóa là tên của tùy chọn dưới dạng chuỗi (ví dụ: 'relief') và có giá trị là 5 bộ dữ liệu.
Một số tùy chọn, như bg là từ đồng nghĩa với các tùy chọn phổ biến có tên dài (bg là tốc ký của "nền"). Truyền phương thức config(), tên của tùy chọn tốc ký sẽ trả về 2 bộ chứ không phải 5 bộ. Bộ 2 được truyền lại sẽ chứa tên của từ đồng nghĩa và tùy chọn "thực" (chẳng hạn như ('bg', 'background')).
chỉ mục |
Ý nghĩa |
Ví dụ |
|---|---|---|
0 |
tên tùy chọn |
|
1 |
tên tùy chọn để tra cứu cơ sở dữ liệu |
|
2 |
lớp tùy chọn để tra cứu cơ sở dữ liệu |
|
3 |
giá trị mặc định |
|
4 |
giá trị hiện tại |
|
Ví dụ:
>>> in(fred.config())
{'cứu trợ': ('cứu trợ', 'cứu trợ', 'Cứu trợ', 'nâng lên', 'rãnh')}
Tất nhiên, từ điển được in sẽ bao gồm tất cả các tùy chọn có sẵn và giá trị của chúng. Điều này chỉ có ý nghĩa như một ví dụ.
Người đóng gói¶
Trình đóng gói là một trong những cơ chế quản lý hình học của Tk. Trình quản lý hình học được sử dụng để chỉ định vị trí tương đối của các vật dụng trong vùng chứa của chúng. Ngược lại với placer cồng kềnh hơn (được sử dụng ít phổ biến hơn và chúng tôi không đề cập ở đây), trình đóng gói lấy đặc tả mối quan hệ định tính - above, to the left of, filling, v.v. - và xử lý mọi thứ để xác định tọa độ vị trí chính xác cho bạn.
Kích thước của bất kỳ tiện ích vùng chứa nào được xác định bởi kích thước của "tiện ích nội dung" bên trong. Trình đóng gói được sử dụng để kiểm soát vị trí các tiện ích nội dung xuất hiện bên trong vùng chứa mà chúng được đóng gói. Bạn có thể đóng gói các vật dụng vào các khung và khung vào các khung khác để đạt được kiểu bố cục mà bạn mong muốn. Ngoài ra, sự sắp xếp được điều chỉnh linh hoạt để phù hợp với những thay đổi gia tăng về cấu hình sau khi được đóng gói.
Lưu ý rằng các tiện ích không xuất hiện cho đến khi chúng được chỉ định hình học bằng trình quản lý hình học. Một sai lầm phổ biến ban đầu là bỏ qua đặc tả hình học và sau đó ngạc nhiên khi tiện ích được tạo nhưng không có gì xuất hiện. Một tiện ích sẽ chỉ xuất hiện sau khi nó đã được áp dụng phương thức pack() của trình đóng gói cho nó, chẳng hạn.
Phương thức pack() có thể được gọi bằng các cặp từ khóa-tùy chọn/giá trị kiểm soát vị trí tiện ích sẽ xuất hiện trong vùng chứa của nó và cách nó hoạt động khi cửa sổ ứng dụng chính được thay đổi kích thước. Dưới đây là một số ví dụ:
fred.pack() # defaults sang side = "top"
fred.pack(side="left")
fred.pack(mở rộng=1)
Tùy chọn đóng gói¶
Để biết thêm thông tin mở rộng về trình đóng gói và các tùy chọn mà nó có thể thực hiện, hãy xem các trang hướng dẫn sử dụng và trang 183 trong cuốn sách của John Ousterhout.
- mỏ neo
Loại neo. Biểu thị nơi người đóng gói sẽ đặt từng nội dung trong bưu kiện của mình.
- mở rộng
Boolean,
0hoặc1.- điền vào
Giá trị pháp lý:
'x','y','both','none'.- ipadx và ipady
Khoảng cách - chỉ định phần đệm bên trong ở mỗi bên của nội dung.
- padx và lúa
Khoảng cách - chỉ định phần đệm bên ngoài ở mỗi bên của nội dung.
- bên
Giá trị pháp lý là:
'left','right','top','bottom'.
Khớp nối các biến widget¶
Cài đặt giá trị hiện tại của một số tiện ích (như tiện ích nhập văn bản) có thể được kết nối trực tiếp với các biến ứng dụng bằng cách sử dụng các tùy chọn đặc biệt. Các tùy chọn này là variable, textvariable, onvalue, offvalue và value. Kết nối này hoạt động theo cả hai cách: nếu biến thay đổi vì bất kỳ lý do gì, tiện ích mà nó kết nối sẽ được cập nhật để phản ánh giá trị mới.
Thật không may, trong quá trình triển khai tkinter hiện tại, không thể chuyển một biến Python tùy ý cho một widget thông qua tùy chọn variable hoặc textvariable. Loại biến duy nhất có tác dụng với tính năng này là các biến được phân lớp từ một lớp có tên Biến, được xác định trong tkinter.
Có nhiều lớp con hữu ích của Biến đã được xác định: StringVar, IntVar, DoubleVar và BooleanVar. Để đọc giá trị hiện tại của một biến như vậy, hãy gọi phương thức get() trên biến đó và để thay đổi giá trị của nó, bạn gọi phương thức set(). Nếu bạn làm theo giao thức này, tiện ích sẽ luôn theo dõi giá trị của biến mà bạn không cần can thiệp gì thêm.
Ví dụ:
nhập tkinter dưới dạng tk
Ứng dụng lớp (tk.Frame):
def __init__(tự, chủ):
siêu().__init__(chính)
self.pack()
self.entrythingy = tk.Entry()
self.entrythingy.pack()
# Create biến ứng dụng.
self.contents = tk.StringVar()
# Set nó đến một giá trị nào đó.
self.contents.set("đây là một biến")
# Tell tiện ích nhập để xem biến này.
self.entrythingy["textvariable"] = self.contents
# Define gọi lại khi người dùng nhấn quay lại.
# It in giá trị hiện tại của biến.
self.entrythingy.bind('<Key-Return>',
self.print_contents)
def print_contents(tự, sự kiện):
print("Xin chào. Nội dung mục nhập hiện tại là:",
self.contents.get())
gốc = tk.Tk()
myapp = Ứng dụng (root)
myapp.mainloop()
Trình quản lý cửa sổ¶
Trong Tk, có một lệnh tiện ích, wm, để tương tác với trình quản lý cửa sổ. Các tùy chọn cho lệnh wm cho phép bạn kiểm soát những thứ như tiêu đề, vị trí, ảnh bitmap biểu tượng và những thứ tương tự. Trong tkinter, các lệnh này đã được triển khai dưới dạng các phương thức trên lớp Wm. Các tiện ích cấp cao nhất được phân lớp từ lớp Wm và do đó có thể gọi trực tiếp các phương thức Wm.
Để truy cập cửa sổ cấp cao nhất chứa một tiện ích nhất định, bạn thường có thể chỉ cần tham khảo master của tiện ích đó. Tất nhiên, nếu tiện ích đã được đóng gói bên trong một khung thì master sẽ không đại diện cho cửa sổ cấp cao nhất. Để truy cập cửa sổ cấp cao nhất chứa tiện ích con tùy ý, bạn có thể gọi phương thức _root(). Phương thức này bắt đầu bằng dấu gạch dưới để biểu thị thực tế rằng chức năng này là một phần của quá trình triển khai chứ không phải là giao diện cho chức năng Tk.
Dưới đây là một số ví dụ về cách sử dụng điển hình:
nhập tkinter dưới dạng tk
Ứng dụng lớp (tk.Frame):
def __init__(self, master=None):
siêu().__init__(chính)
self.pack()
# create ứng dụng
myapp = Ứng dụng()
#
# here là các lệnh gọi phương thức đến lớp trình quản lý cửa sổ
#
myapp.master.title("Ứng dụng không làm gì của tôi")
myapp.master.maxsize(1000, 400)
# start chương trình
myapp.mainloop()
Các kiểu dữ liệu tùy chọn Tk¶
- mỏ neo
Giá trị pháp lý là các điểm của la bàn:
"n","ne","e","se","s","sw","w","nw", và cả"center".- ảnh bitmap
Có tám bitmap tích hợp, được đặt tên:
'error','gray25','gray50','hourglass','info','questhead','question','warning'. Để chỉ định tên tệp bitmap X, hãy cung cấp đường dẫn đầy đủ đến tệp, trước@, như trong"@/usr/contrib/bitmap/gumby.bit".- boolean
Bạn có thể truyền số nguyên 0 hoặc 1 hoặc chuỗi
"yes"hoặc"no".- gọi lại
Đây là bất kỳ hàm Python nào không có đối số. Ví dụ:
chắc chắn print_it(): print("chào bạn") fred["lệnh"] = print_it
- màu sắc
Màu sắc có thể được cung cấp dưới dạng tên của màu X trong tệp rgb.txt hoặc dưới dạng chuỗi biểu thị các giá trị RGB trong 4 bit:
"#RGB", 8 bit:"#RRGGBB", 12 bit:"#RRRGGGBBB"hoặc 16 bit:"#RRRRGGGGBBBB", trong đó R, G, B ở đây đại diện cho bất kỳ chữ số hex hợp pháp nào. Xem trang 160 trong cuốn sách của Ousterhout để biết chi tiết.- con trỏ
Có thể sử dụng tên con trỏ X tiêu chuẩn từ
cursorfont.hmà không cần tiền tốXC_. Ví dụ: để lấy con trỏ tay (XC_hand2), hãy sử dụng chuỗi"hand2". Bạn cũng có thể chỉ định tệp bitmap và mặt nạ của riêng mình. Xem trang 179 trong cuốn sách của Ousterhout.- khoảng cách
Khoảng cách màn hình có thể được chỉ định bằng pixel hoặc khoảng cách tuyệt đối. Điểm ảnh được biểu thị dưới dạng số và khoảng cách tuyệt đối dưới dạng chuỗi, với ký tự cuối biểu thị đơn vị:
ccho centimet,icho inch,mcho milimet,pcho điểm của máy in. Ví dụ: 3,5 inch được biểu thị bằng"3.5i".- phông chữ
Tk sử dụng định dạng tên phông chữ danh sách, chẳng hạn như
{courier 10 bold}. Cỡ chữ có số dương được đo bằng điểm; kích thước có số âm được đo bằng pixel.- hình học
Đây là một chuỗi có dạng
widthxheight, trong đó chiều rộng và chiều cao được đo bằng pixel cho hầu hết các tiện ích (bằng ký tự cho các tiện ích hiển thị văn bản). Ví dụ:fred["geometry"] = "200x100".- biện minh
Giá trị pháp lý là các chuỗi:
"left","center"và"right".- khu vực
Đây là một chuỗi có bốn phần tử được phân cách bằng dấu cách, mỗi phần tử là một khoảng cách hợp pháp (xem ở trên). Ví dụ:
"2 3 4 5"và"3i 2i 4.5i 2i"và"3c 2c 4c 10.43c"đều là khu vực hợp pháp.- cứu trợ
Xác định kiểu đường viền của một widget sẽ như thế nào. Giá trị pháp lý là:
"raised","sunken","flat","groove"và"ridge".- lệnh cuộn
Đây hầu như luôn là phương thức
set()của một số tiện ích thanh cuộn, nhưng có thể là bất kỳ phương thức tiện ích nào có một đối số duy nhất.- bọc
Phải là một trong:
"none","char"hoặc"word".
Ràng buộc và sự kiện¶
Phương thức liên kết từ lệnh widget cho phép bạn theo dõi các sự kiện nhất định và kích hoạt chức năng gọi lại khi loại sự kiện đó xảy ra. Hình thức của phương thức liên kết là:
def bind(self, Sequence, func, add=''):
ở đâu:
- trình tự
là một chuỗi biểu thị loại sự kiện mục tiêu. (Xem trang man bind(3tk) và trang 201 trong cuốn sách của John Ousterhout, Tcl and the Tk Toolkit (2nd edition), để biết chi tiết).
- vui vẻ
là một hàm Python, lấy một đối số, sẽ được gọi khi sự kiện xảy ra. Một phiên bản Sự kiện sẽ được chuyển làm đối số. (Các chức năng được triển khai theo cách này thường được gọi là callbacks.)
- thêm
là tùy chọn,
''hoặc'+'. Việc chuyển một chuỗi trống biểu thị rằng liên kết này sẽ thay thế bất kỳ liên kết nào khác mà sự kiện này được liên kết. Việc chuyển'+'có nghĩa là hàm này sẽ được thêm vào danh sách các hàm liên kết với loại sự kiện này.
Ví dụ:
def Turn_red(tự, sự kiện):
event.widget["activeforeground"] = "đỏ"
self.button.bind("<Enter>", self.turn_red)
Lưu ý cách truy cập trường widget của sự kiện trong lệnh gọi lại turn_red(). Trường này chứa tiện ích đã phát hiện sự kiện X. Bảng sau liệt kê các trường sự kiện khác mà bạn có thể truy cập và cách chúng được biểu thị bằng Tk, điều này có thể hữu ích khi tham khảo các trang Tk man.
Tk |
Trường sự kiện Tkinter |
Tk |
Trường sự kiện Tkinter |
|---|---|---|---|
%f |
tiêu điểm |
%A |
ký tự |
% giờ |
chiều cao |
%E |
gửi_sự kiện |
%k |
mã khóa |
%K |
keysym |
%s |
tiểu bang |
%N |
keysym_num |
%t |
thời gian |
%T |
loại |
%w |
chiều rộng |
%W |
tiện ích |
%x |
x |
%X |
x_root |
%y |
y |
%Y |
y_root |
Tham số chỉ số¶
Một số tiện ích yêu cầu phải thông qua các tham số "chỉ mục". Chúng được sử dụng để trỏ đến một vị trí cụ thể trong tiện ích Văn bản hoặc tới các ký tự cụ thể trong tiện ích Mục nhập hoặc tới các mục menu cụ thể trong tiện ích Menu.
- Chỉ mục tiện ích nhập (chỉ mục, chỉ mục xem, v.v.)
Các tiện ích nhập có các tùy chọn tham chiếu đến vị trí ký tự trong văn bản đang được hiển thị. Bạn có thể sử dụng các hàm
tkinternày để truy cập các điểm đặc biệt này trong các tiện ích văn bản:- Chỉ mục tiện ích văn bản
Ký hiệu chỉ mục cho các tiện ích Văn bản rất phong phú và được mô tả rõ nhất trong các trang Tk man.
- Chỉ mục menu (menu.invoke(), menu.entryconfig(), v.v.)
Một số tùy chọn và phương pháp cho menu thao tác các mục menu cụ thể. Bất cứ khi nào cần có chỉ mục menu cho một tùy chọn hoặc tham số, bạn có thể chuyển vào:
một số nguyên đề cập đến vị trí số của mục nhập trong tiện ích, được tính từ trên xuống, bắt đầu bằng 0;
chuỗi
"active", đề cập đến vị trí menu hiện ở dưới con trỏ;chuỗi
"last"đề cập đến mục menu cuối cùng;Một số nguyên đứng trước
@, như trong@6, trong đó số nguyên được hiểu là tọa độ pixel y trong hệ tọa độ của menu;chuỗi
"none", cho biết không có mục menu nào cả, thường được sử dụng nhất với menu.activate() để hủy kích hoạt tất cả các mục và cuối cùng,một chuỗi văn bản có mẫu khớp với nhãn của mục menu, khi được quét từ đầu menu xuống cuối. Lưu ý rằng loại chỉ mục này được xem xét sau tất cả các loại khác, điều đó có nghĩa là các kết quả khớp với các mục menu có nhãn
last,activehoặcnonecó thể được hiểu là các chữ ở trên.
Hình ảnh¶
Hình ảnh có định dạng khác nhau có thể được tạo thông qua lớp con tương ứng của tkinter.Image:
BitmapImagecho hình ảnh ở định dạng XBM.PhotoImagecho hình ảnh ở định dạng PGM, PPM, GIF và PNG. Cái sau được hỗ trợ bắt đầu với Tk 8.6.
Một trong hai loại hình ảnh được tạo thông qua tùy chọn file hoặc data (các tùy chọn khác cũng có sẵn).
Thay đổi trong phiên bản 3.13: Đã thêm phương thức PhotoImage copy_replace() để sao chép một vùng từ hình ảnh này sang hình ảnh khác, có thể bằng cách thu phóng pixel và/hoặc lấy mẫu con. Thêm tham số from_coords vào các phương thức PhotoImage copy(), zoom() và subsample(). Thêm tham số zoom và subsample vào phương thức PhotoImage copy().
Sau đó, đối tượng hình ảnh có thể được sử dụng ở bất cứ nơi nào tùy chọn image được một số tiện ích hỗ trợ (ví dụ: nhãn, nút, menu). Trong những trường hợp này, Tk sẽ không giữ tham chiếu đến hình ảnh. Khi tham chiếu Python cuối cùng đến đối tượng hình ảnh bị xóa, dữ liệu hình ảnh cũng bị xóa và Tk sẽ hiển thị một hộp trống ở bất kỳ nơi nào hình ảnh được sử dụng.
Xem thêm
Gói Pillow bổ sung hỗ trợ cho các định dạng như BMP, JPEG, TIFF và WebP, cùng nhiều định dạng khác.
Trình xử lý tệp¶
Tk cho phép bạn đăng ký và hủy đăng ký một chức năng gọi lại sẽ được gọi từ vòng lặp chính Tk khi I/O có thể thực hiện được trên bộ mô tả tệp. Chỉ có thể đăng ký một trình xử lý cho mỗi bộ mô tả tệp. Mã ví dụ:
nhập khẩu tkinter
tiện ích = tkinter.Tk()
mặt nạ = tkinter.READABLE | tkinter.WRITABLE
widget.tk.createfilehandler(tệp, mặt nạ, gọi lại)
...
widget.tk.deletefilehandler(tệp)
Tính năng này không có sẵn trên Windows.
Vì bạn không biết có bao nhiêu byte để đọc nên bạn có thể không muốn sử dụng các phương thức BufferedIOBase hoặc TextIOBase read() hoặc readline(), vì các phương thức này sẽ yêu cầu đọc số byte được xác định trước. Đối với ổ cắm, phương thức recv() hoặc recvfrom() sẽ hoạt động tốt; đối với các tệp khác, hãy sử dụng chế độ đọc thô hoặc os.read(file.fileno(), maxbytecount).
- Widget.tk.createfilehandler(file, mask, func)¶
Đăng ký hàm gọi lại trình xử lý tệp func. Đối số file có thể là một đối tượng có phương thức
fileno()(chẳng hạn như đối tượng tệp hoặc ổ cắm) hoặc một bộ mô tả tệp số nguyên. Đối số mask là sự kết hợp ORed của bất kỳ hằng số nào trong ba hằng số bên dưới. Cuộc gọi lại được gọi như sau:gọi lại (tập tin, mặt nạ)
- Widget.tk.deletefilehandler(file)¶
Hủy đăng ký một trình xử lý tập tin.