te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>user interface - Need to align the boxes horizontally and vertically in python tkinter - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

user interface - Need to align the boxes horizontally and vertically in python tkinter - Stack Overflow

programmeradmin3浏览0评论

How it looks right now

Can someone help me align the boxes horizontally and vertically? In the image, the message entry box and the other 4 boxes are out of align. The message entry box should be the same length as frame1 and frame2. And the boxes inside the frames have different lengths. They should be the same length and aligned with the red lines. For example, it should look like this image: How I want it to look

This is the exact code I have:

import tkinter as tk
from tkinter import ttk, filedialog
from PIL import Image, ImageTk
import sys
import os



root = tk.Tk(className="Chat APP")

root.title("Chat APP")

# Maximize the window
root.attributes('-zoomed', True)


# Get the screen width and height
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()


new_note_icon = Image.open("new_note.jpg")
new_note_icon = new_note_icon.resize((25, 25))
new_note_icon = ImageTk.PhotoImage(new_note_icon)
 


# Proportional calculations
def proportion_width(p):
    return int(screen_width * p)

def proportion_height(p):
    return int(screen_height * p)

chat_frame = tk.Frame(root, bg='white')
chat_frame.pack(expand=True, fill=tk.BOTH)
chat_frame.grid_rowconfigure(0, weight=0)
chat_frame.grid_rowconfigure(1, weight=1)
chat_frame.grid_columnconfigure(0, weight=1)

chat_log = tk.Text(chat_frame, state='disabled', wrap='word', width=70, height=15,
                                font=('Helvetica', 14), bg="white", fg="black", highlightthickness=0, borderwidth=0)
chat_log.grid(row=1, column=0, sticky='NESW', padx=proportion_width(0.275), pady=proportion_height(0.01))

# Create a scrollbar for the chat log
scrollbar = tk.Scrollbar(chat_frame, command=chat_log.yview)
scrollbar.grid(row=1, column=1, sticky='NS')
chat_log['yscrollcommand'] = scrollbar.set

frame1 = tk.Frame(root, bg="white")
frame1.pack(side=tk.TOP,  pady=(proportion_height(0.1), 1))

frame2 = tk.Frame(root, bg="white")
frame2.pack(side=tk.TOP,  pady=(proportion_height(0.005), proportion_height(0.02)))


print("Width is",chat_frame.winfo_width())
chat_with_pdf_button = ttk.Button(frame1, width=proportion_width(0.02), text="Chat with PDF", style="def2.TButton",)
chat_with_pdf_button.pack(side=tk.LEFT, padx=(proportion_width(0.0843),0), ipady=proportion_height(0.01))

# Create a button to trigger the summarization process
summarize_button = ttk.Button(frame1, width=proportion_width(0.02), text="Chat with a YouTube video", style="def2.TButton")
summarize_button.pack(side=tk.LEFT, padx=(proportion_height(0.01), 0), ipady=proportion_height(0.01))

letter_button = ttk.Button(frame2, width=proportion_width(0.02), text="Write a letter", style="def2.TButton")
letter_button.pack(side=tk.LEFT, padx=(proportion_width(0.0843),0), ipady=proportion_height(0.01))

blog_button = ttk.Button(frame2, width=proportion_width(0.02), text="Chat with a Blog Post", style="def2.TButton")
blog_button.pack(side=tk.LEFT, padx=(proportion_height(0.01), 0), ipady=proportion_height(0.01))

new_note_button = ttk.Button(chat_frame, style="Toggle.TButton", image=new_note_icon)
new_note_button.grid(row=0, column=0, sticky='W', padx=(proportion_width(0.272), 0), pady=(proportion_height(0.01), 0))


# Frame to contain message_entry and buttons
frame_for_widgets = tk.Frame(root, bg="white")
frame_for_widgets.pack(side=tk.BOTTOM)

empty_space = tk.Text(
    frame_for_widgets,  # Use frame2 as the parent widget
    width=proportion_width(0.001),  # Adjusting padx proportionally
    bg="white",
    borderwidth=0,
    # Removing fixed width and height, so it expands with the frame
    height=proportion_width(0.000001),
      # Set a fixed height if needed
    spacing1=proportion_height(0.02),  # Adjust spacing1 proportionally
    spacing3=proportion_height(0.02),  # Adjust spacing3 proportionally
    font=('Helvetica', 14)
)


message_entry = tk.Text(
    frame_for_widgets,  # Use frame2 as the parent widget
    width=proportion_width(0.0495),  # Adjusting padx proportionally
    bg="white",
    insertbackground='white',
    fg="white",
    borderwidth=0,
    # Removing fixed width and height, so it expands with the frame
    height=proportion_width(0.000001),
      # Set a fixed height if needed
    spacing1=proportion_height(0.02),  # Adjust spacing1 proportionally
    spacing3=proportion_height(0.02),  # Adjust spacing3 proportionally
    font=('Helvetica', 14)
)

# Pack message_entry into frame2
message_entry.pack(
    side=tk.LEFT,
    padx=(proportion_width(0.208),0),
    #fill=tk.X,  # Fill horizontally
    pady=(0, proportion_height(0.02))
    #padx=(0),
      # Adjusting padx proportionally
      # Adjusting pady proportionally
)

message_entry.mark_set("insert", "%d.%d" % (0,0))

send_icon = Image.open("send_icon.png")
send_icon = send_icon.resize((55, 55))
send_icon = ImageTk.PhotoImage(send_icon)


# Send button
send_button = ttk.Button(frame_for_widgets, image=send_icon,  style="Send.TButton")
send_button.image = send_icon
send_button.pack(side=tk.LEFT, pady=(0, proportion_height(0.02)), padx=(1,0),)

message_entry.focus_set()
root.mainloop()

The problem is that these alignments look different for different screen sizes. It should be aligned for all screen sizes; regardless of the screen size of computer.

How it looks right now

Can someone help me align the boxes horizontally and vertically? In the image, the message entry box and the other 4 boxes are out of align. The message entry box should be the same length as frame1 and frame2. And the boxes inside the frames have different lengths. They should be the same length and aligned with the red lines. For example, it should look like this image: How I want it to look

This is the exact code I have:

import tkinter as tk
from tkinter import ttk, filedialog
from PIL import Image, ImageTk
import sys
import os



root = tk.Tk(className="Chat APP")

root.title("Chat APP")

# Maximize the window
root.attributes('-zoomed', True)


# Get the screen width and height
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()


new_note_icon = Image.open("new_note.jpg")
new_note_icon = new_note_icon.resize((25, 25))
new_note_icon = ImageTk.PhotoImage(new_note_icon)
 


# Proportional calculations
def proportion_width(p):
    return int(screen_width * p)

def proportion_height(p):
    return int(screen_height * p)

chat_frame = tk.Frame(root, bg='white')
chat_frame.pack(expand=True, fill=tk.BOTH)
chat_frame.grid_rowconfigure(0, weight=0)
chat_frame.grid_rowconfigure(1, weight=1)
chat_frame.grid_columnconfigure(0, weight=1)

chat_log = tk.Text(chat_frame, state='disabled', wrap='word', width=70, height=15,
                                font=('Helvetica', 14), bg="white", fg="black", highlightthickness=0, borderwidth=0)
chat_log.grid(row=1, column=0, sticky='NESW', padx=proportion_width(0.275), pady=proportion_height(0.01))

# Create a scrollbar for the chat log
scrollbar = tk.Scrollbar(chat_frame, command=chat_log.yview)
scrollbar.grid(row=1, column=1, sticky='NS')
chat_log['yscrollcommand'] = scrollbar.set

frame1 = tk.Frame(root, bg="white")
frame1.pack(side=tk.TOP,  pady=(proportion_height(0.1), 1))

frame2 = tk.Frame(root, bg="white")
frame2.pack(side=tk.TOP,  pady=(proportion_height(0.005), proportion_height(0.02)))


print("Width is",chat_frame.winfo_width())
chat_with_pdf_button = ttk.Button(frame1, width=proportion_width(0.02), text="Chat with PDF", style="def2.TButton",)
chat_with_pdf_button.pack(side=tk.LEFT, padx=(proportion_width(0.0843),0), ipady=proportion_height(0.01))

# Create a button to trigger the summarization process
summarize_button = ttk.Button(frame1, width=proportion_width(0.02), text="Chat with a YouTube video", style="def2.TButton")
summarize_button.pack(side=tk.LEFT, padx=(proportion_height(0.01), 0), ipady=proportion_height(0.01))

letter_button = ttk.Button(frame2, width=proportion_width(0.02), text="Write a letter", style="def2.TButton")
letter_button.pack(side=tk.LEFT, padx=(proportion_width(0.0843),0), ipady=proportion_height(0.01))

blog_button = ttk.Button(frame2, width=proportion_width(0.02), text="Chat with a Blog Post", style="def2.TButton")
blog_button.pack(side=tk.LEFT, padx=(proportion_height(0.01), 0), ipady=proportion_height(0.01))

new_note_button = ttk.Button(chat_frame, style="Toggle.TButton", image=new_note_icon)
new_note_button.grid(row=0, column=0, sticky='W', padx=(proportion_width(0.272), 0), pady=(proportion_height(0.01), 0))


# Frame to contain message_entry and buttons
frame_for_widgets = tk.Frame(root, bg="white")
frame_for_widgets.pack(side=tk.BOTTOM)

empty_space = tk.Text(
    frame_for_widgets,  # Use frame2 as the parent widget
    width=proportion_width(0.001),  # Adjusting padx proportionally
    bg="white",
    borderwidth=0,
    # Removing fixed width and height, so it expands with the frame
    height=proportion_width(0.000001),
      # Set a fixed height if needed
    spacing1=proportion_height(0.02),  # Adjust spacing1 proportionally
    spacing3=proportion_height(0.02),  # Adjust spacing3 proportionally
    font=('Helvetica', 14)
)


message_entry = tk.Text(
    frame_for_widgets,  # Use frame2 as the parent widget
    width=proportion_width(0.0495),  # Adjusting padx proportionally
    bg="white",
    insertbackground='white',
    fg="white",
    borderwidth=0,
    # Removing fixed width and height, so it expands with the frame
    height=proportion_width(0.000001),
      # Set a fixed height if needed
    spacing1=proportion_height(0.02),  # Adjust spacing1 proportionally
    spacing3=proportion_height(0.02),  # Adjust spacing3 proportionally
    font=('Helvetica', 14)
)

# Pack message_entry into frame2
message_entry.pack(
    side=tk.LEFT,
    padx=(proportion_width(0.208),0),
    #fill=tk.X,  # Fill horizontally
    pady=(0, proportion_height(0.02))
    #padx=(0),
      # Adjusting padx proportionally
      # Adjusting pady proportionally
)

message_entry.mark_set("insert", "%d.%d" % (0,0))

send_icon = Image.open("send_icon.png")
send_icon = send_icon.resize((55, 55))
send_icon = ImageTk.PhotoImage(send_icon)


# Send button
send_button = ttk.Button(frame_for_widgets, image=send_icon,  style="Send.TButton")
send_button.image = send_icon
send_button.pack(side=tk.LEFT, pady=(0, proportion_height(0.02)), padx=(1,0),)

message_entry.focus_set()
root.mainloop()

The problem is that these alignments look different for different screen sizes. It should be aligned for all screen sizes; regardless of the screen size of computer.

Share Improve this question edited 2 days ago user29255210 asked 2 days ago user29255210user29255210 12 bronze badges 4
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a minimal reproducible example. – siruku6 Commented 2 days ago
  • I've actually trimmed a lot of code and this is the code after trimming. – user29255210 Commented 2 days ago
  • You could improve thingsd as a starter by setting all the numeric scale values as constants at the beginning of the source code. You can then easily adjust them to see what effect it has on the display. And while doing this you need to check that the values are all correct in terms of their relation to each other. – OldBoy Commented 2 days ago
  • I’ve been trying to do that honestly. I’ve posted this on stackoverflow because I’m helpless. – user29255210 Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 0

Here's a very pared down example - most of the "functional" parts have been removed in order to focus on the layout.

You can achieve this result with grid, like you've tried, but I find pack to be more flexible in general so that's what I've used here.

The core idea is this: I've created container Frames for each effective "row" of widgets (i.e., any widgets that need to appear next to each other), then I've packed those widgets to the 'left' or 'right' accordingly.

The bulk of the layout code is just focused on how widgets fill their respective Frames and how they're padded.

import tkinter as tk
from tkinter import ttk


class ChatApp(tk.Tk):
    def __init__(self) -> None:
        super().__init__()
        self.geometry('800x600')
        self.title('Chat App')
        # create a frame for the main chat
        self.chat_frame = ttk.Frame(self)
        self.chat_frame.pack(expand=True, fill='both', padx=10, pady=10)
        self.chat_log = tk.Text(self.chat_frame)
        self.chat_log.pack(expand=True, fill='both', pady=4, side='left')
        self.scrollbar = ttk.Scrollbar(
            self.chat_frame,
            command=self.chat_log.yview,
        )
        self.scrollbar.pack(fill='y', pady=4, side='right')
        self.chat_log.config(yscrollcommand=self.scrollbar.set)
        # create a Frame to contain each row of widgets
        self.btns_row1 = ttk.Frame(self)
        self.btns_row1.pack(fill='x', padx=8, side='bottom')
        self.btns_row2 = ttk.Frame(self)
        self.btns_row2.pack(
            before=self.btns_row1,
            fill='x',
            padx=8,
            side='bottom',
        )
        self.entry_row = ttk.Frame(self)
        self.entry_row.pack(
            before=self.btns_row2,
            fill='x',
            padx=8,
            side='bottom',
        )
        # create the buttons
        kwargs = {  # common packing arguments for all widgets below
            'expand': True,
            'fill': 'x',
            'padx': 2,
            'pady': (0, 4),
        }
        self.btn_chat_pdf = ttk.Button(
            self.btns_row1,
            text='Chat with PDF',
            width=50,
        )
        self.btn_chat_pdf.pack(side='left', **kwargs)

        self.btn_chat_yt = ttk.Button(
            self.btns_row1,
            text='Chat with a YouTube Video',
            width=50,
        )
        self.btn_chat_yt.pack(side='right', **kwargs)

        self.btn_chat_letter = ttk.Button(
            self.btns_row2,
            text='Write a letter',
            width=50,
        )
        self.btn_chat_letter.pack(side='left', **kwargs)

        self.btn_chat_blog = ttk.Button(
            self.btns_row2,
            text='Chat with a Blog Post',
            width=50,
        )
        self.btn_chat_blog.pack(side='right', **kwargs)
        # create the entry and the send button
        self.chat_entry = ttk.Entry(self.entry_row)
        self.chat_entry.pack(side='left', **kwargs)

        self.btn_send = ttk.Button(self.entry_row, text='>')
        self.btn_send.pack(side='right', **kwargs)
        self.btn_send.pack_configure(expand=False)


if __name__ == '__main__':
    app = ChatApp()
    app.mainloop()
发布评论

评论列表(0)

  1. 暂无评论