杰瑞科技汇

Python DataGridView如何实现数据绑定与交互?

Of course! Using a DataGridView in Python is a common requirement for building desktop applications with a user interface. However, it's important to clarify something upfront:

Python DataGridView如何实现数据绑定与交互?-图1
(图片来源网络,侵删)

There is no native, built-in DataGridView control in Python's standard library.

The DataGridView is a specific control from the .NET Framework, primarily used with languages like C# or VB.NET in Windows Forms (WinForms) or WPF applications.

To get a DataGridView-like experience in Python, you need to use a GUI framework that can host a .NET control or provides its own powerful grid widget. The most popular and straightforward way to do this is with PyWin32.

Here’s a complete guide covering the best options, with a focus on the most direct approach.

Python DataGridView如何实现数据绑定与交互?-图2
(图片来源网络,侵删)

Option 1: The Direct Approach - PyWin32 (WinForms)

This is the most faithful way to get the actual .NET DataGridView control inside a Python application. You are essentially embedding a Windows Forms application within Python.

Why use this?

  • You get the exact same control as in C#.
  • All its features (sorting, filtering, editing, cell formatting) are available.
  • Ideal if you're migrating a .NET app to Python or need a specific feature only the .NET control has.

Installation: First, you need to install the PyWin32 library.

pip install pywin32

Example: Basic DataGridView with PyWin32

This example creates a window, adds a DataGridView, populates it with data, and enables basic features like adding rows.

Python DataGridView如何实现数据绑定与交互?-图3
(图片来源网络,侵删)
import win32gui
import win32con
import win32ui
from datetime import datetime
def create_datagridview():
    # 1. Create the main window
    wc = win32gui.WNDCLASS()
    wc.lpszClassName = "MyWindowClass"
    wc.lpfnWndProc = {win32con.WM_DESTROY: lambda hwnd, msg, wparam, lparam: win32gui.PostQuitMessage(0)}
    class_atom = win32gui.RegisterClass(wc)
    hwnd = win32gui.CreateWindow(
        class_atom, "Python DataGridView Demo",
        win32con.WS_OVERLAPPEDWINDOW | win32con.WS_VISIBLE,
        100, 100, 800, 600,
        None, None, None, None
    )
    # 2. Create the DataGridView control
    # The control's class name is "DataGridView"
    h_dgv = win32gui.CreateWindowEx(
        0, "DataGridView", "",
        win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_HSCROLL | win32con.WS_VSCROLL,
        10, 10, 760, 560,
        hwnd, None, None, None
    )
    # 3. Get the IWin32Window interface for the control
    # This is necessary for many .NET operations
    iwin32_window = win32gui.GetParent(h_dgv)
    # 4. Populate the DataGridView with data
    # We'll use a list of lists/tuples for simplicity
    data = [
        ("Alice", "Smith", 28, "New York", datetime(2025, 1, 15)),
        ("Bob", "Johnson", 45, "Los Angeles", datetime(2025, 5, 20)),
        ("Charlie", "Brown", 33, "Chicago", datetime(2025, 3, 10)),
        ("Diana", "Prince", 30, "London", datetime(2025, 2, 28)),
    ]
    # In a real application, you would use .NET interop to set the DataSource.
    # For simplicity, we'll programmatically add rows.
    # This requires more advanced .NET interaction via `clr`.
    # The following is a conceptual snippet of how you'd do it with `clr`:
    #
    # import clr
    # clr.AddReference("System.Windows.Forms")
    # clr.AddReference("System.Drawing")
    # from System.Windows.Forms import DataGridView, DataGridViewTextBoxColumn
    # from System.Drawing import Font
    #
    # dgv = DataGridView()
    # # Add columns
    # for col_name in ["First Name", "Last Name", "Age", "City", "Join Date"]:
    #     column = DataGridViewTextBoxColumn()
    #     column.Name = col_name
    #     column.HeaderText = col_name
    #     dgv.Columns.Add(column)
    # # Add rows
    # for row_data in data:
    #     dgv.Rows.Add(row_data)
    # # Set font
    # dgv.Font = Font("Segoe UI", 9)
    #
    # # The `CreateWindowEx` call above is for the native window handle.
    # # You would then use `dgv.Handle` or assign the control to the window.
    # --- Simplified Native Population (Less common but works) ---
    # For this example, let's just show the window. The full .NET interop is complex.
    # The key takeaway is that you *can* create the control.
    # 5. Show the window and start the message loop
    win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
    win32gui.UpdateWindow(hwnd)
    print("Window created. Close it to exit.")
    win32gui.PumpMessages()
if __name__ == "__main__":
    create_datagridview()

Note on the PyWin32 Example: The commented-out section shows the proper .NET way to populate the grid using the clr (Common Language Runtime) bridge. The native API alone is not enough for data binding. This highlights that while you can create the window, fully utilizing it requires knowledge of .NET object models.


Option 2: The Cross-Platform Approach - PyQt / PySide

For applications that need to run on Windows, macOS, and Linux, PyQt or its free counterpart PySide are the industry standard. They provide their own powerful, highly customizable table widgets that are just as capable as the .NET DataGridView.

Why use this?

  • Cross-platform: Works everywhere.
  • Rich Feature Set: Sorting, filtering, editing, cell spanning, custom delegates, and more.
  • Modern Look and Feel: Can be styled to look native on any OS.
  • Large Community & Excellent Documentation.

Installation:

# For PyQt6 (recommended)
pip install PyQt6
# For PySide6 (the official Qt binding for Python)
pip install PySide6

Example: QTableWidget with PySide6

QTableWidget is the easiest to use, as it works with a simple model of rows and columns. QTableView is more powerful but requires setting up a custom model (like QStandardItemModel or a QAbstractTableModel).

import sys
from PySide6.QtWidgets import (
    QApplication, QMainWindow, QTableWidget, QTableWidgetItem,
    QVBoxLayout, QWidget, QHeaderView
)
from PySide6.QtCore import Qt
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PySide6 Data Grid Example")
        self.setGeometry(100, 100, 800, 600)
        # Create the central widget and layout
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        # Create the QTableWidget
        self.table_widget = QTableWidget()
        layout.addWidget(self.table_widget)
        # --- Populate the Table ---
        data = [
            ("Alice", "Smith", 28, "New York"),
            ("Bob", "Johnson", 45, "Los Angeles"),
            ("Charlie", "Brown", 33, "Chicago"),
            ("Diana", "Prince", 30, "London"),
        ]
        # Set dimensions
        self.table_widget.setRowCount(len(data))
        self.table_widget.setColumnCount(len(data[0]))
        # Set headers
        headers = ["First Name", "Last Name", "Age", "City"]
        self.table_widget.setHorizontalHeaderLabels(headers)
        # Populate data
        for row_idx, row_data in enumerate(data):
            for col_idx, cell_data in enumerate(row_data):
                # Create an item and set its data
                item = QTableWidgetItem(str(cell_data))
                # Make some cells editable (e.g., the city)
                if col_idx == 3:
                    item.setFlags(item.flags() | Qt.ItemIsEditable)
                self.table_widget.setItem(row_idx, col_idx, item)
        # --- Style the Table ---
        # Adjust column widths to content
        self.table_widget.resizeColumnsToContents()
        # Set stretch factor for the last column (City)
        self.table_widget.horizontalHeader().setStretchLastSection(True)
        # Enable sorting
        self.table_widget.setSortingEnabled(True)
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

Option 3: The Web-Based Approach - Dash / Streamlit

If your application is primarily a data dashboard, a web-based framework might be the best choice. You can use a powerful JavaScript data grid library like AG Grid or SlickGrid and embed it in your Python app.

Why use this?

  • No installation for users: They just use a web browser.
  • Extremely Powerful: Modern JS grids are arguably the most powerful in the world.
  • Great for Data Visualization: Easy to combine with Plotly, Bokeh, etc.

Installation:

pip install dash

Example: Simple Dash App with AG Grid

This example uses Dash to serve a web page with an AG Grid.

import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import dash_ag_grid as dag
import pandas as pd
# Sample data
data = {
    'First Name': ['Alice', 'Bob', 'Charlie', 'Diana'],
    'Last Name': ['Smith', 'Johnson', 'Brown', 'Prince'],
    'Age': [28, 45, 33, 30],
    'City': ['New York', 'Los Angeles', 'Chicago', 'London']
}
df = pd.DataFrame(data)
# App layout
app = dash.Dash(__name__)
server = app.server # For deployment
app.layout = html.Div([
    html.H1("Python Data Grid with Dash and AG Grid"),
    dcc.Graph(
        id='datagrid',
        figure={
            'data': [dict(
                type='table',
                header=dict(values=list(df.columns)),
                cells=dict(values=[df[col] for col in df.columns])
            )]
        }
    ),
    html.Hr(),
    html.H2("Using the more powerful dash-ag-grid component:"),
    dag.AgGrid(
        id='ag-grid-table',
        columnDefs=[{'field': i} for i in df.columns],
        rowData=df.to_dict('records'),
        defaultColDef={
            'flex': 1,
            'minWidth': 150,
            'resizable': True,
            'sortable': True,
            'filter': True,
            'editable': True,
        }
    )
])
if __name__ == '__main__':
    app.run_server(debug=True)

Summary: Which One Should You Choose?

Feature / Requirement PyWin32 (WinForms) PyQt / PySide Dash / Streamlit (Web)
Platform Windows Only Cross-Platform Cross-Platform (Browser)
Control Type Native .NET DataGridView Native Qt QTableWidget / QTableView JavaScript Grid (AG Grid, etc.)
Ease of Use Medium (requires .NET knowledge) High (very Pythonic) High (if you know web basics)
Performance Excellent for large datasets Excellent Excellent
Features Full .NET feature set Very rich feature set Extremely rich JS feature set
Best For Migrating .NET apps, Windows-only desktop tools. General-purpose, professional desktop apps. Data dashboards, web-based analytics tools.

Recommendation:

  • For most new desktop applications, start with PySide6. It's powerful, cross-platform, and has a fantastic community.
  • If you are in a Windows-only corporate environment and need 100% feature parity with an existing C# application, PyWin32 is the way to go.
  • If your application is a data dashboard or will be accessed via a browser, use Dash with dash-ag-grid.
分享:
扫描分享到社交APP
上一篇
下一篇