Adik laki-laki saya baru saja masuk ke pemrograman, dan untuk proyek Science Fair-nya, dia melakukan simulasi sekawanan burung di langit. Dia mendapatkan sebagian besar kodenya tertulis, dan itu bekerja dengan baik, tetapi burung perlu bergerak setiap saat .
Tkinter, bagaimanapun, memonopoli waktu untuk event loopnya sendiri, sehingga kodenya tidak akan berjalan. Melakukan root.mainloop()
lari, lari, dan terus berlari, dan satu-satunya yang dijalankannya adalah pengendali kejadian.
Apakah ada cara agar kodenya berjalan bersama mainloop (tanpa multithreading, itu membingungkan dan ini harus dibuat sederhana), dan jika demikian, apa itu?
Saat ini, dia datang dengan peretasan jelek, mengikat move()
fungsinya ke <b1-motion>
, sehingga selama dia menahan tombol dan menggoyangkan mouse, itu berhasil. Tapi pasti ada cara yang lebih baik.
threading
modul.The solusi diposting oleh Bjorn hasil dalam "RuntimeError: Memanggil Tcl dari apartemen yang berbeda" pesan di komputer saya (RedHat Enterprise 5, python 2.6.1). Bjorn mungkin tidak mendapatkan pesan ini, karena menurut satu tempat yang saya periksa , kesalahan penanganan threading dengan Tkinter tidak dapat diprediksi dan bergantung pada platform.
Masalahnya tampaknya yang
app.start()
dihitung sebagai referensi ke Tk, karena aplikasi berisi elemen Tk. Saya memperbaikinya dengan menggantiapp.start()
dengan bagianself.start()
dalam__init__
. Saya juga membuatnya sehingga semua referensi Tk baik di dalam fungsi yang memanggilmainloop()
atau di dalam fungsi yang dipanggil oleh fungsi yang memanggilmainloop()
(ini tampaknya penting untuk menghindari kesalahan "apartemen berbeda").Akhirnya, saya menambahkan penangan protokol dengan callback, karena tanpa ini program keluar dengan kesalahan ketika jendela Tk ditutup oleh pengguna.
Kode yang direvisi adalah sebagai berikut:
sumber
run
metode tersebut? Sepertinya saya tidak tahu bagaimana ...__init__(..)
, menyimpannyaself
dan menggunakannya dirun(..)
while app.is_alive(): etc
Saat menulis loop Anda sendiri, seperti dalam simulasi (saya asumsikan), Anda perlu memanggil
update
fungsi yang melakukan apa yangmainloop
dilakukannya: memperbarui jendela dengan perubahan Anda, tetapi Anda melakukannya di loop Anda.sumber
task
dipanggil, Anda akan berakhir dengan loop acara bersarang, dan itu buruk. Kecuali Anda benar-benar memahami cara kerja loop acara, Anda harus menghindari panggilanupdate
dengan cara apa pun.Pilihan lainnya adalah membiarkan tkinter mengeksekusi pada utas terpisah. Salah satu caranya adalah seperti ini:
Berhati-hatilah, pemrograman multithread itu sulit dan sangat mudah untuk menembak diri Anda sendiri. Misalnya Anda harus berhati-hati ketika Anda mengubah variabel anggota dari kelas contoh di atas sehingga Anda tidak mengganggu event loop Tkinter.
sumber
Ini adalah versi kerja pertama dari apa yang akan menjadi pembaca GPS dan penyaji data. tkinter adalah hal yang sangat rapuh dengan terlalu sedikit pesan kesalahan. Itu tidak meletakkan barang-barang dan tidak memberi tahu mengapa banyak waktu. Sangat sulit datang dari pengembang formulir WYSIWYG yang baik. Bagaimanapun, ini menjalankan rutinitas kecil 10 kali per detik dan menyajikan informasi pada formulir. Butuh beberapa saat untuk mewujudkannya. Ketika saya mencoba nilai pengatur waktu 0, bentuknya tidak pernah muncul. Kepalaku sekarang sakit! 10 kali atau lebih per detik sudah cukup baik untuk saya. Saya harap ini membantu orang lain. Mike Morrow
sumber