サンプルソース

  • Geminiが教えてくれたソースコード

指定したディレクトでファイル名検索

  • 2025-04-11
すべて開くすべて閉じる
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
!
 
 
-
|
!
 
 
 
 
-
!
 
 
 
-
!
 
-
!
 
-
|
!
 
 
 
 
-
!
 
 
-
!
 
-
!
 
 
-
!
 
-
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
!
 
 
 
 
 
 
-
!
 
 
 
-
!
 
-
!
 
 
 
 
 
 
 
-
!
 
 
 
 
 
 
 
 
 
 
 
 
import sys
import os
from PySide6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QHBoxLayout,
    QLineEdit, QPushButton, QListWidget, QLabel,
    QFileDialog, QMessageBox
)
from PySide6.QtCore import Qt, Slot
 
class FileSearchApp(QWidget):
    def __init__(self):
        super().__init__()
        self.search_path = "" # 検索対象ディレクトリを保持する変数
        self.init_ui()
 
    def init_ui(self):
        self.setWindowTitle('ファイル検索プログラム')
        self.resize(600, 400) # ウィンドウサイズを少し大きめに
 
        # --- レイアウト設定 ---
        main_layout = QVBoxLayout(self)
        dir_layout = QHBoxLayout() # ディレクトリ選択用レイアウト
 
        # --- ウィジェット作成 ---
        # ディレクトリ選択
        dir_label = QLabel("検索ディレクトリ:")
        self.dir_path_label = QLineEdit() # 選択されたパス表示用
        self.dir_path_label.setReadOnly(True) # 編集不可にする
        select_dir_button = QPushButton("ディレクトリを選択...")
 
        # 検索キーワード入力
        keyword_label = QLabel("検索キーワード:")
        self.keyword_input = QLineEdit()
        self.keyword_input.setPlaceholderText("ファイル名に含まれる文字を入力") # ヒント表示
 
        # 検索ボタン
        search_button = QPushButton("検索開始")
 
        # 検索結果表示リスト
        self.results_list = QListWidget()
 
        # --- レイアウトにウィジェットを追加 ---
        # ディレクトリ選択部分
        dir_layout.addWidget(dir_label)
        dir_layout.addWidget(self.dir_path_label)
        dir_layout.addWidget(select_dir_button)
        main_layout.addLayout(dir_layout)
 
        # キーワード入力部分
        main_layout.addWidget(keyword_label)
        main_layout.addWidget(self.keyword_input)
 
        # 検索ボタン
        main_layout.addWidget(search_button, alignment=Qt.AlignmentFlag.AlignCenter) # 中央寄せ
 
        # 結果リスト
        main_layout.addWidget(QLabel("検索結果:"))
        main_layout.addWidget(self.results_list)
 
        # --- シグナルとスロットの接続 ---
        select_dir_button.clicked.connect(self.select_directory)
        search_button.clicked.connect(self.search_files)
        # Enterキーでも検索できるようにする
        self.keyword_input.returnPressed.connect(self.search_files)
 
        self.setLayout(main_layout)
 
    @Slot()
    def select_directory(self):
        """ディレクトリ選択ダイアログを開き、選択されたパスを保存・表示する"""
        directory = QFileDialog.getExistingDirectory(self, "検索するディレクトリを選択してください")
        if directory:
            self.search_path = directory
            self.dir_path_label.setText(directory) # 選択されたパスをラベルに表示
 
    @Slot()
    def search_files(self):
        """指定されたディレクトリ内でキーワードを含むファイルを検索し、結果を表示する"""
        keyword = self.keyword_input.text().strip() # 入力されたキーワードを取得(前後の空白削除)
 
        # --- 入力チェック ---
        if not self.search_path:
            QMessageBox.warning(self, "エラー", "検索するディレクトリを選択してください。")
            return
        if not keyword:
            QMessageBox.warning(self, "エラー", "検索キーワードを入力してください。")
            return
 
        # --- 検索処理 ---
        self.results_list.clear() # 前回の結果をクリア
        found_files = []
 
        try:
            # os.walkで指定ディレクトリ以下の全ファイル・ディレクトリを探索
            for root, dirs, files in os.walk(self.search_path):
                for filename in files:
                    # ファイル名にキーワードが含まれているかチェック(大文字小文字区別なし)
                    if keyword.lower() in filename.lower():
                        full_path = os.path.join(root, filename)
                        found_files.append(full_path)
 
        except Exception as e:
            QMessageBox.critical(self, "検索エラー", f"ファイルの検索中にエラーが発生しました:\n{e}")
            return
 
        # --- 結果表示 ---
        if found_files:
            self.results_list.addItems(found_files)
            print(f"検索完了: {len(found_files)} 件のファイルが見つかりました。") # コンソールにも出力
        else:
            self.results_list.addItem("該当するファイルは見つかりませんでした。")
            print("検索完了: 該当ファイルなし")
 
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = FileSearchApp()
    window.show()
    sys.exit(app.exec())


複数行テキスト処理プログラム

  • 2025-04-11
すべて開くすべて閉じる
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
!
 
-
|
!
 
 
 
-
!
 
-
!
 
 
 
-
!
 
 
 
 
 
-
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
!
 
 
-
!
-
!
 
 
 
 
 
 
 
import sys
from PySide6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout,
    QTextEdit, QPushButton, QLabel
)
from PySide6.QtCore import Slot
 
class MultiLineTextProcessor(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
 
    def init_ui(self):
        self.setWindowTitle('複数行テキスト処理プログラム')
        self.resize(500, 600) # ウィンドウサイズ
 
        # --- レイアウト設定 ---
        main_layout = QVBoxLayout(self)
 
        # --- ウィジェット作成 ---
        # 入力エリア
        input_label = QLabel("入力テキスト:")
        self.input_text_edit = QTextEdit()
        self.input_text_edit.setPlaceholderText("ここに処理したいテキストを入力してください...")
 
        # 処理実行ボタン
        process_button = QPushButton("行番号を付加する") # 処理内容がわかるように
 
        # 出力エリア
        output_label = QLabel("出力テキスト:")
        self.output_text_edit = QTextEdit()
        self.output_text_edit.setReadOnly(True) # 結果表示用なので読み取り専用に
 
        # --- レイアウトにウィジェットを追加 ---
        main_layout.addWidget(input_label)
        main_layout.addWidget(self.input_text_edit)
        main_layout.addWidget(process_button)
        main_layout.addWidget(output_label)
        main_layout.addWidget(self.output_text_edit)
 
        # --- シグナルとスロットの接続 ---
        process_button.clicked.connect(self.process_text)
 
        self.setLayout(main_layout)
 
    @Slot()
    def process_text(self):
        """入力テキストを取得し、処理(行番号付加)を行って出力エリアに表示する"""
        input_text = self.input_text_edit.toPlainText() # 入力テキスト全体を取得
 
        if not input_text:
            self.output_text_edit.setPlainText("") # 入力が空なら出力も空にする
            return
 
        lines = input_text.splitlines() # テキストを行ごとに分割
        processed_lines = []
 
        # --- ここでテキスト処理を行う ---
        # 例: 各行の先頭に行番号を付加する (1始まり)
        for i, line in enumerate(lines):
            processed_line = f"{i + 1}: {line}" # 行番号と元の行を結合
            processed_lines.append(processed_line)
        # -----------------------------
 
        # 処理結果を結合して出力エリアに設定
        result_text = "\n".join(processed_lines)
        self.output_text_edit.setPlainText(result_text)
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MultiLineTextProcessor()
    window.show()
    sys.exit(app.exec())


CSV/TSV Viewer

  • 2025-04-11
すべて開くすべて閉じる
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
!
 
-
|
!
 
-
!
 
 
-
!
 
-
!
-
!
 
 
 
-
!
 
 
 
 
 
 
-
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
!
 
 
-
!
 
 
 
 
 
 
 
 
 
 
-
!
-
!
 
 
 
 
-
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
!
 
 
 
 
-
!
 
-
!
-
!
 
 
 
 
 
 
 
-
!
 
 
 
 
 
 
 
 
import sys
import csv
import os
from PySide6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QPushButton,
    QTableWidget, QTableWidgetItem, QFileDialog,
    QMessageBox, QLabel # 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) # 行の色を交互に変える
        # self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 編集不可にする場合
 
        # --- レイアウトにウィジェットを追加 ---
        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):
        """ファイル選択ダイアログを開く"""
        # ホームディレクトリなどを初期位置にすることも可能
        # start_dir = os.path.expanduser("~")
        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:
                    # csv.readerを使用して読み込む
                    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: # ループがbreakせずに終わった場合 (どのエンコーディングでも読めなかった)
             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())


罫線を含むドキュメントの印刷

  • 2025-04-11
  • QPrinterを利用した印刷
すべて開くすべて閉じる
 
 
 
 
-
!
-
!
 
 
 
 
 
 
 
 
 
 
 
-
!
 
-
!
 
-
!
 
-
!
 
 
 
 
 
-
|
|
!
 
-
!
 
-
|
!
-
!
 
 
 
 
-
!
-
!
 
 
-
!
 
 
 
 
 
 
 
 
-
|
|
|
!
 
-
!
 
 
 
 
 
 
-
!
 
 
 
 
-
!
 
 
-
!
 
 
-
!
 
 
 
 
 
 
 
 
 
 
 
-
!
 
 
-
!
 
 
 
 
 
-
!
 
 
 
 
 
 
 
 
 
import sys
from PySide6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QPushButton, QMessageBox
)
# QtPrintSupportモジュールから印刷関連クラスをインポート
from PySide6.QtPrintSupport import QPrinter, QPrintDialog
# QtGuiモジュールから描画関連クラスをインポート
from PySide6.QtGui import QPainter, QFont, QPen # QPenを追加
from PySide6.QtCore import Qt, QRectF, QPointF # QRectF, QPointFを追加
 
class PrintDocumentApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
 
    def init_ui(self):
        self.setWindowTitle('罫線を含むドキュメントの印刷')
        self.resize(300, 150)
 
        # --- レイアウト設定 ---
        main_layout = QVBoxLayout(self)
 
        # --- ウィジェット作成 ---
        print_button = QPushButton("ドキュメントを印刷")
 
        # --- レイアウトにウィジェットを追加 ---
        main_layout.addWidget(print_button)
 
        # --- シグナルとスロットの接続 ---
        print_button.clicked.connect(self.handle_print)
 
        self.setLayout(main_layout)
 
    def handle_print(self):
        """印刷処理を実行する"""
        # 1. QPrinterオブジェクトを作成
        # 高解像度モードを設定すると、座標系の単位が変わることがあるので注意
        # printer = QPrinter(QPrinter.PrinterMode.HighResolution)
        printer = QPrinter() # 標準解像度
 
        # 2. QPrintDialogを表示してプリンター設定を取得
        print_dialog = QPrintDialog(printer, self)
        if print_dialog.exec() == QPrintDialog.DialogCode.Accepted:
            # ユーザーが「印刷」をクリックした場合のみ続行
            # 3. QPainterオブジェクトを作成して描画開始
            painter = QPainter()
            # プリンターデバイスに対して描画を開始
            if not painter.begin(printer):
                QMessageBox.critical(self, "印刷エラー", "プリンターで描画を開始できませんでした。")
                return
 
            try:
                # --- ここから描画処理 ---
                self.draw_content(painter, printer)
                # --- 描画処理ここまで ---
            except Exception as e:
                 QMessageBox.critical(self, "描画エラー", f"描画中にエラーが発生しました:\n{e}")
            finally:
                # 4. 描画終了
                painter.end()
                print("印刷ジョブを送信しました。") # コンソールにメッセージ
        else:
            print("印刷はキャンセルされました。")
 
 
    def draw_content(self, painter: QPainter, printer: QPrinter):
        """QPainterを使って罫線とテキストを描画する"""
 
        # 描画領域を取得 (単位: デバイスピクセル)
        # page_rect_pixels = printer.pageRect(QPrinter.Unit.DevicePixel)
        # QPainterはデフォルトで論理座標 (通常Points or Pixels) を使う
        # ここでは、よりデバイス非依存な論理座標系で考える
        page_rect = QRectF(printer.pageRect(QPrinter.Unit.Point)) # 単位をポイントにする
 
        # マージン設定 (単位: ポイント, 1 inch = 72 points)
        margin_points = 72 / 2 # 0.5インチ = 36ポイント
        content_rect = page_rect.adjusted(margin_points, margin_points, -margin_points, -margin_points)
 
        if not content_rect.isValid():
            print("エラー: 描画領域が無効です(マージンが大きすぎる可能性)")
            return
 
        # --- 簡単な表を描画する例 ---
        num_rows = 5
        num_cols = 3
        cell_height = content_rect.height() / num_rows
        cell_width = content_rect.width() / num_cols
 
        # フォント設定
        font = QFont("sans-serif", 10) # 10ポイント
        painter.setFont(font)
 
        # ペン設定 (罫線用)
        pen = QPen(Qt.GlobalColor.black, 1, Qt.PenStyle.SolidLine) # 1ポイントの黒線
        painter.setPen(pen)
 
        # 罫線 (表のグリッド) を描画
        for row in range(num_rows + 1):
            y = content_rect.top() + row * cell_height
            p1 = QPointF(content_rect.left(), y)
            p2 = QPointF(content_rect.right(), y)
            painter.drawLine(p1, p2)
 
        for col in range(num_cols + 1):
            x = content_rect.left() + col * cell_width
            p1 = QPointF(x, content_rect.top())
            p2 = QPointF(x, content_rect.bottom())
            painter.drawLine(p1, p2)
 
        # 各セルにテキストを描画
        padding = 5 # セル内のパディング (ポイント)
        for row in range(num_rows):
            for col in range(num_cols):
                # セルの矩形を計算
                cell_rect = QRectF(
                    content_rect.left() + col * cell_width + padding,
                    content_rect.top() + row * cell_height + padding,
                    cell_width - 2 * padding,
                    cell_height - 2 * padding
                )
                # セル内にテキストを描画 (中央揃え)
                text = f"項目 {row+1}-{col+1}"
                painter.drawText(cell_rect, Qt.AlignmentFlag.AlignCenter, text)
 
        print(f"描画完了: PageRect={page_rect}, ContentRect={content_rect}")
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = PrintDocumentApp()
    window.show()
    sys.exit(app.exec())