টিকিনটারে উইন্ডোটি বন্ধ করার ইভেন্টটি আমি কীভাবে পরিচালনা করব?


130

আমি পাইথন টিন্টার প্রোগ্রামে উইন্ডোটি বন্ধ করার ইভেন্টটি (ব্যবহারকারী 'এক্স' বোতামে ক্লিক করা) কীভাবে পরিচালনা করব?

উত্তর:


178

টিন্টার প্রোটোকল হ্যান্ডলার নামক একটি প্রক্রিয়া সমর্থন করে । এখানে, প্রোটোকল শব্দটি অ্যাপ্লিকেশন এবং উইন্ডো ম্যানেজারের মধ্যে মিথস্ক্রিয়া বোঝায়। সর্বাধিক ব্যবহৃত প্রোটোকল বলা হয়WM_DELETE_WINDOW এবং যখন ব্যবহারকারী স্পষ্টভাবে উইন্ডো ম্যানেজারটি ব্যবহার করে উইন্ডো বন্ধ করে তখন কী ঘটে তা সংজ্ঞায়িত করতে ব্যবহৃত হয়।

আপনি এই প্রোটোকলের জন্য হ্যান্ডলার ইনস্টল করতে protocolপদ্ধতিটি ব্যবহার করতে পারেন (উইজেটটি অবশ্যই একটি বা উইজেট হতে হবে ):TkToplevel

এখানে আপনার একটি দৃ concrete় উদাহরণ রয়েছে:

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()

def on_closing():
    if messagebox.askokcancel("Quit", "Do you want to quit?"):
        root.destroy()

root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()

2
আপনি যদি ট্যুইস্টের মতো এমন কিছু ব্যবহার করছেন যা কোনও ইভেন্ট লুপটি স্বাধীনভাবে বজায় রাখে বা টিন্টার (উদাহরণস্বরূপ: টুইস্টেড রিঅ্যাক্টর অবজেক্ট) নিশ্চিত করে যে বাইরের মূল লুপটি সে উদ্দেশ্যে যা কিছু স্মৃতিচারণ করে তা বন্ধ করা হয়েছে (যেমন: রিঅ্যাক্টর.স্টপ () মোচড়ের জন্য)
ব্রায়ান জ্যাক

4
উইন্ডোজে আমার পাইথন ২.7 এ, Tkinterসাবমডিউল মেসেজবক্স নেই। আমি ব্যবহার করেছিimport tkMessageBox as messagebox
IronManMark20

আমি মনে করি আপনার জানা উচিত যে আপনি এই উত্তর এবং কোডটি অন্য কারও কাছ থেকে / যেখানে অনুলিপি করেছেন।
খ্রিস্টান ডিন

1
আমি জানি না, এটি মূলত পোস্ট করা কোড নয়।
ম্যাট গ্রেগরি

আমার জন্য কাজ করে না। যখন কেউ হার্ড উইন্ডোটি বন্ধ করে (যেমন Alt + F4 সহ) উইন্ডোজ বন্ধ করে দেয় তখন গ্রাফিক্সের ব্যাঘাতের জন্য ক্লাসিক পাইথনের বিশৃঙ্খলাজনিত প্রতিক্রিয়া পরিবর্তন হয় না।
অ্যাপোস্টোলোস

29

ম্যাট ক্লোজ বোতামটির একটি ক্লাসিক পরিবর্তন দেখিয়েছে।
অন্যটি হ'ল বন্ধ বোতামটি উইন্ডোটি ছোট করা উচিত।
আপনি না থাকার এই আচরণ পুনরুত্পাদন করতে iconify পদ্ধতি
হতে প্রোটোকল পদ্ধতি দ্বিতীয় যুক্তি।

উইন্ডোজ 7 এবং 10 এ পরীক্ষিত এখানে একটি কার্যকারী উদাহরণ রয়েছে:

# Python 3
import tkinter
import tkinter.scrolledtext as scrolledtext

root = tkinter.Tk()
# make the top right close button minimize (iconify) the main window
root.protocol("WM_DELETE_WINDOW", root.iconify)
# make Esc exit the program
root.bind('<Escape>', lambda e: root.destroy())

# create a menu bar with an Exit command
menubar = tkinter.Menu(root)
filemenu = tkinter.Menu(menubar, tearoff=0)
filemenu.add_command(label="Exit", command=root.destroy)
menubar.add_cascade(label="File", menu=filemenu)
root.config(menu=menubar)

# create a Text widget with a Scrollbar attached
txt = scrolledtext.ScrolledText(root, undo=True)
txt['font'] = ('consolas', '12')
txt.pack(expand=True, fill='both')

root.mainloop()

এই উদাহরণে আমরা ব্যবহারকারীকে দুটি নতুন প্রস্থান বিকল্পগুলি দেই:
ক্লাসিক ফাইল → প্রস্থান করুন এবং Escবোতামটিও।


12

টিনেটার ক্রিয়াকলাপের উপর নির্ভর করে এবং বিশেষত টিনেটার.এর পরে, এই ক্রিয়াকলাপটি destroy()- এমনকি প্রোটোকল (), একটি বোতাম ইত্যাদির সাহায্যে থামিয়ে দেওয়া - এই ক্রিয়াকলাপটি (কেবল "ত্রুটি কার্যকর করার সময়" ত্রুটিযুক্ত করবে) কেবল এটি বন্ধ করার পরিবর্তে । প্রায় প্রতিটি ক্ষেত্রেই সেরা সমাধান হ'ল পতাকা ব্যবহার করা। এটি কীভাবে ব্যবহার করা যায় তার একটি সহজ এবং নির্বোধ উদাহরণ (যদিও আমি নিশ্চিত যে আপনার বেশিরভাগের এটির প্রয়োজন নেই! :)

from Tkinter import *

def close_window():
  global running
  running = False  # turn off while loop
  print( "Window closed")

root = Tk()
root.protocol("WM_DELETE_WINDOW", close_window)
cv = Canvas(root, width=200, height=200)
cv.pack()

running = True;
# This is an endless loop stopped only by setting 'running' to 'False'
while running: 
  for i in range(200): 
    if not running: 
        break
    cv.create_oval(i, i, i+1, i+1)
    root.update() 

এটি গ্রাফিক্সের ক্রিয়াকলাপটি দুর্দান্তভাবে শেষ করে। আপনার কেবলমাত্র runningসঠিক স্থানে পরীক্ষা করা উচিত need


4

এটিকে আমার নজরে আনার জন্য আমি অ্যাপোস্টোলসের জবাবটি ধন্যবাদ জানাতে চাই। এখানে পরিষ্কার বর্ণনা এবং উদাহরণ কোড সহ 2019 সালে পাইথন 3 এর আরও অনেক বিশদ উদাহরণ।


এই বিষয়টি থেকে সাবধান থাকুন destroy()(বা কাস্টম উইন্ডোটি ক্লোজিং হ্যান্ডলারটি না পেয়ে) উইন্ডোটি এবং তার চলমান সমস্ত কলব্যাকগুলি তত্ক্ষণাত ধ্বংস করবে যখন ব্যবহারকারী এটি বন্ধ করে দেবে।

আপনার বর্তমান টিনকিটার ক্রিয়াকলাপের উপর নির্ভর করে এবং বিশেষত ব্যবহার করার সময় এটি আপনার পক্ষে খারাপ হতে পারে tkinter.after (পর্যায়ক্রমিক কলব্যাকস) । আপনি সম্ভবত একটি কলব্যাক ব্যবহার করছেন যা কিছু ডেটা প্রক্রিয়াকরণ করে এবং ডিস্কে লেখেন ... সেক্ষেত্রে আপনি সম্ভবত ডেটা রচনাটি হঠাৎ করে হত্যা না করেই শেষ করতে চান।

এর জন্য সর্বোত্তম সমাধান হ'ল পতাকা ব্যবহার করা। সুতরাং যখন ব্যবহারকারী উইন্ডোটি বন্ধ করার অনুরোধ করবেন, আপনি এটিকে পতাকা হিসাবে চিহ্নিত করুন এবং তারপরে এটি প্রতিক্রিয়া জানান।

(দ্রষ্টব্য: আমি সাধারণত জিইআইআইগুলি দুর্দান্ত এনপ্যাপুলেটেড ক্লাস এবং পৃথক কর্মী থ্রেড হিসাবে ডিজাইন করি এবং আমি অবশ্যই "গ্লোবাল" ব্যবহার করি না (পরিবর্তে আমি শ্রেণীর উদাহরণের ভেরিয়েবল ব্যবহার করি)) তবে এটি বোঝানোর জন্য একটি সাধারণ, স্ট্রিপ-ডাউন উদাহরণ হিসাবে বোঝানো হয়েছে যখন ব্যবহারকারী উইন্ডোটি বন্ধ করে দেয় তখন হঠাৎ করে আপনার সাময়িকী কলব্যাকগুলি কীভাবে হত্যা করে ...)

from tkinter import *
import time

# Try setting this to False and look at the printed numbers (1 to 10)
# during the work-loop, if you close the window while the periodic_call
# worker is busy working (printing). It will abruptly end the numbers,
# and kill the periodic callback! That's why you should design most
# applications with a safe closing callback as described in this demo.
safe_closing = True

# ---------

busy_processing = False
close_requested = False

def close_window():
    global close_requested
    close_requested = True
    print("User requested close at:", time.time(), "Was busy processing:", busy_processing)

root = Tk()
if safe_closing:
    root.protocol("WM_DELETE_WINDOW", close_window)
lbl = Label(root)
lbl.pack()

def periodic_call():
    global busy_processing

    if not close_requested:
        busy_processing = True
        for i in range(10):
            print((i+1), "of 10")
            time.sleep(0.2)
            lbl["text"] = str(time.time()) # Will error if force-closed.
            root.update() # Force redrawing since we change label multiple times in a row.
        busy_processing = False
        root.after(500, periodic_call)
    else:
        print("Destroying GUI at:", time.time())
        try: # "destroy()" can throw, so you should wrap it like this.
            root.destroy()
        except:
            # NOTE: In most code, you'll wanna force a close here via
            # "exit" if the window failed to destroy. Just ensure that
            # you have no code after your `mainloop()` call (at the
            # bottom of this file), since the exit call will cause the
            # process to terminate immediately without running any more
            # code. Of course, you should NEVER have code after your
            # `mainloop()` call in well-designed code anyway...
            # exit(0)
            pass

root.after_idle(periodic_call)
root.mainloop()

এই কোডটি আপনাকে দেখাবে যে WM_DELETE_WINDOWআমাদের কাস্টম চলাকালীন হ্যান্ডলারটি চলমান runsperiodic_call() কাজের / লুপগুলির মাঝে ব্যস্ত !

আমরা কিছু চমত্কার অতিরঞ্জিত .after()মান ব্যবহার করি : 500 মিলিসেকেন্ড onds এই মাত্র এটা খুব সহজ করতে আপনি বন্ধের মধ্যে পার্থক্য দেখার জন্য যখন পর্যায়ক্রমিক কল ব্যস্ত, বা না ... আপনি ঘনিষ্ঠ যখন সংখ্যার আপডেট করছি, আপনি দেখতে হবে বোঝানো হয় WM_DELETE_WINDOWঘটেছে যখন আপনার পর্যাবৃত্ত call " ব্যস্ত প্রক্রিয়াকরণ: সত্য "। যদি সংখ্যাগুলি থামার সময় আপনি বন্ধ করে থাকেন (এর অর্থ এই মুহূর্তে পর্যায়ক্রমিক কলব্যাক প্রক্রিয়া করছে না), আপনি দেখতে পাচ্ছেন যে এটি "ব্যস্ত নয়" অবস্থায় বন্ধটি ঘটেছে।

বাস্তব-বিশ্বের ব্যবহারের ক্ষেত্রে, আপনার .after()প্রতিক্রিয়াশীল জিইউআই রাখতে 30-100 মিলিসেকেন্ডের মতো কিছু ব্যবহার করা হবে। "টাকার ডিফল্ট থেকে নিজেকে কীভাবে রক্ষা করবেন" "আচরণ বন্ধ করার সাথে সাথে সমস্ত কাজ তাত্ক্ষণিকভাবে বাধাগ্রস্ত করতে" আপনাকে বুঝতে সাহায্য করার জন্য এটি কেবল একটি বিক্ষোভ।

সংক্ষিপ্তসার: WM_DELETE_WINDOWহ্যান্ডলারটি একটি পতাকা সেট করুন এবং তারপরে .destroy()উইন্ডোটি সুরক্ষিত অবস্থায় সময় সময় এবং ম্যানুয়ালি সেই পতাকাটি পরীক্ষা করুন (যখন আপনার অ্যাপ্লিকেশনটি সমস্ত কাজ সম্পন্ন হয়)।

পিএস: আপনি যদি সত্যিই উইন্ডোটি বন্ধ করতে চান তবে ব্যবহারকারীকে জিজ্ঞাসা করতেও আপনি এটি ব্যবহার WM_DELETE_WINDOWকরতে পারেন ; এবং যদি তারা না উত্তর দেয় আপনি পতাকা সেট করবেন না। এটা খুবই সাধারণ. আপনি কেবল আপনার একটি বার্তা বাক্স দেখান WM_DELETE_WINDOWএবং ব্যবহারকারীর উত্তরের ভিত্তিতে পতাকা সেট করে।


1

সহজ সংস্করণ চেষ্টা করুন:

import tkinter

window = Tk()

closebutton = Button(window, text='X', command=window.destroy)
closebutton.pack()

window.mainloop()

অথবা আপনি যদি আরও কমান্ড যুক্ত করতে চান:

import tkinter

window = Tk()


def close():
    window.destroy()
    #More Functions


closebutton = Button(window, text='X', command=close)
closebutton.pack()

window.mainloop()

উইন্ডোটি বন্ধ করার জন্য ওএসের এক্স বোতাম সম্পর্কে প্রশ্নটি নিয়মিত বোতাম নিয়ন্ত্রণ নয়।
ব্যবহারকারী 1318499

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.