сделай мне xml ui файл для переделки этого кода из tkinter в qt designer

import numpy as np
import pandas as pd
import pygimli as pg
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import pygimli.meshtools as mt
from pygimli.physics import ert
from pygimli.physics.ves import VESModelling
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class PolygonTab:
    def __init__(self, parent, polygon_data, on_save):
        self.polygon_data = polygon_data
        self.on_save = on_save
        
        # Создание вкладки
        self.frame = tk.Frame(parent)
        
        # Поле ввода сопротивления
        self.resistivity_label = tk.Label(self.frame, text="Resistivity:")
        self.resistivity_label.pack(anchor=tk.W)
        
        self.resistivity_entry = tk.Entry(self.frame)
        self.resistivity_entry.insert(0, str(polygon_data['resistivity']))
        self.resistivity_entry.pack(anchor=tk.W, fill=tk.X)
        
        # Таблица точек (X, Y)
        self.points_label = tk.Label(self.frame, text="Points (X, Y):")
        self.points_label.pack(anchor=tk.W)
        
        self.points_table = ttk.Treeview(self.frame, columns=("X", "Y"), show="headings")
        self.points_table.heading("X", text="X")
        self.points_table.heading("Y", text="Y")
        self.points_table.pack(fill=tk.BOTH, expand=True)

        self.points_table.bind("<Double-1>", self.on_point_double_click)

        # Заполнение таблицы точек
        self.update_points_table()

        # Кнопки
        self.add_point_button = tk.Button(self.frame, text="Add Point", command=self.add_point)
        self.add_point_button.pack(side=tk.LEFT, pady=5)

        self.delete_point_button = tk.Button(self.frame, text="Delete Point", command=self.delete_point)
        self.delete_point_button.pack(side=tk.LEFT, pady=5)
        
        self.save_button = tk.Button(self.frame, text="Save Changes", command=self.save_changes)
        self.save_button.pack(side=tk.LEFT, pady=5)

    def update_points_table(self):
        self.points_table.delete(*self.points_table.get_children())
        for i, point in enumerate(self.polygon_data['points']):
            self.points_table.insert("", "end", iid=i, values=(point[0], point[1]))

    def add_point(self):
        # Добавляем новую точку, если в полигоне уже 3 или более точек
        self.polygon_data['points'].append([0, 0])  # Новая точка с дефолтными координатами
        self.update_points_table()

    def delete_point(self):
        if len(self.polygon_data['points']) > 3:
            selected_item = self.points_table.selection()
            if selected_item:
                self.points_table.delete(selected_item[0])
                self.polygon_data['points'].pop(int(selected_item[0]))
                self.update_points_table()

    def on_point_double_click(self, event):
        item = self.points_table.selection()
        if item:
            x, y = self.points_table.item(item[0], 'values')
            x = simpledialog.askfloat("Edit Point", "Enter new X value:", initialvalue=x)
            y = simpledialog.askfloat("Edit Point", "Enter new Y value:", initialvalue=y)
            if x is not None and y is not None:
                self.points_table.item(item[0], values=(x, y))
                self.polygon_data['points'][int(item[0])] = [x, y]

    def save_changes(self):
        # Обновление сопротивления
        resistivity = self.resistivity_entry.get()
        try:
            self.polygon_data['resistivity'] = float(resistivity)
        except ValueError:
            messagebox.showerror("Error", "Invalid resistivity value.")
            return

        # Обновление координат точек
        points = []
        for child in self.points_table.get_children():
            x, y = self.points_table.item(child, 'values')
            try:
                points.append([float(x), float(y)])
            except ValueError:
                messagebox.showerror("Error", "Invalid point coordinates.")
                return

        if len(points) >= 3:
            self.polygon_data['points'] = points
        else:
            messagebox.showerror("Error", "A polygon must have at least 3 points.")
            return
        
        self.on_save()  # Уведомляем родителя об обновлении данных# Assuming PolygonTab and other classes remain unchanged

class GeoApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Geophysical Modelling GUI")
        self.geometry("1200x1200")

        # Основной макет
        self.main_frame = tk.PanedWindow(self, orient=tk.HORIZONTAL)
        self.main_frame.pack(fill=tk.BOTH, expand=True)

        # Разделение окна на две части
        self.left_frame = tk.Frame(self.main_frame, width=400)
        self.main_frame.add(self.left_frame)
        self.right_frame = tk.PanedWindow(self.main_frame, orient=tk.VERTICAL)
        self.main_frame.add(self.right_frame)

        # Create two subframes for model plotting and VES plotting
        self.model_plot_frame = tk.Frame(self.right_frame)
        self.curve_plot_frame = tk.Frame(self.right_frame)
        self.right_frame.add(self.model_plot_frame)
        self.right_frame.add(self.curve_plot_frame)

        self.polygons = []  # Начальная модель пустая
        self.datapole = None
        self.surrounding_resistivity = 100  # Значение сопротивления окружающей среды по умолчанию

        self.create_widgets()

    def create_widgets(self):
        # Левая панель
        self.polygon_frame = tk.LabelFrame(self.left_frame, text="Polygon Editor", padx=10, pady=10)
        self.polygon_frame.pack(fill=tk.BOTH, expand=True)

        self.polygon_tabs = ttk.Notebook(self.polygon_frame)
        self.polygon_tabs.pack(fill=tk.BOTH, expand=True)

        self.add_polygon_button = tk.Button(self.left_frame, text="Add Polygon", command=self.add_polygon)
        self.add_polygon_button.pack(pady=5)

        self.delete_polygon_button = tk.Button(self.left_frame, text="Delete Polygon", command=self.delete_polygon)
        self.delete_polygon_button.pack(pady=5)

        # Поле ввода сопротивления окружающей среды
        self.surrounding_resistivity_label = tk.Label(self.left_frame, text="Surrounding Resistivity:")
        self.surrounding_resistivity_label.pack(anchor=tk.W)

        self.surrounding_resistivity_entry = tk.Entry(self.left_frame)
        self.surrounding_resistivity_entry.insert(0, str(self.surrounding_resistivity))
        self.surrounding_resistivity_entry.pack(anchor=tk.W, fill=tk.X)

        # Create the Update button for surrounding resistivity
        self.update_button = tk.Button(self.left_frame, text="Update Resistivity", command=self.update_surrounding_resistivity)
        self.update_button.pack(pady=5)

        # Модельный график
        self.figure_model = plt.Figure(figsize=(6, 3), dpi=100)
        self.ax_model = self.figure_model.add_subplot(111)
        self.canvas_model = FigureCanvasTkAgg(self.figure_model, master=self.model_plot_frame)
        self.canvas_model.get_tk_widget().pack(fill=tk.BOTH, expand=True)

        # VES график
        self.figure_ves = plt.Figure(figsize=(6, 3), dpi=100)
        self.ax_ves = self.figure_ves.add_subplot(111)
        self.canvas_ves = FigureCanvasTkAgg(self.figure_ves, master=self.curve_plot_frame)
        self.canvas_ves.get_tk_widget().pack(fill=tk.BOTH, expand=True)

        self.load_button = tk.Button(self.right_frame, text="Load Data", command=self.load_data)
        self.load_button.pack(pady=10)

        self.plot_model_button = tk.Button(self.right_frame, text="Plot 2D Model", command=self.plot_model)
        self.plot_model_button.pack(pady=10)

        self.plot_curve_button = tk.Button(self.right_frame, text="Plot VES Curves", command=self.plot_curve)
        self.plot_curve_button.pack(pady=10)

    def add_polygon(self):
        # Создаем новый полигон с 3 точками по умолчанию
        points = [[0, 0], [100, 0], [50, -20]]  # Минимум 3 точки
        resistivity = 500  # Сопротивление по умолчанию

        polygon_data = {'points': points, 'resistivity': resistivity}
        self.polygons.append(polygon_data)
        self.update_polygon_tabs()

    def delete_polygon(self):
        selected_tab = self.polygon_tabs.select()
        if selected_tab:
            tab_index = self.polygon_tabs.index(selected_tab)
            del self.polygons[tab_index]
            self.update_polygon_tabs()

    def update_polygon_tabs(self):
        # Очистка текущих вкладок
        for tab in self.polygon_tabs.tabs():
            self.polygon_tabs.forget(tab)

        for idx, polygon in enumerate(self.polygons):
            tab = PolygonTab(self.polygon_tabs, polygon, self.update_polygon_tabs)
            self.polygon_tabs.add(tab.frame, text=f"Polygon {idx + 1}")
            
    def load_data(self):
        filepath = "ves47.xlsx"
        df = pd.read_excel(filepath)
        self.datapole = df.values
        messagebox.showinfo("Data Loaded", "Data has been loaded successfully.")

    def update_surrounding_resistivity(self):
        try:
            self.surrounding_resistivity = float(self.surrounding_resistivity_entry.get())
            messagebox.showinfo("Success", f"Surrounding resistivity updated to: {self.surrounding_resistivity} Ωm")
        except ValueError:
            messagebox.showerror("Error", "Invalid surrounding resistivity value.")

    def plot_model(self):
        print(f"Current surrounding resistivity: {self.surrounding_resistivity}")

        # Similar polygon and mesh generation code
        plc = mt.createWorld(start=[-800, -600], end=[800, 0], layers=[], marker=0)
        for idx, polygon in enumerate(self.polygons):
            poly = mt.createPolygon(polygon['points'], isClosed=True, marker=idx + 1)
            plc += poly

        mesh = pg.meshtools.createMesh(plc, quality=33, area=1000)

        resistivity_data = np.full(mesh.cellCount(), self.surrounding_resistivity)
        for cell in mesh.cells():
            marker = cell.marker()
            if 1 <= marker <= len(self.polygons):
                resistivity_data[cell.id()] = self.polygons[marker - 1]['resistivity']
            elif marker == 0:
                resistivity_data[cell.id()] = self.surrounding_resistivity

        self.ax_model.clear()
        pg.show(mesh, data=resistivity_data, ax=self.ax_model, cMap='viridis', logScale=True, label=pg.unit('res'))
        self.canvas_model.draw()

    def plot_curve(self):
        if self.datapole is None or len(self.datapole) == 0:
            messagebox.showwarning("Warning", "Load data first!")
            return

        self.scheme = ert.createData(pg.utils.grange(start=0.05, end=480, dx=1, n=35, log=True), sounding=True)

        plc = mt.createWorld(start=[-800, -600], end=[800, 0], layers=[], isSubSurface=True, marker=0)
        for idx, polygon in enumerate(self.polygons):
            poly = mt.createPolygon(polygon['points'], isClosed=True, marker=idx + 1)
            plc += poly

        mesh = pg.meshtools.createMesh(plc, quality=33, area=200)

        resistivity_data = np.full(mesh.cellCount(), self.surrounding_resistivity)
        for cell in mesh.cells():
            marker = cell.marker()
            if marker > 0 and marker <= len(self.polygons):
                resistivity_data[cell.id()] = self.polygons[marker - 1]['resistivity']
            else:
                resistivity_data[cell.id()] = self.surrounding_resistivity

        try:
             # Assuming self.datapole is a 2D numpy array and columns are indexed
            # For example, let's assume columns are: [a, b, n, m, rhoa]
            a = self.datapole[:, 0]
            b = self.datapole[:, 1]
            n = self.datapole[:, 2]
            m = self.datapole[:, 3]
            rhoa = self.datapole[:, 4]
            
            ab2p = (b - a) / 2
            mn2p = (n - m) / 2
            x = pg.x(self.scheme)
            ab2 = (x[self.scheme('b')] - x[self.scheme('a')]) / 2
            mn2 = (x[self.scheme('n')] - x[self.scheme('m')]) / 2# Simulate ERT data           
            data = ert.simulate(mesh, res=resistivity_data, scheme=self.scheme, verbose=False)
            ves = VESModelling(ab2=ab2, mn2=mn2)

            # Extract resistivity values for plotting
            resistivity_values = data.get('rhoa')  # Replace 'rhoa' with the correct field name if needed

            # Ensure valid data for log-scale plotting
            valid_indices = resistivity_values > 0
            if not np.any(valid_indices):
                messagebox.showerror("Error", "No valid data points for log-scale plotting.")
                return

            ab2_valid = ab2[valid_indices]
            data_valid = resistivity_values[valid_indices]
            
            self.ax_ves.clear()
            self.ax_ves.loglog(ab2_valid, data_valid, '-o', label='2D model')
            self.ax_ves.loglog(ab2p, rhoa, '-x', label='Field VES curve')
            self.ax_ves.plot(ab2, ves.response([0.2, 1.5, 9, 60, 75, 300, 70, 30, 240, 115, 2000]), '-x', label='1D inversion')
            self.ax_ves.set_xlabel('AB/2 (m)')
            self.ax_ves.set_ylabel('Apparent resistivity (Ωm)')
            self.ax_ves.grid(True)
            self.ax_ves.legend()
            self.canvas_ves.draw()


        except Exception as e:
            messagebox.showerror("Error", f"An unexpected error occurred: {str(e)}")

if __name__ == "__main__":
    app = GeoApp()
    app.mainloop()