python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python计算器

Python结合Tkinter手搓一个寄存器计算器

作者:xingzhemengyou1

寄存器计算器是一款专业的32位寄存器计算工具,专为程序员和硬件工程师设计,提供直观的位操作和进制转换功能,下面我们就来看看如何使用Python和Tkinter手搓一个寄存器计算器吧

专业的32位寄存器计算工具,为程序员和硬件工程师设计

软件概述

寄存器计算器(Register Calculator)是一款专业的32位寄存器计算工具,专为程序员和硬件工程师设计, 提供直观的位操作和进制转换功能,帮助用户快速进行寄存器配置和位级操作。

核心功能

1.32位寄存器位操作

通过点击按钮直接切换寄存器各位的值(0/1),按每4位一组进行分组显示,符合16进制显示习惯,位值变化时实时更新所有显示。

2.多进制转换

支持16进制、10进制、2进制三种进制,修改任一进制值时,其他进制值自动更新,可直接复制不同进制的结果到剪贴板。

3.窗口控制

可将窗口固定在屏幕最上层,方便在其他应用程序上操作,窗口大小可调整,适应不同屏幕分辨率。

界面设计

现代专业风格

采用专业的深蓝色系作为主色调,搭配柔和的背景色,通过分组显示、分隔符和适当的间距创建清晰的视觉层次, 默认窗口大小(900x500)确保所有内容完全显示,无需调整。

功能区域划分

寄存器位显示区:32位寄存器的可视化操作界面,按每4位一组分组显示

进制转换显示区:显示和编辑不同进制的值,支持实时转换

交互体验

通过点击按钮切换位值,操作简单直观,位值变化时立即更新所有显示,提供即时视觉反馈, 符合程序员的审美习惯,界面整洁有序。

技术实现

开发语言与库

核心技术特点

代码结构

效果图

源代码

import tkinter as tk
from tkinter import ttk

# 定义颜色主题 - 优化配色方案
class Colors:
    # 主色调 - 专业深蓝色系
    PRIMARY = "#2c3e50"        # 主深蓝色
    PRIMARY_DARK = "#1a252f"    # 深蓝色
    PRIMARY_LIGHT = "#34495e"   # 浅蓝色
    
    # 功能色
    SUCCESS = "#27ae60"        # 绿色
    WARNING = "#f39c12"        # 橙色
    ERROR = "#e74c3c"          # 红色
    INFO = "#3498db"           # 信息蓝
    
    # 背景色
    BACKGROUND = "#f5f7fa"      # 柔和浅灰背景
    CARD_BG = "#ffffff"        # 卡片背景
    FRAME_BG = "#ffffff"        # 框架背景
    
    # 文本色
    TEXT_PRIMARY = "#2c3e50"    # 主文本色
    TEXT_SECONDARY = "#6c757d"  # 次要文本色
    TEXT_LIGHT = "#ffffff"      # 亮色文本
    
    # 寄存器位颜色
    BIT_ACTIVE = "#4361ee"      # 激活位 - 专业蓝紫色
    BIT_INACTIVE = "#e9ecef"    # 未激活位 - 柔和浅灰色
    BIT_HOVER = "#dee2e6"       # 悬停位 - 浅灰色
    
    # 边框色
    BORDER = "#dee2e6"          # 边框
    BORDER_LIGHT = "#f8f9fa"    # 浅色边框
    
    # 按钮色
    BUTTON_BG = "#4361ee"       # 按钮背景
    BUTTON_HOVER = "#3a0ca3"    # 按钮悬停
    BUTTON_TEXT = "#ffffff"     # 按钮文本

class RegisterCalculator:
    def __init__(self, root):
        self.root = root
        self.root.title("寄存器计算器")
        self.root.geometry("800x400")
        self.root.resizable(True, True)
        
        # 设置背景颜色
        self.root.configure(bg=Colors.BACKGROUND)
        
        # 初始化寄存器值
        self.register_value = 0
        
        # 创建主框架
        self.main_frame = ttk.Frame(root, padding="20")
        self.main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建寄存器位显示区域
        self.create_register_display()
        
        # 创建进制显示区域
        self.create_conversion_display()
        
        # 控制区域已移除
        
        # 初始化显示
        self.update_display()
    
    def create_register_display(self):
        """创建寄存器位显示区域"""
        register_frame = ttk.LabelFrame(self.main_frame, text="32位寄存器", padding="15")
        register_frame.pack(fill=tk.X, pady=10)
        
        # 创建位标题行和值行的容器
        bits_frame = ttk.Frame(register_frame)
        bits_frame.pack(fill=tk.X, pady=5)
        
        # 第一组 (31-16)
        group1_frame = ttk.Frame(bits_frame)
        group1_frame.pack(fill=tk.X, pady=2)
        
        self.bit_buttons1 = []
        col = 0
        for i, bit_idx in enumerate(range(31, 15, -1)):
            # 每4位添加一个分隔符
            if i > 0 and i % 4 == 0:
                # 添加空白列作为分隔符
                spacer = ttk.Label(group1_frame, text="", width=2)
                spacer.grid(row=0, column=col, rowspan=2, padx=2)
                col += 1
            
            # 位标题
            bit_label = ttk.Label(group1_frame, text=str(bit_idx), width=4, anchor="center", 
                                background=Colors.CARD_BG, foreground=Colors.TEXT_SECONDARY,
                                font=('Consolas', 9, 'bold'))
            bit_label.grid(row=0, column=col, padx=1, pady=1, sticky=tk.NSEW)
            
            # 位值按钮
            bit_var = tk.StringVar(value="0")
            bit_button = ttk.Button(
                group1_frame, 
                width=4, 
                textvariable=bit_var,
                command=lambda idx=bit_idx, var=bit_var: self.update_bit(idx, var),
                style="BitButton.TButton"
            )
            bit_button.grid(row=1, column=col, padx=1, pady=1, sticky=tk.NSEW)
            self.bit_buttons1.append((bit_idx, bit_var, bit_button))
            col += 1
        
        # 第二组 (15-0)
        group2_frame = ttk.Frame(bits_frame)
        group2_frame.pack(fill=tk.X, pady=2)
        
        self.bit_buttons2 = []
        col = 0
        for i, bit_idx in enumerate(range(15, -1, -1)):
            # 每4位添加一个分隔符
            if i > 0 and i % 4 == 0:
                # 添加空白列作为分隔符
                spacer = ttk.Label(group2_frame, text="", width=2)
                spacer.grid(row=0, column=col, rowspan=2, padx=2)
                col += 1
            
            # 位标题
            bit_label = ttk.Label(group2_frame, text=str(bit_idx), width=4, anchor="center", 
                                background=Colors.CARD_BG, foreground=Colors.TEXT_SECONDARY,
                                font=('Consolas', 9, 'bold'))
            bit_label.grid(row=0, column=col, padx=1, pady=1, sticky=tk.NSEW)
            
            # 位值按钮
            bit_var = tk.StringVar(value="0")
            bit_button = ttk.Button(
                group2_frame, 
                width=4, 
                textvariable=bit_var,
                command=lambda idx=bit_idx, var=bit_var: self.update_bit(idx, var),
                style="BitButton.TButton"
            )
            bit_button.grid(row=1, column=col, padx=1, pady=1, sticky=tk.NSEW)
            self.bit_buttons2.append((bit_idx, bit_var, bit_button))
            col += 1
    
    def create_conversion_display(self):
        """创建进制转换显示区域"""
        conversion_frame = ttk.LabelFrame(self.main_frame, text="进制转换", padding="15")
        conversion_frame.pack(fill=tk.X, pady=10)
        
        # 16进制输入
        ttk.Label(conversion_frame, text="16进制:", width=10, foreground=Colors.TEXT_PRIMARY,
                 font=('Arial', 10, 'bold')).grid(row=0, column=0, padx=10, pady=8, sticky=tk.W)
        self.hex_var = tk.StringVar(value="0x00000000")
        hex_entry = ttk.Entry(conversion_frame, textvariable=self.hex_var, width=30,
                            font=('Consolas', 10))
        hex_entry.grid(row=0, column=1, padx=10, pady=8, sticky=tk.EW)
        hex_entry.bind("<Return>", lambda e: self.update_from_hex())
        
        # 10进制显示
        ttk.Label(conversion_frame, text="10进制:", width=10, foreground=Colors.TEXT_PRIMARY,
                 font=('Arial', 10, 'bold')).grid(row=0, column=2, padx=10, pady=8, sticky=tk.W)
        self.dec_var = tk.StringVar(value="0")
        dec_entry = ttk.Entry(conversion_frame, textvariable=self.dec_var, width=30,
                            font=('Consolas', 10))
        dec_entry.grid(row=0, column=3, padx=10, pady=8, sticky=tk.EW)
        dec_entry.bind("<Return>", lambda e: self.update_from_dec())
        
        # 2进制显示
        ttk.Label(conversion_frame, text="2进制:", width=10, foreground=Colors.TEXT_PRIMARY,
                 font=('Arial', 10, 'bold')).grid(row=1, column=0, padx=10, pady=8, sticky=tk.W)
        self.bin_var = tk.StringVar(value="0000 0000 0000 0000 0000 0000 0000 0000")
        bin_entry = ttk.Entry(conversion_frame, textvariable=self.bin_var, width=50,
                            font=('Consolas', 10))
        bin_entry.grid(row=1, column=1, columnspan=2, padx=10, pady=8, sticky=tk.EW)
        
        # 最上端显示复选框 - 与2进制在同一行
        self.topmost_var = tk.BooleanVar(value=False)
        ttk.Checkbutton(conversion_frame, text="最上端显示", variable=self.topmost_var, 
                       command=self.toggle_topmost, style="Modern.TCheckbutton").grid(
                           row=1, column=3, padx=10, pady=8, sticky=tk.E)
        
        # 设置列权重,使输入框能够扩展
        conversion_frame.columnconfigure(1, weight=1)
        conversion_frame.columnconfigure(3, weight=1)
    

    
    def update_bit(self, bit_index, bit_var):
        """更新指定位的值"""
        # 切换位值
        current_value = bit_var.get()
        new_value = "1" if current_value == "0" else "0"
        bit_var.set(new_value)
        
        # 更新寄存器值
        if new_value == "1":
            self.register_value |= (1 << bit_index)
        else:
            self.register_value &= ~(1 << bit_index)
        
        # 更新显示
        self.update_display()
    
    def update_from_hex(self):
        """从16进制输入更新寄存器值"""
        try:
            hex_str = self.hex_var.get().strip()
            # 处理前缀
            if hex_str.startswith("0x"):
                hex_str = hex_str[2:]
            # 转换为整数
            self.register_value = int(hex_str, 16)
            # 确保值在32位范围内
            self.register_value &= 0xFFFFFFFF
            # 更新显示
            self.update_display()
        except ValueError:
            # 输入无效,恢复之前的值
            self.hex_var.set(f"0x{self.register_value:08X}")
    
    def update_from_dec(self):
        """从10进制输入更新寄存器值"""
        try:
            dec_str = self.dec_var.get().strip()
            # 转换为整数
            self.register_value = int(dec_str)
            # 确保值在32位范围内
            self.register_value &= 0xFFFFFFFF
            # 更新显示
            self.update_display()
        except ValueError:
            # 输入无效,恢复之前的值
            self.dec_var.set(str(self.register_value))
    
    def toggle_topmost(self):
        """切换窗口是否显示在最上端"""
        self.root.attributes("-topmost", self.topmost_var.get())
    
    def update_display(self):
        """更新所有显示"""
        # 更新位按钮状态
        for bit_info in self.bit_buttons1 + self.bit_buttons2:
            bit_index, bit_var, bit_button = bit_info
            bit_value = (self.register_value >> bit_index) & 1
            bit_var.set(str(bit_value))
            # 更新按钮样式
            if bit_value:
                # 为1的位使用不同的颜色
                bit_button.configure(style="ActiveBit.TButton")
            else:
                # 为0的位使用默认颜色
                bit_button.configure(style="InactiveBit.TButton")
        
        # 更新16进制显示
        self.hex_var.set(f"0x{self.register_value:08X}")
        
        # 更新10进制显示
        self.dec_var.set(str(self.register_value))
        
        # 更新2进制显示
        bin_str = f"{self.register_value:032b}"
        # 添加空格分隔
        formatted_bin = " ".join([bin_str[i:i+4] for i in range(0, 32, 4)])
        self.bin_var.set(formatted_bin)

if __name__ == "__main__":
    root = tk.Tk()
    
    # 创建自定义样式
    style = ttk.Style()
    
    # 基础位按钮样式
    style.configure("BitButton.TButton",
                   width=5,
                   padding=4,
                   font=('Consolas', 10, 'bold'))
    
    # 活动状态的位按钮样式(值为1)
    style.configure("ActiveBit.TButton",
                   background=Colors.BIT_ACTIVE,
                   foreground=Colors.TEXT_PRIMARY,
                   relief="raised")
    
    # 非活动状态的位按钮样式(值为0)
    style.configure("InactiveBit.TButton",
                   background=Colors.BIT_INACTIVE,
                   foreground=Colors.TEXT_PRIMARY,
                   relief="sunken")
    

    
    # 现代复选框样式
    style.configure("Modern.TCheckbutton",
                   padding=5,
                   font=('Arial', 10))
    
    # 标签样式
    style.configure("TLabel",
                   background=Colors.FRAME_BG,
                   foreground=Colors.TEXT_PRIMARY)
    
    # 输入框样式
    style.configure("TEntry",
                   fieldbackground=Colors.CARD_BG,
                   foreground=Colors.TEXT_PRIMARY,
                   padding=4,
                   borderwidth=1,
                   relief="solid")
    
    # 框架样式
    style.configure("TLabelframe",
                   background=Colors.FRAME_BG,
                   foreground=Colors.PRIMARY,
                   borderwidth=1,
                   relief="solid")
    
    style.configure("TLabelframe.Label",
                   background=Colors.FRAME_BG,
                   foreground=Colors.PRIMARY,
                   font=("Arial", 11, "bold"),
                   padding=(5, 0, 5, 10))
    
    # 主窗口样式
    root.configure(bg=Colors.BACKGROUND)
    
    app = RegisterCalculator(root)
    root.mainloop()

到此这篇关于Python结合Tkinter手搓一个寄存器计算器的文章就介绍到这了,更多相关Python计算器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文