-
!
-
|
!
-
!
-
!
-
!
-
!
-
!
-
|
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
| import sys
import csv
import os
from PySide6.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QPushButton,
QTableWidget, QTableWidgetItem, QFileDialog,
QMessageBox, QLabel )
from PySide6.QtCore import Qt,Slot
class CsvTsvViewer(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle('CSV/TSV Viewer')
self.resize(800, 600)
main_layout = QVBoxLayout(self)
open_button = QPushButton("CSV/TSVファイルを開く")
self.file_label = QLabel("ファイルが選択されていません")
self.file_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.table_widget = QTableWidget()
self.table_widget.setAlternatingRowColors(True)
main_layout.addWidget(open_button)
main_layout.addWidget(self.file_label) main_layout.addWidget(self.table_widget)
open_button.clicked.connect(self.open_file_dialog)
self.setLayout(main_layout)
@Slot()
def open_file_dialog(self):
"""ファイル選択ダイアログを開く"""
file_path, _ = QFileDialog.getOpenFileName(
self,
"CSVまたはTSVファイルを選択",
"", "CSV/TSV Files (*.csv *.tsv *.txt);;CSV Files (*.csv);;TSV Files (*.tsv);;All Files (*)"
)
if file_path:
self.load_data(file_path)
self.file_label.setText(f"表示中のファイル: {os.path.basename(file_path)}") else:
self.file_label.setText("ファイルが選択されていません")
self.table_widget.setRowCount(0)
self.table_widget.setColumnCount(0)
def load_data(self, file_path):
"""指定されたパスのファイルを読み込み、テーブルに表示する"""
self.table_widget.setRowCount(0)
self.table_widget.setColumnCount(0)
_, ext = os.path.splitext(file_path)
delimiter = ',' if ext.lower() == '.csv' else '\t'
encodings_to_try = ['utf-8', 'cp932', 'shift_jis'] data = []
header = []
for encoding in encodings_to_try:
try:
print(f"Trying encoding: {encoding}") with open(file_path, 'r', encoding=encoding, newline='') as csvfile:
reader = csv.reader(csvfile, delimiter=delimiter)
header = next(reader, None)
if header is None: QMessageBox.information(self, "情報", "ファイルが空です。")
return
data = list(reader)
print("File read successfully.")
break except FileNotFoundError:
QMessageBox.critical(self, "エラー", f"ファイルが見つかりません:\n{file_path}")
return
except UnicodeDecodeError:
print(f"Failed to decode with {encoding}")
continue except csv.Error as e:
QMessageBox.critical(self, "CSVエラー", f"ファイルの読み込み中にエラーが発生しました (形式が不正な可能性があります):\n{e}")
return
except Exception as e:
QMessageBox.critical(self, "エラー", f"予期せぬエラーが発生しました:\n{e}")
return
else: QMessageBox.critical(self, "エンコーディングエラー", f"ファイルの文字コードを判別できませんでした。\n試行したエンコーディング: {', '.join(encodings_to_try)}")
return
if not header: return
num_cols = len(header)
num_rows = len(data)
self.table_widget.setColumnCount(num_cols)
self.table_widget.setRowCount(num_rows)
self.table_widget.setHorizontalHeaderLabels(header)
for row_idx, row_data in enumerate(data):
for col_idx in range(num_cols):
if col_idx < len(row_data):
cell_text = row_data[col_idx]
else:
cell_text = "" item = QTableWidgetItem(cell_text)
self.table_widget.setItem(row_idx, col_idx, item)
self.table_widget.resizeColumnsToContents()
print("Table populated.")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = CsvTsvViewer()
window.show()
sys.exit(app.exec())
|