LoginSignup
0
0

tkinter がうまくいかないので、PyQt6でWidget(ウィジェット)に挑戦(その4)自作programをRadiButtonでリスト化

Last updated at Posted at 2023-06-09

環境

・MacOS Ventura 13.2
・python3.10.4
・pyqt6(インストールが必要です。% python3 -m pip install pyqt6)

作った理由

programを色々と作って行くといっぱいたまりますよね。そう言う時ディレクトリにある自作programをRadiButtonでリスト化して、ラジオボタンを選択するだけで実行できれば楽ちんだなと考えました。ターミナルもprogramごとに開かないで、一度ひらけばOKです。

出来上がったWedget

"フォルダーに新規ターミナル" をクリック

スクリーンショット

ターミナルがひらいたら % python3 main.py で実行
スクリーンショット

ラジオボタンを選択してSelectをクリック
スクリーンショット

選択したディレクトリのプログラムが実行されて、Widgetが表示される。
Closeをクリックするまで、選択は繰り返し行えます。

スクリーンショット

これだけのことですが、一度terminalを開き、main.pyを実行するだけで、
terminalをprogram毎に開かない で実行できます。
楽ちんです。

事前準備

1、python ファイルのあるディレクトリが必要です。(ディレクトリの出来上がりのイメージを参照してください。)
この中のディレクトリをリストにして、RadioButtonにします。
 なお、表示するリストから外したいディレクトリもあると思います。外す場合は、_(アンダーバー)を対象のディレクトリの頭部につけてください。
 (頭部にアンダーバー( _ )の付いている_test_1及び_test_2のディレクトリについては、RadioButtonの表示から省かれることを確認するダミーです。確認後削除しても構いません)

2、01_ から03_まではプログラムの入っているディレクトリです。
RadioButoonで」実行したい番号を選択した時に、キーとしている名称はメインプログラムの名称が"main.py"となっているものとしています。

           # 実行
            sb.run(['python3', 'main.py'])

'main.py'を普段使っている名称に変更する場合は、全ての対象ディレクトリで共通の名称にして下さい。
sb.run(['python3', 'xxxx.py'])の'xxxx.py'部分の変更も忘れずに!

(ディレクトリの出来上がりのイメージ)

スクリーンショット スクリーンショット スクリーンショット スクリーンショット

3、programの最初にPATHを記述する箇所があります。
このprogram(main.py)を置いた直前のディレクトリのフルパスを記述してください

Finderの下部に表示されている「”xxxxx”のパス名をコピー」を右クリックしてコピーを取得し、貼り付けて下さい。(ご存じと思いますが念のため)
スクリーンショット

4、実行ファイルは、リスト化したいディレクトリと同じ場所にに保管してください。(ディレクトリの出来上がりのイメージを参照してください。)
実行は、% python3 main.pyとTerminalで記述して下さい。一度実行すれば、terminalは隠しておいても大丈夫です。
スクリーンショット

それでは下記のCodeをコピペして試して見てください>

# 一つのディレクトリにあるいくつかのファイルから、一つのpython faileを選択して実行する

# ラジオボタンにつける名称をディレクトリからリストを作り、そのリストから付ける
# ラジオボタンをチェックし、buttonをクリックするとその番号を返す
# 選択された番号からpython3 Fileを選択してmain.pyを実行する

# ---------------------------------------------
import pandas as pd
import os
import subprocess as sb
# ---------------------------------------------
# ディレクトリ名のみの一覧を取得・実行するディレクトリに移動で使用
# 本programのあるディレクトリのフルパス
path = '/Users/あなたの名前/Library/Mobile Documents/com~apple~CloudDocs/03_qiita関係/Qiita投稿Program/15_tkinter がうまくいかないので、PyQt6でWidget(ウィジェット)に挑戦(その4)'
# ---------------------------------------------
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QRadioButton, QPushButton, QLabel
from PyQt6.QtGui import QFont   # フォントのサイズを設定
# ---------------------------------------------

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    # -----------------------------------------
    def initUI(self):
        '''画面タイトルの設定'''
        self.setWindowTitle('Select Meni')

        # -------------------------------------
        '''mainレイアウトの設定'''
        layout = QVBoxLayout()
        self.setLayout(layout)

        # -------------------------------------
        '''widgetの用意'''
        # ---------------
        #rdiobuttonの準備(リストから設定)
        # ディレクトリ名のみの一覧を取得
        files = os.listdir(path)
        files_dir = [f for f in files if os.path.isdir(os.path.join(path, f))]

        # --------------------------------------
        #「files_dir」リストから先頭がアンダースコアで始まるファイルを除外する
        files_dir = [file for file in files_dir if not file.startswith('_')]

        # --------------------------------------
        # 作成したリストのディレクトリ名をラジオボタンの名称に設定
        self.radiobuttons = []

        font = QFont()# フォントのサイズを設定
        font.setPointSize(15)  # フォントのサイズを設定
        files_dir.sort()  # リストを番号順に並び替える
        
        for i, option in enumerate(files_dir,start = 1):# start=1で開始値指定
            rb = QRadioButton(option)
            rb.setObjectName(str(i))
            rb.setFont(font)  # フォントを設定
            layout.addWidget(rb)
        
            self.radiobuttons.append(rb)
            # -------------------
            # 選択漏れ防止(1番目にチェックが入る)
            if i == 1:
                rb.setChecked(True)
            else:
                pass
            # -------------------

        self.mylist = files_dir

        # -------------------
        # buttonの作成
        self.button = QPushButton('Select')
        self.button.setFont(font)  # フォントを設定
        self.button.clicked.connect(self.show_selected)
        layout.addWidget(self.button)

        # -------------------
        # 計算結果を表示するためのラベルの用意
        self.result_label = QLabel('選択結果を表示',self)
        self.result_label.setFont(font)  # フォントを設定
        layout.addWidget(self.result_label)
        
        # -------------------
        self.label2 = QLabel('リストを表示',self)
        self.label2.setFont(font)  # フォントを設定
        layout.addWidget(self.label2)
        
        # -------------------
        self.button2 = QPushButton('Close')
        self.button2.setFont(font)  # フォントを設定
        self.button2.clicked.connect(QApplication.quit)
        layout.addWidget(self.button2)

        # -------------------------------------
        # widgwetが画面上に表示される
        self.show
        
    # -----------------------------------------
    def show_selected(self):
        ans = None  # 他の関数(メソッド)で使用する為、初期値を与える
        for rb in self.radiobuttons:
            if rb.isChecked():# ラジオボタン(QRadioButton)の状態を1個ずつ確認するメソッド
                self.result_label.setText(f'選択結果:{rb.objectName()}')
                #print('#14')
                self.label2.setText(f'選択結果:{str(self.mylist[int(rb.objectName())-1])}')# ラジオボタンは1〜、リストは0〜のため-1で補正。またrb.objectName()はstrのためintへ変換
                #print('#15')
                ans = int(rb.objectName())# <--
                #print('#16')
                break
            #else:
                #print('#12')
                
        # -------------------------------------
        # ansをshow_selected2メソッドに渡す
        self.show_selected2(ans)
        
    # -----------------------------------------
    def show_selected2(self,ans):# ansを引数として使用
        if ans == None:  # もし初期値がNoneであれば何もしない
            print()

        else:

            # 辞書に変換
            files_dir = self.mylist
            key = []
            ln = len(files_dir)

            [key.append(i+1) for i in range(ln)]

            ele = files_dir
            dct = dict(zip(key, ele))

            # --------------------------------------
            # 辞書をdataframeへ変換
            dct2 = {'key':key, 'File':files_dir}
            df = pd.DataFrame(dct2,columns = ['key','File'],index = key)

            # --------------------------------------
            # 実行するディレクトリを選択する
            pr = df.loc[ans,'File']

            # --------------------------------------
            # 実行するディレクトリに移動
            os.chdir(path + '/'+pr)
            b = os.getcwd()
            print(f'現在のディレクトリは\n{b}\nです')

            # 実行
            sb.run(['python3', 'main.py'])
            # --------------------------------------

# ---------------------------------------------
if __name__ == '__main__':
   #main()
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()

関係リンク

"ChatGPT for Mac" をインストールして使ってみた。
https://qiita.com/ti104110/items/40563e13d9f389bd62bd


tkinter がうまくいかないので、PyQt6でWidget(ウィジェット)に挑戦(その1)
https://qiita.com/ti104110/items/0c0800cff58cd10b9676


tkinter がうまくいかないので、PyQt6でWidget(ウィジェット)に挑戦(その2)RadioButtonで選択してWebを開く
https://qiita.com/ti104110/items/7785758f98ef978c2d97


tkinter がうまくいかないので、PyQt6でWidget(ウィジェット)に挑戦(その3)QGridLayout()オブジェクトを使って、labelとQLineEditを横並びに表示
https://qiita.com/ti104110/items/a35263176ff5ddaafac7


tkinter がうまくいかないので、PyQt6でウィジェットに挑戦(その5)「Googleの急上昇ワード」の表示に"QTextBrowser"でURLにリンク設定を追加
https://qiita.com/ti104110/items/d9868846ff7ac9556edf

あとがき

pyqt6については記述方法が定型的なので大分慣れなしたが、今回は実行するディレクトリに移動する部分でChatGPTに教えてもらいました。
osモジュールについては、知らなかったのでこれを機会に勉強してみようと思います。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0