يقوم Python Tkinter بلف عناصر واجهة المستخدم في الإطار إذا وصلت إلى نهاية الشاشة

StackOverflow https://stackoverflow.com//questions/20012860

سؤال

هل هناك شيء مثل حزمة السطر الجديد لمدير هندسة Tk؟أنا أستخدم الحزمة لوضع الأدوات داخل الإطار.على شاشة عالية الدقة، يمكن العثور على الأدوات جنبًا إلى جنب.ومع ذلك، إذا قمت بوضعها في شاشة أصغر، فسوف تنفد الأدوات من المساحة الموجودة في الإطار.

في الأساس، ننتقل من:

Before

ل:

after

يمكنك أن ترى كيف يتم قطع حقل إدخال المعالجات الخاص بي.الكود ذو الصلة:

options_frame = ttk.LabelFrame(
        parent_frame, text="Blast Options")
options_frame.pack(side=TOP, fill=X, expand=1, padx=5, pady=5)
        self._set_up_blast_options(options_frame)

def _set_up_blast_options(self, options_frame):
    self.evalue = Tkinter.DoubleVar()
    self.evalue.set(1)
    self.word_size = Tkinter.IntVar()
    self.word_size.set(4)
    self.penalty_mismatch = Tkinter.DoubleVar()
    self.penalty_mismatch.set(-4)
    self.min_d_match = Tkinter.IntVar()
    self.min_d_match.set(5)
    self.proc_count = Tkinter.IntVar()
    self.proc_count.set(cpu_count())

    # evalue
    e_value_label = ttk.LabelFrame(
        options_frame, text="e-Value Threshold")
    e_value_entry = ttk.Entry(e_value_label)
    e_value_entry.insert(0, self.evalue.get())
    e_value_entry.bind('<Return>', self._validate_e_value)
    e_value_entry.bind('<FocusOut>', self._validate_e_value)
    e_value_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    e_value_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

    # word size
    word_size_label = ttk.LabelFrame(
        options_frame, text="Word Size")
    word_size_entry = ttk.Entry(word_size_label)
    word_size_entry.insert(0, self.word_size.get())
    word_size_entry.bind('<Return>', self._validate_word_value)
    word_size_entry.bind('<FocusOut>', self._validate_word_value)
    word_size_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    word_size_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

    penalty_mismatch_label = ttk.LabelFrame(
        options_frame, text="Penalty Mismatch")
    penalty_mismatch_entry = ttk.Entry(penalty_mismatch_label)
    penalty_mismatch_entry.insert(0, self.penalty_mismatch.get())
    penalty_mismatch_entry.bind(
        '<Return>', self._validate_penalty_mismatch_value)
    penalty_mismatch_entry.bind(
        '<FocusOut>', self._validate_penalty_mismatch_value)
    penalty_mismatch_label.pack(side=LEFT, expand=1, pady=5,
                                padx=5, fill=X)
    penalty_mismatch_entry.pack(side=TOP, expand=1, pady=5,
                                padx=5, fill=X)
    # Min D Nucleotides
    min_d_match_label = ttk.LabelFrame(
        options_frame, text="Minimal Number of D Nucleotides")
    min_d_match_entry = ttk.Entry(min_d_match_label)
    min_d_match_entry.insert(0, self.min_d_match.get())
    min_d_match_entry.bind(
        '<Return>', self._validate_min_match_value)
    min_d_match_entry.bind(
        '<FocusOut>', self._validate_min_match_value)
    min_d_match_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    min_d_match_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

    # how many cpus to use
    proc_count_label = ttk.LabelFrame(
        options_frame, text="Processors")
    proc_count_entry = ttk.Entry(proc_count_label)
    proc_count_entry.insert(0, self.proc_count.get())
    proc_count_entry.bind(
        '<Return>', self._validate_proc_count_value)
    proc_count_entry.bind(
        '<FocusOut>', self._validate_proc_count_value)
    proc_count_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    proc_count_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

قد لا يكون الكثير من ربط الأحداث وإعدادات الخيارات ذات صلة، لكنني أعتقد أنه لا يزال يتعين علي تضمينها... فقط في حالة حدوث ذلك.هل سيكون الخيار الأفضل هو التبديل إلى مدير الشبكة؟ستكون المشكلة أن هذا الإطار معبأ داخل إطار آخر...وهكذا.أليس أنه إذا بدأت في استخدام مدير الشبكة، فسيتعين عليك استخدامه في كل شيء لأنه لا يمكنك الجمع بين مدير الشبكة ومدير الشبكة في نفس الإطار؟

هل كانت مفيدة؟

المحلول

afaik لا توجد طريقة محدثة لإنشاء واجهات ديناميكية في Tkinter.أفضل رهان لديك هو الحصول على دقة الشاشة ثم الشبكة / الحزمة بشكل مناسب.

giveacodicetagpre.

لذلك على سبيل المثال ....

giveacodicetagpre.

نصائح أخرى

بشكل عام، أنا أتفق مع إجابة I_do_python، ولكنني أود إجراء تعديل صغير واحد.أود أن أضع جميع عناصر واجهة المستخدم في إطار جديد، وسأستخدم عرض الإطار باعتباره اختبارًا لتحديد ما إذا كان سيتم الالتفاف أم لا.ويمكنك ربط معالج الأحداث لـ "<Configure>" الحدث الذي يتحقق بعد ذلك لمعرفة ما إذا كانت محتويات الإطار بحاجة إلى التغليف عند تغيير حجم نافذة التطبيق (وبالتالي الإطار).

لقد كتبت الوظيفة أدناه التي تستخدم طريقة الشبكة لإدراج عناصر واجهة المستخدم بذكاء في الإطار.يمكن بالتأكيد تحسينه، لكنه يعمل بالنسبة لي.عادة إذا كنت تستخدم .grid() لملء أحد الوالدين، يمكنك الحصول على مساحة بيضاء مهدرة عندما تختلف عناصر واجهة المستخدم في العرض.تعالج الوظيفة أدناه هذا عن طريق تقسيم الأصل إلى أعمدة منطقية (divisions في الكود) والسماح للأدوات بالامتداد على أعمدة متعددة.والنتيجة هي تخطيط شبكي مع مساحة بيضاء مهدرة أقل بكثير.كلما قمت بتعيين أعلى divisions, كلما كانت النتيجة أفضل، ولكن القيمة الافتراضية يجب أن تعمل في معظم المواقف.

def smart_grid(parent, *args, **kwargs): # *args are the widgets!
    divisions   = kwargs.pop('divisions', 100)
    force_f     = kwargs.pop('force', False)
    if 'sticky' not in kwargs:
        kwargs.update(sticky='w')
    try:
        parent.win_width
    except:
        parent.win_width = -1
    winfo_width = parent.winfo_width()
    if 1 < winfo_width != parent.win_width or force_f:
        parent.win_width = winfo_width
        row = col = width = 0
        argc = len(args)
        for i in range(argc):
            widget_width = args[i].winfo_width()
            columns = max(1, int(widget_width * float(divisions) / winfo_width))
            width += widget_width
            if width > winfo_width:
                width = widget_width
                row += 1
                col = 0
            args[i].grid(row=row, column=col, columnspan=columns, **kwargs)
            col += columns
        parent.update_idletasks() # update() # 
        return row + 1

في النهاية سأستغرق بضع دقائق لإعادة كتابتها w.winfo_reqwidth() وسيتم تحديث منصبي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top