|
1 | 1 | # ------------------------------------------------------------------------------- |
2 | 2 | # Name: IV Sweep GUI for Keithley 2400/2182 |
3 | | -# Purpose: Provide a professional GUI for performing IV sweeps using a |
| 3 | +# Purpose: Provide a professional GUI for performing I-V sweeps using a |
4 | 4 | # Keithley 2400 as a current source and a Keithley 2182 |
5 | 5 | # as a nanovoltmeter. |
6 | 6 | # Author: Prathamesh Deshmukh |
|
9 | 9 | # ------------------------------------------------------------------------------- |
10 | 10 |
|
11 | 11 | # --- GUI and Plotting Packages --- |
12 | | -import tkinter as tk |
| 12 | +import tkinter as tk; from tkinter import Canvas |
13 | 13 | from tkinter import ttk, filedialog, messagebox, scrolledtext |
14 | 14 | import numpy as np |
15 | 15 | import os |
|
21 | 21 | from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg |
22 | 22 | import matplotlib as mpl |
23 | 23 |
|
| 24 | +# --- Pillow for Logo Image --- |
| 25 | +try: |
| 26 | + from PIL import Image, ImageTk |
| 27 | + PIL_AVAILABLE = True |
| 28 | +except ImportError: |
| 29 | + PIL_AVAILABLE = False |
| 30 | + |
24 | 31 | # --- Instrument Control Packages --- |
25 | 32 | try: |
26 | 33 | import pyvisa |
@@ -95,20 +102,21 @@ def shutdown(self): |
95 | 102 | # --- FRONT END (GUI) --- |
96 | 103 | # ------------------------------------------------------------------------------- |
97 | 104 | class IV_GUI: |
98 | | - PROGRAM_VERSION = "1.0" |
| 105 | + PROGRAM_VERSION = "1.1" |
99 | 106 | CLR_BG = '#2B3D4F'; CLR_HEADER = '#3A506B'; CLR_FG = '#EDF2F4' |
100 | 107 | CLR_FRAME_BG = '#3A506B'; CLR_INPUT_BG = '#4C566A' |
101 | 108 | CLR_ACCENT_GREEN, CLR_ACCENT_RED, CLR_ACCENT_BLUE = '#A7C957', '#E74C3C', '#8D99AE' |
102 | 109 | CLR_ACCENT_GOLD = '#FFC107'; CLR_CONSOLE_BG = '#1E2B38' |
103 | 110 | FONT_BASE = ('Segoe UI', 11); FONT_TITLE = ('Segoe UI', 13, 'bold') |
104 | | - |
| 111 | + |
105 | 112 | def __init__(self, root): |
106 | 113 | self.root = root |
107 | 114 | self.root.title("I-V Sweep (K2400 + K2182)") |
108 | 115 | self.root.geometry("1600x950") |
109 | 116 | self.root.minsize(1400, 800) |
110 | 117 | self.root.configure(bg=self.CLR_BG) |
111 | 118 | self.is_running = False |
| 119 | + self.logo_image = None |
112 | 120 | self.backend = IV_Backend() |
113 | 121 | self.data_storage = {'current': [], 'voltage': []} |
114 | 122 | self.setup_styles() |
@@ -140,10 +148,31 @@ def create_widgets(self): |
140 | 148 | right_panel = self._create_right_panel(main_pane); main_pane.add(right_panel, weight=3) |
141 | 149 |
|
142 | 150 | def _create_left_panel(self, parent): |
143 | | - panel = ttk.Frame(parent, padding=5); panel.grid_columnconfigure(0, weight=1); panel.grid_rowconfigure(2, weight=1) |
144 | | - self._create_params_panel(panel, 0); self._create_control_panel(panel, 1); self._create_console_panel(panel, 2) |
| 151 | + panel = ttk.Frame(parent, padding=5); panel.grid_columnconfigure(0, weight=1); panel.grid_rowconfigure(3, weight=1) |
| 152 | + self._create_info_panel(panel, 0) |
| 153 | + self._create_params_panel(panel, 1); self._create_control_panel(panel, 2); self._create_console_panel(panel, 3) |
145 | 154 | return panel |
146 | 155 |
|
| 156 | + def _create_info_panel(self, parent, grid_row): |
| 157 | + frame = ttk.LabelFrame(parent, text='Information'); frame.grid(row=grid_row, column=0, sticky='new', pady=5) |
| 158 | + frame.grid_columnconfigure(1, weight=1) |
| 159 | + logo_canvas = Canvas(frame, width=80, height=80, bg=self.CLR_FRAME_BG, highlightthickness=0) |
| 160 | + logo_canvas.grid(row=0, column=0, rowspan=2, padx=10, pady=10) |
| 161 | + try: |
| 162 | + script_dir = os.path.dirname(os.path.abspath(__file__)) |
| 163 | + logo_path = os.path.join(script_dir, "..", "_assets", "LOGO", "UGC_DAE_CSR.jpeg") |
| 164 | + if PIL_AVAILABLE and os.path.exists(logo_path): |
| 165 | + img = Image.open(logo_path).resize((80, 80), Image.Resampling.LANCZOS) |
| 166 | + self.logo_image = ImageTk.PhotoImage(img) |
| 167 | + logo_canvas.create_image(40, 40, image=self.logo_image) |
| 168 | + except Exception as e: |
| 169 | + self.log(f"Warning: Could not load logo. {e}") |
| 170 | + |
| 171 | + info_text = ("Institute: UGC DAE CSR, Mumbai\n" |
| 172 | + "Measurement: I-V Sweep (4-Probe)\n" |
| 173 | + "Instruments: K2400 & K2182") |
| 174 | + ttk.Label(frame, text=info_text, justify='left').grid(row=0, column=1, rowspan=2, sticky='w', padx=5) |
| 175 | + |
147 | 176 | def _create_right_panel(self, parent): |
148 | 177 | panel = ttk.Frame(parent, padding=5) |
149 | 178 | container = ttk.LabelFrame(panel, text='Live I-V Curve'); container.pack(fill='both', expand=True) |
|
0 commit comments