Saat ini saya bermigrasi dari wxPython 4.0.7 ke wxPython 4.1.0. Ini mengubah versi wx dari 3.0.x menjadi 3.1.x.

Tl; dr: Menggunakan wx.ListCtrl terkadang saya mendapatkan error saat memanggil event.Skip() di dalam event handler wxEVT_SIZE. Ke Skip() atau tidak ke Skip()? (yaitu apa penanganan acara default untuk wxEVT_SIZE dan apakah saya membutuhkannya?)


Versi Panjang:

Menggunakan wx.ListCtrl dengan event.Skip di dalam wxEVT_SIZE handler menghasilkan kesalahan dalam beberapa formulir saya (jadi saya pikir pasti ada lebih dari itu). Sekarang, saya tidak dapat menghapus kejadian apa pun untuk mendapatkan contoh minimal, karena kesalahannya agak hilang secara acak ketika saya menghapus (tampaknya) bagian kode yang tidak terkait. Kesalahan bahkan hilang (kadang-kadang) ketika saya mengganti label panjang dengan label yang lebih pendek. Namun, mengubah ukuran Bingkai atau Panel tidak mengubah apa pun.

Inilah, apa yang saya temukan:

  • Kesalahan pasti terkait dengan penggunaan kelas wx.ListCtrl}
  • Kesalahan hanya terjadi, ketika suatu fungsi terikat ke peristiwa wxEVT_COMMAND_LIST_ITEM_ACTIVATED, meskipun penangan kosong (dengan atau tanpa Skip()) sudah cukup untuk memicu kesalahan.
  • Kesalahan hanya terjadi ketika suatu fungsi terikat pada peristiwa wxEVT_SIZE
  • Kesalahan hanya terjadi ketika saya memanggil event.Skip() di wxEVT_SIZE handler

Sepertinya saya cukup menghapus panggilan event.Skip() di dalam handler wxEVT_SIZE dan selesai, tetapi Kode C++ yang relevan sepertinya ada lebih banyak yang terjadi.

Inilah kesalahannya (catatan: kesalahan tidak membuat crash wxApp):

wx._core.wxAssertionError: C++ assertion "nNew != dynamicEvents.size()" failed at ..\..\src\common\event.cpp(1926) in wxEvtHandler::SearchDynamicEventTable():

The above exception was the direct cause of the following exception:

SystemError: <class 'wx._core.SizeEvent'> returned a result with an error set

Kode C++ yang relevan dalam repositori github dapat ditemukan di sini: https://github.com/wxWidgets/wxWidgets/blob/e803408058186a7a9a61c456246f145abcaccd13/src/common/event.cpp#L1926

(Petunjuk: Ini adalah versi wxWidget yang disematkan yang digunakan dalam Rilis wxPython 4.1.0)

Adakah pakar wx & C++ di sini, yang mungkin tahu apa yang terjadi?

-1
Anaconda 11 Mei 2021, 17:40

1 menjawab

Jawaban Terbaik

Saya percaya pernyataan ini hanya dapat dipicu jika penangan memanggil Bind() dari pengendali acaranya, tetapi melewatkan acara tersebut, yaitu berpura-pura bahwa acara tersebut tidak ditangani sama sekali. Di dunia yang ideal, ini seharusnya mungkin dan saya pikir pernyataan itu sebenarnya terlalu bersemangat dan perlu santai, tetapi untuk saat ini, jika Anda benar-benar perlu melakukannya seperti ini, Anda harus:

  1. Tunda panggilan Bind() dengan menggunakan CallAfter().
  2. Atau hindari menelepon event.Skip().

(perhatikan bahwa pernyataan tidak akan selalu dipicu dalam kasus ini, Anda juga perlu menghapus penangan yang sebelumnya terhubung ke objek yang sama sesaat sebelumnya).

Tetapi secara umum Anda harus memanggil Skip() kecuali Anda telah sepenuhnya memproses acara dan tidak ingin ada penangan lain, baik yang ada di kelas dasar atau yang sudah ada di dalamnya, untuk menjalankan setelah Anda. Untuk wxEVT_SIZE itu berarti Anda telah melakukan tata letak ulang jendela sendiri dan tidak ingin kelas dasar melakukan apa pun. Jadi solusi (1) lebih baik karena dapat digunakan bahkan jika Anda ingin penangan kelas dasar dijalankan.

0
VZ. 12 Mei 2021, 11:09