如何自定义Telegram Bot按钮?动态排版与分页需求
实现动态按钮排版与分页逻辑
根据列表长度,按钮的每行数量遵循以下规则:
- 列表长度为3:第一行2个,第二行1个
- 列表长度为4:两行各2个
- 列表长度5-6:每行最多3个
- 列表长度7-8:前两行各3个,最后一行2个
- 列表长度9-12:每行3个,排满所有行
- 列表长度>12:分页显示,每页最多展示12个按钮,每页内部按上述规则排版
完整实现代码
from typing import List, Tuple # 模拟Button.inline方法,实际项目中替换为对应库的实现 class Button: @staticmethod def inline(text: str): return f"Button({text})" def generate_single_page_layout(names: List[str]) -> List[List[object]]: layout = [] total = len(names) if total == 0: return layout # 确定每行的按钮数量分布 if total == 3: row_sizes = [2, 1] elif total == 4: row_sizes = [2, 2] elif 5 <= total <= 6: row_sizes = [3] * (total // 3) if total % 3 != 0: row_sizes.append(total % 3) elif 7 <= total <= 8: row_sizes = [3, 3, total - 6] elif 9 <= total <= 12: row_sizes = [3] * (total // 3) if total % 3 != 0: row_sizes.append(total % 3) else: # 长度为1或2的情况 row_sizes = [total] if total == 1 else [2] # 生成按钮行 index = 0 for size in row_sizes: row = [Button.inline(names[index + i]) for i in range(size)] layout.append(row) index += size return layout def generate_paginated_keyboards(names: List[str], page_size: int = 12) -> List[List[List[object]]]: paginated_keyboards = [] total_names = len(names) if total_names == 0: return paginated_keyboards # 拆分列表为分页数据 for i in range(0, total_names, page_size): page_names = names[i:i+page_size] page_layout = generate_single_page_layout(page_names) # 可选:添加分页导航按钮,比如上一页/下一页 # page_layout.append([Button.inline("上一页"), Button.inline("下一页")]) paginated_keyboards.append(page_layout) return paginated_keyboards # 测试不同场景 if __name__ == "__main__": test_cases = [ ["a", "b", "c"], # 长度3 ["a", "b", "c", "d"], # 长度4 ["a", "b", "c", "d", "e", "f"], # 长度6 ["a", "b", "c", "d", "e", "f", "g", "h"], # 长度8 ["a"]*13 # 长度13,分页 ] for idx, case in enumerate(test_cases): print(f"测试用例 {idx+1}(长度{len(case)}):") keyboards = generate_paginated_keyboards(case) for page_idx, page in enumerate(keyboards): print(f" 第{page_idx+1}页:") for row in page: print(f" {' '.join(str(btn) for btn in row)}") print("---")
逻辑说明
- 单页排版:
先根据列表长度预设每行的按钮数量,比如长度3时分两行[2,1],长度7-8时分三行[3,3,2]。接着按这个行大小从名称列表中截取元素,生成对应的按钮行,组合成单页布局。 - 分页处理:
将原列表按每页12个元素拆分,每个子页单独生成排版。如果需要分页导航按钮(比如上一页、下一页),可以在每个页面的末尾添加,代码中已预留注释位置。 - 测试覆盖:
代码包含了题目中所有指定的排版场景,以及长度超过12的分页情况,运行后可直接查看各场景的排版效果。
内容的提问来源于stack exchange,提问作者KrisH Jodu
相关产品推荐
相关产品推荐

