1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

tkinter がうまくいかないので、PyQt6でWidget(ウィジェット)に挑戦(その2)RadioButtonで選択してWebを開く

Last updated at Posted at 2023-06-05

環境

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

出来上がったWedget

ラジオボタンを選択すると
スクリーンショット

選択結果が表示され、Enterをクリックすると
スクリーンショット

Newsサイトが表示されるというProgramです。。
スクリーンショット

今回苦労した点

1.ラジオボタンを作成し、QVBoxLayoutに配置
2.画面の中央にWidgetを表示するために、Widgetのziseを制御

取り敢えずCodeをコピペして試して下さい。

Codeの流れは(その1)と同じです。
1.まず最初に、ほぼ定型の以下の記述をする。
from PyQt6.QtWidgets import xxxの部分は気にしない。もし足りない場合は、Codeを実行した時点で
"NameError: name 'QPushButton' is not defined"
とエラーが出るので、そうしたらQPushButtonをimportに付け加えればOK

#----------------------------------------------------
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QRadioButton, QPushButton
'''主なQtWidgetの種類
QWidget, QVBoxLayout, QLabel, QPushButton, QLineEdit, QRadioButton, QComboBox, QTextEdit, QCheckBox, QxSpinBox, QDateTimeEdit
'''
from PyQt6.QtGui import QFont   # Fontを作成

# ******************************************************
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        # -------------------
        self.initUI()
        # -------------------
        '''後でここに、クラスのインスタンス変数として定義する'''

# ******************************************************
    def initUI(self):
        # Widgetのタイトルの設定
        self.setWindowTitle("RadioButtonでURLを開く")
        #----------------------------------------------------
        # 縦のレイアウトを作成
        layout = QVBoxLayout()# 必須
        self.setLayout(layout)# 必須

と同時に、最後にほぼ定型の以下のCodeを記述。


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    #-----GraphWindowへ飛び処理が終了したら戻ってくる------------
    window.show()
    sys.exit(app.exec())

2.次に、作りたいwidgetをイメージして、設定する順番にLabelButtondef initUI(self):に記述する。ここは、Widgetの種類やrayout、それから重要なconnectを記載します。
一つ記述するごとにCodeを実行してみるといいと思います。
例えば

        # 説明するラベル(Labelの作成とlayout設定)
        self.lbl_01 = QLabel("Selection",self)# 必須
        # layoutの設定
        layout.addWidget(self.lbl_01)# 必須

これで’Selection’と言うラベルが表示されます。
そしてここで実行してみてイメージ通りか確認する。

また、ボタンなどの場合は

        # buttonの作成
        self.btn1 = QPushButton('Select')
        self.btn1.clicked.connect(self.show_selected)
        layout.addWidget(self.btn1)

self.btn1.clicked.connect(self.show_selected)でボタンをクリックした場合の動作をするオブジェクトを指定します。(上記の場合は、def show_selected(self):を呼び出して、押されたラジオボタンの番号を、クラスのインスタンス変数に代入します。)
(なお、def show_selected(self):メソッドが作成されてないと実行してもこの段階ではエラーになります。)

3.次に、connectで操作したい処理をdef文で書く。その際def xxxxxx(self):.selfを忘れないこと
4.最後にEnterボタンを押した後させたい処理のCodeをpython3で記述する。

    def mainText(self):#<-名称は適宜
        '''色々な処理をするpython3 Codeを記入'''
        # URL
        URL1 = "https://www.nikkei.com"# 日経新聞ニュース
        URL2 = "https://news.yahoo.co.jp"# Yahoo!ニュース
        URL3 = "https://news.google.com"# Google ニュース
        
        ans = self.kind_ans
        
        if ans == 1:
            sb.run(['open', '-a', 'Safari', '-g', URL1])
        elif ans == 2:
            sb.run(['open', '-a', 'Safari', '-g', URL2])
        elif ans == 3:
            sb.run(['open', '-a', 'Safari', '-g', URL3])

上記例では、クラスのインスタンス変数(kind_ans)に代入された番号のURLを、Pythonの標準ライブラリのsubprosecc()モジュールを使って開くCodeです。

そうして出来たのがこれです。
これをコピペして、一度動かしてみると何がどんな役割か解ると思います。

# PyQt6の操作
# RadioButtonで選択してWebを開く
# 日経新聞ニュース"https://www.nikkei.com"
# Yahoo!ニュース"https://news.yahoo.co.jp"
# Google ニュース"https://news.google.com"
#----------------------------------------------------
import subprocess as sb
#----------------------------------------------------
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QRadioButton, QPushButton
'''主なQtWidgetの種類
QWidget, QVBoxLayout, QLabel, QPushButton, QLineEdit, QRadioButton, QComboBox, QTextEdit, QCheckBox, QxSpinBox, QDateTimeEdit
'''
from PyQt6.QtGui import QFont   # Fontを作成

# ******************************************************
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        # -------------------
        self.initUI()
        # -------------------
        # クラスのインスタンス変数として定義する
        # (RadioButton_No)
        self.kind_ans = None

# ******************************************************
    def initUI(self):
        # Widgetのタイトルの設定
        self.setWindowTitle("RadioButtonでURLを開く")
        #----------------------------------------------------
        # 縦のレイアウトを作成
        layout = QVBoxLayout()# 必須
        self.setLayout(layout)# 必須
        #----------------------------------------------------
        #(必要であれば記述)
        # 画面の中央に表示するために、Widgetのziseを制御
        # -------------------
        # ウィンドウの幅と高さ(適宜)
        win_width = 300
        win_height = 150
        # -------------------
        # デスクトップの主要なスクリーン情報を取得
        screen = app.primaryScreen()
        screen_geometry = screen.geometry()
        # -------------------
        # デスクトップの中心にウィンドウを表示するためのx座標とy座標を計算
        x = (screen_geometry.width() - win_width) // 2
        y = (screen_geometry.height() - win_height) // 2
        # -------------------
        # ウィンドウの位置とサイズを設定(X, Y, width, height)
        self.setGeometry(x, y, win_width, win_height)
        
        #----------------------------------------------------
        #(必要であれば記述)
        # FontSizeを設定
        font = QFont("Helvetica", 15, QFont.Weight.Normal)# 必要で必要に応じて
        # *************************************************
        '''Widgetを設計(想定)してLabelやButtonを表示指定順に記述'''
        # 説明するラベル(Labelの作成とlayout設定)
        self.lbl_01 = QLabel("Selection",self)# 必須
        # label Fontの設定
        self.lbl_01.setFont(font)# 必要で必要に応じて
        # styleSheetを使用して色を設定
        self.lbl_01.setStyleSheet("color:brown")# 必要で必要に応じて
        # layoutの設定
        layout.addWidget(self.lbl_01)# 必須

        #----------------------------------------------------
        # 種類の選択
        #radioButton
        # Buttonnameのリストの準備
        lst = ['日経新聞ニュース', 'Yahoo!ニュース', 'Google ニュース']
        # -------------------
        # ラジオボタンを作成し、QVBoxLayoutに配置する
        self.lst_element = []

        for i, option in enumerate(lst,start = 1):# start=1で開始値指定
            rbtn1 = QRadioButton(option)

            rbtn1.setObjectName(str(i))
            layout.addWidget(rbtn1)
        
            self.lst_element.append(rbtn1)
            # 選択を忘れた場合のError防止(1番目をdefaultで選択)
            if i==1:
                rbtn1.setChecked(True)
            else:
                pass
        self.mylist = lst
        # -------------------
        # buttonの作成
        self.btn1 = QPushButton('Select')
        self.btn1.clicked.connect(self.show_selected)
        layout.addWidget(self.btn1)

        #----------------------------------------------------
        # 計算結果を表示するためのラベルの用意
        self.result_label = QLabel('選択結果を表示',self)
        layout.addWidget(self.result_label)
        self.lbl4 = QLabel('リストを表示',self)
        layout.addWidget(self.lbl4)

        #----------------------------------------------------
        # 計算を開始するボタンの作成
        self.btn01 = QPushButton("Enter",self,checkable=True)
        self.btn01.clicked.connect(self.mainText)
        layout.addWidget(self.btn01)

        #----------------------------------------------------
        # Widgetを終了するボタン
        self.btn_fin= QPushButton("Finish",self,checkable=True)
        self.btn_fin.clicked.connect(QApplication.quit)
        layout.addWidget(self.btn_fin)
        
# **********************************************************
    def show_selected(self):
        for rbtn1 in self.lst_element:
            if rbtn1.isChecked():# ラジオボタン(QRadioButton)の状態を1個ずつ確認するメソッド
                self.result_label.setText(f'選択結果:{rbtn1.objectName()}')

                self.lbl4.setText(f'選択結果:{str(self.mylist[int(rbtn1.objectName())-1])}を開きます。')# ラジオボタンは1〜、リストは0〜のため-1で補正。またrbtn1.objectName()はstrのためintへ変換
                ans = int(rbtn1.objectName())

                break

        # インスタンス変数へ代入
        self.kind_ans = ans
        
# ******************************************************
    def mainText(self):
        '''色々な処理をするpython3 Codeを記入'''
        # URL
        URL1 = "https://www.nikkei.com"# 日経新聞ニュース
        URL2 = "https://news.yahoo.co.jp"# Yahoo!ニュース
        URL3 = "https://news.google.com"# Google ニュース
        
        ans = self.kind_ans
        
        if ans == 1:
            sb.run(['open', '-a', 'Safari', '-g', URL1])
        elif ans == 2:
            sb.run(['open', '-a', 'Safari', '-g', URL2])
        elif ans == 3:
            sb.run(['open', '-a', 'Safari', '-g', URL3])
        # '-g'フラグは、アイコンがDockに残らないようにするために使用

# ******************************************************
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    #-----GraphWindowへ飛び処理が終了したら戻ってくる------------
    window.show()
    sys.exit(app.exec())    # PyQt6アプリケーションのメインループを開始し、アプリケーションが終了するときに呼び出される関数

あとがき

これらは、参考図書がないため、ほとんどchatGPTに「pyqt6でlabelの作り方を具体的に教えて?」などと聞きながら作りました。
ググったり、本を読むより早くわかりやすく進みました。
たまには、言われた通り記述してもErrorが出ることがあり、その都度Error内容を伝えると、「申し訳ありません。xxxxが説明不足でした。・・・・」とすぐ訂正Codeが来るので、結構楽しく出来ました。

関係リンク

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


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


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


tkinter がうまくいかないので、PyQt6でWidget(ウィジェット)に挑戦(その4)自作programをRadiButtonでリスト化
https://qiita.com/ti104110/items/dc07bcb2d0fa7a9ff269


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


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

1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?