##前置き
自分自身の備忘録のメモとして書いていきます。
参考としている文献は以下となります。
PyQtの概念的な物やメソッドの使い方に関して、引用させていただいています。
(https://www.amazon.co.jp/Rapid-GUI-Programming-Python-Definitive/dp/0134393333)
(https://www.packtpub.com/application-development/qt5-python-gui-programming-cookbook)
PyQt5のプログラムをQt Designerを使って組み立てていきます。
頻繁に使用するwidgetの使い方から、QMainWindowを使ったものまでを網羅していきたいと思います。
前提として、PyQt5がインストール済みであり、pythonのプログラム経験があることを基本とします。
インストールの仕方やテストプログラムに関してはPyQt5とpython3によるGUIプログラミングを参照してください。
このカテゴリーでは、各widgetの基本的な使用方法を提示していきたいと思います。
次の章以降でより実践的な一歩踏み込んだサンプルを提示したいと思います。
従って、この章は非常に長いです。
#Qt Designerについて
Qt Designerを使用して、PyQtでGUIアプリケーションを開発することができます。これは、一行のコードも書くことなくユーザインタフェースを素早く簡単に設計できます。 デスクトップ上のアイコンをダブルクリックしてQt Designerを起動してください。
Qt Designerを起動すると、次のスクリーンショットに示すように、新しいアプリケーションのテンプレートを選択するように要求されます。
Qt Designerには、さまざまな種類のアプリケーションに適した多数のテンプレートが用意されています。 これらのテンプレートのいずれかを選択し、[作成]ボタンをクリックします。
Qt Designerは、新しいアプリケーション用に以下の定義済みのテンプレートを提供します。
- Dialog with Buttons Bottom:このテンプレートは、右下隅にOKボタンとCancelボタンを含むフォームを作成します。
- Dialog with Buttons Right: このテンプレートは、右上にOKボタンとCancelボタンを含むフォームを作成します。
- Dialog without Buttons: このテンプレートは、ウィジェットを配置できる空のフォームを作成します。 ダイアログのスーパークラスはQDialogです。
- Main Window: このテンプレートは、メインアプリケーションウィンドウと、必要でない場合に削除できるツールバーを備えています。
- Widget: このテンプレートは、スーパークラスがQDialogではなくQWidgetであるフォームを作成します。
GUIアプリケーションは、いくつかのダイアログを持つメインウィンドウまたは1つのダイアログだけで構成されます。小さなGUIアプリケーションは通常、少なくとも1つのダイアログで構成されます。 ダイアログアプリケーションにはボタンが含まれています。 メニューバー、ツールバー、ステータスバー、または中央ウィジェットは含まれていませんが、メインウィンドウアプリケーションには通常それらのすべてが含まれています。
##シグナル&スロットについて
(Qt Documentationから引用)
シグナルとスロットは、オブジェクト間の通信に使用されます。シグナルとスロットのメカニズムはPyQtの中心的な機能で、おそらく他のフレームワークが提供する機能と最も異なる部分です。シグナルとスロットはPyQtのMeta-Object Systemによって可能になりました。
ウィジェットで特定のイベントが発生したときにシグナルが発行されます。PyQtのウィジェットには多くの定義済みシグナルがありますが、ウィジェットをサブクラス化して独自のシグナルを追加することもできます。スロットは特定のシグナルに応答して呼び出される関数です。
PyQtのウィジェットには定義済みのスロットがたくさんありますが、興味のあるシグナルを処理できるように、ウィジェットをサブクラス化して独自のスロットを追加するのが一般的な方法です。シグナルとスロットは、任意の型の引数をいくつでも取ることができます。
スロットはシグナルを受信するために使用できますが、それらは通常のメンバー関数でもあります。オブジェクトがそのシグナルを受信したかどうかがわからないのと同じように、スロットにはシグナルが接続されているかどうかはわかりません。これにより、真に独立したコンポーネントをPyQtで作成することができます。
1つのスロットには任意の数の信号を接続でき、1つの信号は必要に応じた数のスロットに接続できます。信号を別の信号に直接接続することさえ可能です。(これは、最初のシグナルが発行されるとすぐに2番目のシグナルを発行します。)
同時に、シグナルとスロットは強力なコンポーネントプログラミングメカニズムを構成します。
###図(シグナル&スロット)
これらを踏まえた上で、アプリケーションを作っていきます。
作りながらその都度、必要なところを補足していきます。
#Qt DesignerでPyQtアプリケーションを作成する場合の手順
Qt DesignerでPyQtアプリケーションを作成する場合、ほとんど同じ手順がその核となります。
①Qt Designerでアプリケーションに適したテンプレートを選択する
②ウィジェットをレイアウトに配置し、外観と初期属性を設定するとともに、シグナルをスロットに接続する
③作成した画面を.uiファイル(XMLファイル)として保存する
④コマンドユーティリティpyuic5により、.uiファイルをpythonファイルに変換する
⑤④のファイルをインポートするmainのpythonファイルを作成する
→スロットはこちらにコーディングします
それでは、まずは作ってみます。
##QLabelとQPushButtonを使ったアプリケーションを作ってみる
完成形はこんな感じです。
各ボタンを押すことで、左側にその結果が表示されます。
この画面のウィジェットとイベント(シグナルスロット)の関係を表にまとめます。
これがこの画面の設計書となります。「-」はなしです。
division | widget | objectName | text | text point | シグナル | スロット | Input widget | Output widget |
---|---|---|---|---|---|---|---|---|
1 | Label | label_setText | ??? | 13 | - | - | - | - |
2 | Label | label_setPix | Null | 13 | - | - | - | - |
3 | Label | label_setNum | TextLabel | 13 | - | - | - | - |
4 | Label | label_Clear | TextLabel | 13 | - | - | - | - |
5 | Push Button | pushButton_setText | 「にゃんこ」に変更 | 13 | clicked | setText | - | label_setText |
6 | Push Button | pushButton_setPix | 画像をセット | 13 | clicked | setPix | - | label_setPix |
7 | Push Button | pushButton_setNum | 2020をセット | 13 | clicked | setNum | - | label_setNum |
8 | Push Button | pushButton_Clear | クリア | 13 | clicked | Clear_txt | - | label_Clear |
これを実際のレイアウトに設定していきます。
まずは必要なウイジェットを配置します。
全選択し、右クリックしてレイアウトを選択
そのまま格子状に並べるを選択します。
すると以下のように整列します。
設計通り画面を設定し、スペーサーをいれてレイアウトを調整します。
そして以下のような感じにします。
ここら辺は自分にあった調整の仕方を試行錯誤します。
自分にあったものを見つけることで、その後の画面レイアウトの効率をあげることができるはずです。
画像を読み込むlabelウィジェットを右クリックし、[限界サイズ]→[幅の最大値を設定]の順にクリックします
ボタンも余白が勝手に削られないように両わきに全角のスペースを入れておきます
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>552</width>
<height>363</height>
</rect>
</property>
<property name="windowTitle">
<string>Label_TEST</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>480</width>
<height>291</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QLabel" name="label_Clear">
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_setPix">
<property name="font">
<font>
<family>Hiragino Maru Gothic ProN</family>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>画像をセット</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButton_setText">
<property name="font">
<font>
<family>Hiragino Maru Gothic ProN</family>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>「にゃんこ」に変更</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="pushButton_setNum">
<property name="font">
<font>
<family>Hiragino Maru Gothic ProN</family>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>2020をセット</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_setNum">
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="2" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QLabel" name="label_setPix">
<property name="minimumSize">
<size>
<width>206</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="pushButton_Clear">
<property name="font">
<font>
<family>Hiragino Maru Gothic ProN</family>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>クリア</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_setText">
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>???</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
pyuic5で.uiを.py形式に変換します
以下がコマンドです
pyuic5 ui_LabelTest01.ui -o ui_LabelTest01.py
Qt Designerでアプリケーションを作成する際の注意としては、上記のコマンドで作成された.pyファイルを直接編集してはいけないということです、なぜなら次回同じコマンドを打った瞬間にそのコードは消えてしまうからです
作成されたui_LabelTest01.pyを見てみます。
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_LabelTest01.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(552, 363)
self.layoutWidget = QtWidgets.QWidget(Dialog)
self.layoutWidget.setGeometry(QtCore.QRect(40, 30, 480, 291))
self.layoutWidget.setObjectName("layoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.label_Clear = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(18)
self.label_Clear.setFont(font)
self.label_Clear.setObjectName("label_Clear")
self.gridLayout.addWidget(self.label_Clear, 4, 0, 1, 1)
self.pushButton_setPix = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setFamily("Hiragino Maru Gothic ProN")
font.setPointSize(18)
self.pushButton_setPix.setFont(font)
self.pushButton_setPix.setObjectName("pushButton_setPix")
self.gridLayout.addWidget(self.pushButton_setPix, 1, 2, 1, 1)
self.pushButton_setText = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setFamily("Hiragino Maru Gothic ProN")
font.setPointSize(18)
self.pushButton_setText.setFont(font)
self.pushButton_setText.setObjectName("pushButton_setText")
self.gridLayout.addWidget(self.pushButton_setText, 0, 2, 1, 1)
self.pushButton_setNum = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setFamily("Hiragino Maru Gothic ProN")
font.setPointSize(18)
self.pushButton_setNum.setFont(font)
self.pushButton_setNum.setObjectName("pushButton_setNum")
self.gridLayout.addWidget(self.pushButton_setNum, 3, 2, 1, 1)
self.label_setNum = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(18)
self.label_setNum.setFont(font)
self.label_setNum.setObjectName("label_setNum")
self.gridLayout.addWidget(self.label_setNum, 3, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem, 2, 2, 1, 1)
self.label_setPix = QtWidgets.QLabel(self.layoutWidget)
self.label_setPix.setMinimumSize(QtCore.QSize(206, 0))
font = QtGui.QFont()
font.setPointSize(18)
self.label_setPix.setFont(font)
self.label_setPix.setText("")
self.label_setPix.setObjectName("label_setPix")
self.gridLayout.addWidget(self.label_setPix, 1, 0, 2, 1)
self.pushButton_Clear = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setFamily("Hiragino Maru Gothic ProN")
font.setPointSize(18)
self.pushButton_Clear.setFont(font)
self.pushButton_Clear.setObjectName("pushButton_Clear")
self.gridLayout.addWidget(self.pushButton_Clear, 4, 2, 1, 1)
self.label_setText = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(18)
self.label_setText.setFont(font)
self.label_setText.setObjectName("label_setText")
self.gridLayout.addWidget(self.label_setText, 0, 0, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem1, 1, 1, 1, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Label_TEST"))
self.label_Clear.setText(_translate("Dialog", "TextLabel"))
self.pushButton_setPix.setText(_translate("Dialog", "画像をセット"))
self.pushButton_setText.setText(_translate("Dialog", "「にゃんこ」に変更"))
self.pushButton_setNum.setText(_translate("Dialog", "2020をセット"))
self.label_setNum.setText(_translate("Dialog", "TextLabel"))
self.pushButton_Clear.setText(_translate("Dialog", "クリア"))
self.label_setText.setText(_translate("Dialog", "???"))
トップレベルのオブジェクトの名前を持つクラスが作成され、Ui_が前に付加されます。 アプリケーションで使用されるトップレベルのオブジェクトはDialogであるため、Ui_Dialogクラスが作成され、ウィジェットのインタフェース要素が格納されます。 そのクラスには、setupUi()とretranslateUi()という2つのメソッドがあります。 setupUi()メソッドはウィジェットを設定します。 Qt Designerでユーザーインターフェイスを定義する際に使用するウィジェットを作成します。 メソッドは、ウィジェットを1つずつ作成し、それらのプロパティも設定します。 setupUi()メソッドは、ユーザーインターフェイス(子ウィジェット)が作成されるトップレベルのウィジェットである単一の引数をとります。 アプリケーションでは、QDialogのインスタンスです。 retranslateUi()メソッドはインタフェースを変換します。
では、この画面のファイルをインポートするmainのpythonファイルを作成します。
ファイル名はmain_LabelTest01.pyとしています。
import sys
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5.QtGui import QPixmap
from ui_LabelTest01 import *
class MyForm(QDialog):
def __init__(self, parent=None):
super(MyForm, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.ui.pushButton_Clear.clicked.connect(self.Clear_txt)
self.ui.pushButton_setNum.clicked.connect(self.setNum)
self.ui.pushButton_setPix.clicked.connect(self.setPix)
self.ui.pushButton_setText.clicked.connect(self.setText)
self.show()
def setText(self):
self.ui.label_setText.setText('にゃんこ')
def setPix(self):
pixmap = QPixmap("1.png")
self.ui.label_setPix.setPixmap(pixmap)
def setNum(self):
self.ui.label_setNum.setNum(2020)
def Clear_txt(self):
self.ui.label_Clear.clear()
if __name__=="__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())
コードの解説を少々
どんなウィジェットもトップレベルウィンドウとして使用することができます。しかし、ほとんどの場合、QDialog、またはQMainWindow、または、QWidgetのサブクラスでトップレベルウィンドウを作成するでしょう。 QDialogおよびQMainWindowの両方、そしてPyQtのウイジェットはすべてQwidgetを継承します。
・まず必要なモジュールをインポートします、もちろんui_LabelTest01もです
・基本クラスQDialogから継承する新しいMyFormクラスを作成します
MyFormクラスの__init __()
メソッドにNoneのデフォルトの親を与え、それを初期化するためにsuper()を使用しています。親を持っていないウィジェットはトップレベルのウインドウになります。
Ui_Dialog()で画面を作成し、それらの参照をself.uiとして保持します。
self.uiの参照から画面のウィジェットにアクセスしボタンのclickedシグナルにスロットを接続します。
そして画面を表示します。
ちなみに、以下のコードは
def __init__(self, parent=None):
super(MyForm, self).__init__(parent)
以下でも動きますが、親の情報は明確化したほうが今後読みやすいとおもいます。
def __init__(self):
super().__init__()
・def setText(self):、def setPix(self):、def setNum(self):、def Clear_txt(self):はスロットでありシグナルの発生時に実行されるメソッドになります。
たとえば、pushButton_setTextをクリックすると、clicked()イベントが起こりシグナルが送出します。 connect()メソッドはシグナルをスロットに接続します。この場合、スロットはメソッド:setText()です。つまり、ユーザーがpushButton_setTexをクリックすると、setText()メソッドが呼び出されます。 clicked()はイベントであり、イベント処理ループはイベントが発生するのを待ってから、それをディスパッチして何らかのタスクを実行します。イベント処理ループは、exit()メソッドが呼び出されるか、メインウィジェットが破棄されるまで機能し続けます。
QApplication()メソッドを使用して、名前がappのアプリケーションオブジェクトを作成します。すべてのPyQt5アプリケーションは、コマンドラインからの引数リストを含むsys.argvアプリケーションオブジェクトを作成し、アプリケーションオブジェクトの作成中にメソッドに渡さなければなりません。sys.argvパラメータは、スクリプトの起動属性を渡して制御するのに役立ちます。
MyFormクラスのインスタンスは、wという名前で作成されます。
show()メソッドはウィジェットを画面に表示します。
app.exec_()によりイベントループが開始されます。
sys.exit()メソッドはクリーンな終了を保証し、メモリのリソースを解放します。
(注)sys.exit()がなくても動作的には同じなようですが、PyQtのsamplesコードはsys.exit(app.exec_())を使用しているので本稿ではこちらを採用していきます。
##■QLabelクラスが提供するメソッドについて
(Qt Documentationから引用)
⚫️QLabelの特長
QLabelウィジェットはテキストまたは画像表示を提供します。
QLabelはテキストや画像を表示するために使用されます。ユーザー対話機能は提供されていません。ラベルの外観はさまざまな方法で設定でき、他のウィジェットのフォーカスニーモニックキーを指定するために使用できます。
QLabelには、次のコンテンツタイプを含めることができます。
コンテンツ | 設定 |
---|---|
プレーンテキスト | テキストをsetText()に渡します。 |
リッチテキスト | リッチテキストを含むテキストをsetText()に渡します。 |
ピックスマップ | QPixmapをsetPixmap()に渡します。 |
ムービー | QMovieをsetMovie()に渡します。 |
数値 | ntまたはdoubleをsetNum()に渡します。setNum()は、数値をプレーンテキストに変換します。 |
何もない | 空のプレーンテキストと同じです。これがデフォルトです。 clear()で設定してください。 |
警告:QStringをコンストラクターに渡すとき、またはsetText()を呼び出すときは、QLabelがテキストをプレーンテキストとして表示するのか、リッチテキストとして表示するのかを推測するため、入力をサニタイズする必要があります。たとえば、テキストがプレーンフォーマットであるがテキストソースを制御できないと予想される場合(Webからロードされたデータを表示する場合など)、setTextFormat()を明示的に呼び出すことができます。
これらの機能のいずれかを使用して内容が変更されると、以前の内容は消去されます。
デフォルトでは、ラベルには左寄せで縦方向の中央揃えのテキストとイメージが表示され、そこには表示されるテキスト内のタブが自動的に展開されます。ただし、QLabelの外観はいくつかの方法で調整および微調整できます。
QLabelウィジェット領域内のコンテンツの位置は、setAlignment()とsetIndent()で調整できます。テキストコンテンツはsetWordWrap()を使用して単語境界に沿って行を折り返すこともできます。
##■QLineEditクラスが提供するメソッドについて
(Qt Documentationから引用)
⚫️QLineEditの特長
QLineEditのウィジェットは、1行のテキストエディタです。
QLineEditを使用すると、undo とredo、cut とpaste、drag and dropなど、便利な一連の編集機能を使用してプレーンテキストを1行で入力および編集できます(setDragEnabled()を参照)。
QLineEditのechoMode()を変更することで、パスワードなどの入力用の「書き込み専用」フィールドとしても使用できます。
テキストの長さはmaxLength()で制限できます。
関連するクラス QTextEdit で、これは複数行のリッチテキスト編集を可能にします。
テキストはsetText()またはinsert()で変更できます。テキストはtext()で取得されます。表示されたテキストはdisplayText()で取得されます。 テキストはsetSelection()またはselectAll()で選択でき、選択範囲はcut()、copy()およびpaste()できます。テキストはsetAlignment()で整列させることができます。
⚫️QLineEditのシグナル
テキストが変わるとtextChanged()シグナルが発行されます。setText()を呼び出す以外の方法でテキストが変更されると、textEdited()シグナルが発行されます。カーソルが移動するとcursorPositionChanged()シグナルが発行されます。ReturnキーまたはEnterキーが押されると、returnPressed()シグナルが発行されます。
編集が終了すると、ライン編集がフォーカスを失うかReturn / Enterが押されるかしたため、editingFinished()シグナルが発行されます。
ライン編集にvalidator が設定されている場合、validator がQValidator::Acceptableを返す場合にのみreturnPressed()/ editingFinished()シグナルが発行されます。
デフォルトでは、QLineEditはプラットフォームスタイルガイドで指定されているようにフレームを持ちます。setFrame(False)を呼び出すことで無効にできます。
⚫️QLineEditの入力制御
テキストは、validator()またはinputMask()、あるいはその両方を使用して任意に制約することができます。同じQLineEditでvalidator とinput maskを切り替えるときは、未定義の動作を防ぐためにvalidator またはinput maskをクリアするのが最善です。
※ QDoubleValidator, QIntValidator, QRegExpValidator, そしてQRegularExpressionValidatorが参考になります。
####QLineEdit::EchoMode
定数 | 値 | 説明 |
---|---|---|
Normal | 0 | 入力したとおりに文字を表示します。これがデフォルトです。 |
NoEcho | 1 | 何も表示しません。これは、パスワードの長ささえ秘密にしなければならないパスワードに適しているかもしれません。 |
Password | 2 | 実際に入力された文字の代わりにプラットフォーム依存のパスワードマスク文字を表示します。 |
PasswordEchoOnEdit | 3 | 編集中に入力したとおりに文字を表示しPasswordます。それ以外の場合は文字を表示します。 |
##QLineEditを使ったアプリケーションを作ってみる
完成形はこんな感じです。
設計書は以下です。
- | ui_LineEditTest01.py | main_LineTest01.py | |||||||
division | widget | objectName | text | text point | atribute | シグナル | スロット | Input widget | Output widget |
1 | Line Edit | lineEdit_item | Null | 13 | focusPolicy(ClickFocus) | - | - | this | this |
2 | label | label_1 | モードの選択ボタンを押してください | 13 | - | - | - | - | - |
3 | Push Button | pushButton_Normal | Normal | 13 | AutoDefault(False) | clicked | setNormal | lineEdit_item | lineEdit_item |
4 | Push Button | pushButton_NoEcho | NoEcho | 13 | AutoDefault(False) | clicked | setNoEcho | lineEdit_item | lineEdit_item |
5 | Push Button | pushButton_Password | Password | 13 | AutoDefault(False) | clicked | setPassword | lineEdit_item | lineEdit_item |
6 | Push Button | pushButton_PasswordEchoOnEdit | PasswordEchoOnEdit | 13 | AutoDefault(False) | clicked | setPasswordEchoOnEdit | lineEdit_item | lineEdit_item |
7 | horizontal line | line_1 | - | - | - | - | - | - | - |
8 | label | label_2 | テキストの最大文字数は10です。[半角・全角どちらも1文字としてカウント] | 13 | - | - | - | - | - |
9 | Line Edit | lineEdit_Maxlen | Null | 13 | setMaxLength(10) | this | this | ||
focusPolicy(ClickFocus) | |||||||||
10 | label | label_3 | テキストの最大バイトは20です。[半角=1byte、全角=2byteでカウント] | 13 | - | - | - | - | - |
11 | Line Edit | lineEdit_MaxlenCount | Null | 13 | focusPolicy(ClickFocus) | editingFinished | check_length | this | this |
12 | horizontal line | line_2 | - | - | - | - | - | - | - |
13 | Line Edit | lineEdit_sample | Null | 13 | - | - | - | this | this |
14 | label | label_display | Null | 13 | - | - | - | lineEdit_sample | this |
15 | Push Button | pushButton_setText | 「いろは」をセット | 13 | AutoDefault(False) | clicked | Method_setText | - | lineEdit_sample |
16 | Push Button | pushButton_textShow | 入力文字を表示 | 13 | AutoDefault(False) | clicked | Method_textShow | lineEdit_sample | lineEdit_sample |
17 | Push Button | pushButton_Clear | Clear | 13 | AutoDefault(False) | clicked | Method_Clear | lineEdit_sample | lineEdit_sample |
18 | Push Button | pushButton_setFocus | フォーカスセット | 13 | AutoDefault(False) | clicked | Method_setFocus | - | lineEdit_sample |
19 | Push Button | pushButton_Disable | 読み取り専用 | 13 | AutoDefault(False) | clicked | Method_Disable | lineEdit_sample | lineEdit_sample |
20 | Push Button | pushButton_DisableCSS | 読み取り専用(CSS) | 13 | AutoDefault(False) | clicked | Method_DisableCSS | lineEdit_sample | lineEdit_sample |
21 | Push Button | pushButton_editEnable | 入力可能 | 13 | AutoDefault(False) | clicked | Method_editEnable | lineEdit_sample | lineEdit_sample |
22 | horizontal line | line_3 | - | - | - | - | - | - | - |
23 | Line Edit | lineEdit_readOnly | Null | 13 | focusPolicy(ClickFocus) | - | - | this | this |
24 | Push Button | pushButton_readOnly | readOnly(True) | 13 | AutoDefault(False) | clicked | Method_readOnly | lineEdit_readOnly | lineEdit_readOnly |
25 | Push Button | pushButton_readOnlyFalse | readOnly(False) | 13 | AutoDefault(False) | clicked | Method_readOnlyFalse | lineEdit_readOnly | lineEdit_readOnly |
表の意味を少し...
・「-」は「なし」です。
・「Input widget」「Output widget」が「this」のものはそのwidget自身という意味になります。
・「atribute」はQtDesignerで設定してあるプロパティです。
ui_LineEditTest01.pyでセル結合している部分は、QtDesignerでレイアウトと設定したものになります。
プログラムは、LineEditに入力し、ボタンを押すことでならかの加工を行います。
レイアウトは、簡単なものなので、詳細は省きます。
下の3つを使えば簡単にできます。トライしてみてください。
PushButtonの「atribute」をAutoDefault(False)にしていますが、Tureの場合EnterやReturnキーでボタンのclickイベントが有効になってしまうのでそれを避けるためにしています。
(※QPushButtの特徴はこの後にふれます)
LineEditの「atribute」をfocusPolicy(ClickFocus)にしているのは、クリックしたときだけfocus移動したいためです。
例として、こんな感じです。これをui_LineEditTest01.uiとして保存します。
ui_LineEditTest01.uiはこちらになります。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>781</width>
<height>615</height>
</rect>
</property>
<property name="windowTitle">
<string>LineEditTest</string>
</property>
<widget class="QLineEdit" name="lineEdit_item">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>43</x>
<y>30</y>
<width>691</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
</widget>
<widget class="QLabel" name="label_1">
<property name="geometry">
<rect>
<x>43</x>
<y>62</y>
<width>371</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>モードの選択ボタンを押してください</string>
</property>
</widget>
<widget class="Line" name="line_2">
<property name="geometry">
<rect>
<x>40</x>
<y>310</y>
<width>691</width>
<height>21</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="Line" name="line_1">
<property name="geometry">
<rect>
<x>40</x>
<y>140</y>
<width>691</width>
<height>21</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="Line" name="line_3">
<property name="geometry">
<rect>
<x>40</x>
<y>480</y>
<width>691</width>
<height>16</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_MaxlenCount">
<property name="geometry">
<rect>
<x>43</x>
<y>266</y>
<width>200</width>
<height>32</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>43</x>
<y>240</y>
<width>671</width>
<height>26</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>テキストの最大バイトは20です。[半角=1byte、全角=2byteでカウント]</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_Maxlen">
<property name="geometry">
<rect>
<x>43</x>
<y>195</y>
<width>200</width>
<height>32</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="maxLength">
<number>10</number>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>43</x>
<y>169</y>
<width>745</width>
<height>26</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>テキストの最大文字数は10です。[半角・全角どちらも1文字としてカウント]</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_readOnly">
<property name="geometry">
<rect>
<x>43</x>
<y>513</y>
<width>501</width>
<height>32</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>560</x>
<y>510</y>
<width>180</width>
<height>85</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton_readOnly">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>readOnly(True)</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_readOnlyFalse">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>readOnly(False)</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>40</x>
<y>385</y>
<width>701</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton_setText">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>「いろは」をセット</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton_textShow">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>入力文字を表示</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButton_Clear">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>Clear</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="pushButton_setFocus">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>フォーカスセット</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_Disable">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>読み取り専用</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButton_DisableCSS">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>読み取り専用(CSS)</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_editEnable">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string> 入力可能 </string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLineEdit" name="lineEdit_sample">
<property name="geometry">
<rect>
<x>43</x>
<y>340</y>
<width>341</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
</widget>
<widget class="QLabel" name="label_display">
<property name="geometry">
<rect>
<x>400</x>
<y>340</y>
<width>341</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>42</x>
<y>98</y>
<width>691</width>
<height>35</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_Normal">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>Normal</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_NoEcho">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>NoEcho</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_Password">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>Password</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_PasswordEchoOnEdit">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>PasswordEchoOnEdit</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
それでは、.uiファイル(xml形式)を.pyに変換します。コマンドは以下になります。
pyuic5 ui_LineEditTest01.ui -o ui_LineEditTest01.py
変換するとこんな感じになります。
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_LineEditTest01.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(781, 615)
self.lineEdit_item = QtWidgets.QLineEdit(Dialog)
self.lineEdit_item.setEnabled(True)
self.lineEdit_item.setGeometry(QtCore.QRect(43, 30, 691, 31))
font = QtGui.QFont()
font.setPointSize(16)
self.lineEdit_item.setFont(font)
self.lineEdit_item.setFocusPolicy(QtCore.Qt.ClickFocus)
self.lineEdit_item.setObjectName("lineEdit_item")
self.label_1 = QtWidgets.QLabel(Dialog)
self.label_1.setGeometry(QtCore.QRect(43, 62, 371, 31))
font = QtGui.QFont()
font.setPointSize(16)
self.label_1.setFont(font)
self.label_1.setObjectName("label_1")
self.line_2 = QtWidgets.QFrame(Dialog)
self.line_2.setGeometry(QtCore.QRect(40, 310, 691, 21))
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.line_1 = QtWidgets.QFrame(Dialog)
self.line_1.setGeometry(QtCore.QRect(40, 140, 691, 21))
self.line_1.setFrameShape(QtWidgets.QFrame.HLine)
self.line_1.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_1.setObjectName("line_1")
self.line_3 = QtWidgets.QFrame(Dialog)
self.line_3.setGeometry(QtCore.QRect(40, 480, 691, 16))
self.line_3.setFrameShape(QtWidgets.QFrame.HLine)
self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_3.setObjectName("line_3")
self.lineEdit_MaxlenCount = QtWidgets.QLineEdit(Dialog)
self.lineEdit_MaxlenCount.setGeometry(QtCore.QRect(43, 266, 200, 32))
self.lineEdit_MaxlenCount.setMinimumSize(QtCore.QSize(125, 0))
self.lineEdit_MaxlenCount.setMaximumSize(QtCore.QSize(200, 16777215))
font = QtGui.QFont()
font.setPointSize(16)
self.lineEdit_MaxlenCount.setFont(font)
self.lineEdit_MaxlenCount.setFocusPolicy(QtCore.Qt.ClickFocus)
self.lineEdit_MaxlenCount.setObjectName("lineEdit_MaxlenCount")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(43, 240, 671, 26))
font = QtGui.QFont()
font.setPointSize(16)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.lineEdit_Maxlen = QtWidgets.QLineEdit(Dialog)
self.lineEdit_Maxlen.setGeometry(QtCore.QRect(43, 195, 200, 32))
self.lineEdit_Maxlen.setMaximumSize(QtCore.QSize(200, 16777215))
font = QtGui.QFont()
font.setPointSize(16)
self.lineEdit_Maxlen.setFont(font)
self.lineEdit_Maxlen.setFocusPolicy(QtCore.Qt.ClickFocus)
self.lineEdit_Maxlen.setMaxLength(10)
self.lineEdit_Maxlen.setObjectName("lineEdit_Maxlen")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setEnabled(True)
self.label_2.setGeometry(QtCore.QRect(43, 169, 745, 26))
font = QtGui.QFont()
font.setPointSize(16)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.lineEdit_readOnly = QtWidgets.QLineEdit(Dialog)
self.lineEdit_readOnly.setGeometry(QtCore.QRect(43, 513, 501, 32))
font = QtGui.QFont()
font.setPointSize(16)
self.lineEdit_readOnly.setFont(font)
self.lineEdit_readOnly.setFocusPolicy(QtCore.Qt.ClickFocus)
self.lineEdit_readOnly.setObjectName("lineEdit_readOnly")
self.layoutWidget = QtWidgets.QWidget(Dialog)
self.layoutWidget.setGeometry(QtCore.QRect(560, 510, 180, 85))
font = QtGui.QFont()
font.setPointSize(16)
self.layoutWidget.setFont(font)
self.layoutWidget.setObjectName("layoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.pushButton_readOnly = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_readOnly.setFont(font)
self.pushButton_readOnly.setAutoDefault(False)
self.pushButton_readOnly.setObjectName("pushButton_readOnly")
self.verticalLayout.addWidget(self.pushButton_readOnly)
self.pushButton_readOnlyFalse = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_readOnlyFalse.setFont(font)
self.pushButton_readOnlyFalse.setAutoDefault(False)
self.pushButton_readOnlyFalse.setObjectName("pushButton_readOnlyFalse")
self.verticalLayout.addWidget(self.pushButton_readOnlyFalse)
self.layoutWidget1 = QtWidgets.QWidget(Dialog)
self.layoutWidget1.setGeometry(QtCore.QRect(40, 385, 701, 81))
font = QtGui.QFont()
font.setPointSize(16)
self.layoutWidget1.setFont(font)
self.layoutWidget1.setFocusPolicy(QtCore.Qt.TabFocus)
self.layoutWidget1.setObjectName("layoutWidget1")
self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget1)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.pushButton_setText = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_setText.setFont(font)
self.pushButton_setText.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_setText.setAutoDefault(False)
self.pushButton_setText.setObjectName("pushButton_setText")
self.gridLayout.addWidget(self.pushButton_setText, 0, 0, 1, 1)
self.pushButton_textShow = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_textShow.setFont(font)
self.pushButton_textShow.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_textShow.setAutoDefault(False)
self.pushButton_textShow.setObjectName("pushButton_textShow")
self.gridLayout.addWidget(self.pushButton_textShow, 0, 1, 1, 1)
self.pushButton_Clear = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_Clear.setFont(font)
self.pushButton_Clear.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_Clear.setAutoDefault(False)
self.pushButton_Clear.setObjectName("pushButton_Clear")
self.gridLayout.addWidget(self.pushButton_Clear, 0, 2, 1, 1)
self.pushButton_setFocus = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_setFocus.setFont(font)
self.pushButton_setFocus.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_setFocus.setAutoDefault(False)
self.pushButton_setFocus.setObjectName("pushButton_setFocus")
self.gridLayout.addWidget(self.pushButton_setFocus, 0, 3, 1, 1)
self.pushButton_Disable = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_Disable.setFont(font)
self.pushButton_Disable.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_Disable.setAutoDefault(False)
self.pushButton_Disable.setObjectName("pushButton_Disable")
self.gridLayout.addWidget(self.pushButton_Disable, 1, 0, 1, 1)
self.pushButton_DisableCSS = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_DisableCSS.setFont(font)
self.pushButton_DisableCSS.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_DisableCSS.setAutoDefault(False)
self.pushButton_DisableCSS.setObjectName("pushButton_DisableCSS")
self.gridLayout.addWidget(self.pushButton_DisableCSS, 1, 1, 1, 1)
self.pushButton_editEnable = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_editEnable.setFont(font)
self.pushButton_editEnable.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_editEnable.setAutoDefault(False)
self.pushButton_editEnable.setObjectName("pushButton_editEnable")
self.gridLayout.addWidget(self.pushButton_editEnable, 1, 2, 1, 1)
self.lineEdit_sample = QtWidgets.QLineEdit(Dialog)
self.lineEdit_sample.setGeometry(QtCore.QRect(43, 340, 341, 31))
font = QtGui.QFont()
font.setPointSize(16)
self.lineEdit_sample.setFont(font)
self.lineEdit_sample.setFocusPolicy(QtCore.Qt.ClickFocus)
self.lineEdit_sample.setObjectName("lineEdit_sample")
self.label_display = QtWidgets.QLabel(Dialog)
self.label_display.setGeometry(QtCore.QRect(400, 340, 341, 31))
font = QtGui.QFont()
font.setPointSize(16)
self.label_display.setFont(font)
self.label_display.setText("")
self.label_display.setObjectName("label_display")
self.layoutWidget2 = QtWidgets.QWidget(Dialog)
self.layoutWidget2.setGeometry(QtCore.QRect(42, 98, 691, 35))
self.layoutWidget2.setFocusPolicy(QtCore.Qt.TabFocus)
self.layoutWidget2.setObjectName("layoutWidget2")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget2)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton_Normal = QtWidgets.QPushButton(self.layoutWidget2)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_Normal.setFont(font)
self.pushButton_Normal.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_Normal.setAutoDefault(False)
self.pushButton_Normal.setObjectName("pushButton_Normal")
self.horizontalLayout.addWidget(self.pushButton_Normal)
self.pushButton_NoEcho = QtWidgets.QPushButton(self.layoutWidget2)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_NoEcho.setFont(font)
self.pushButton_NoEcho.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_NoEcho.setAutoDefault(False)
self.pushButton_NoEcho.setObjectName("pushButton_NoEcho")
self.horizontalLayout.addWidget(self.pushButton_NoEcho)
self.pushButton_Password = QtWidgets.QPushButton(self.layoutWidget2)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_Password.setFont(font)
self.pushButton_Password.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_Password.setAutoDefault(False)
self.pushButton_Password.setObjectName("pushButton_Password")
self.horizontalLayout.addWidget(self.pushButton_Password)
self.pushButton_PasswordEchoOnEdit = QtWidgets.QPushButton(self.layoutWidget2)
font = QtGui.QFont()
font.setPointSize(16)
self.pushButton_PasswordEchoOnEdit.setFont(font)
self.pushButton_PasswordEchoOnEdit.setFocusPolicy(QtCore.Qt.TabFocus)
self.pushButton_PasswordEchoOnEdit.setAutoDefault(False)
self.pushButton_PasswordEchoOnEdit.setObjectName("pushButton_PasswordEchoOnEdit")
self.horizontalLayout.addWidget(self.pushButton_PasswordEchoOnEdit)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "LineEditTest"))
self.label_1.setText(_translate("Dialog", "モードの選択ボタンを押してください"))
self.label_3.setText(_translate("Dialog", "テキストの最大バイトは20です。[半角=1byte、全角=2byteでカウント]"))
self.label_2.setText(_translate("Dialog", "テキストの最大文字数は10です。[半角・全角どちらも1文字としてカウント]"))
self.pushButton_readOnly.setText(_translate("Dialog", "readOnly(True)"))
self.pushButton_readOnlyFalse.setText(_translate("Dialog", "readOnly(False)"))
self.pushButton_setText.setText(_translate("Dialog", "「いろは」をセット"))
self.pushButton_textShow.setText(_translate("Dialog", "入力文字を表示"))
self.pushButton_Clear.setText(_translate("Dialog", "Clear"))
self.pushButton_setFocus.setText(_translate("Dialog", "フォーカスセット"))
self.pushButton_Disable.setText(_translate("Dialog", "読み取り専用"))
self.pushButton_DisableCSS.setText(_translate("Dialog", "読み取り専用(CSS)"))
self.pushButton_editEnable.setText(_translate("Dialog", " 入力可能 "))
self.pushButton_Normal.setText(_translate("Dialog", "Normal"))
self.pushButton_NoEcho.setText(_translate("Dialog", "NoEcho"))
self.pushButton_Password.setText(_translate("Dialog", "Password"))
self.pushButton_PasswordEchoOnEdit.setText(_translate("Dialog", "PasswordEchoOnEdit"))
では、この画面のファイルをインポートするmainのpythonファイルを作成します。
ファイル名はmain_LineEditTest01.pyとしています。
後は設計通り実装するだけです。
import sys
from PyQt5.QtWidgets import QDialog, qApp, QLineEdit, QApplication
import unicodedata
from ui_LineEditTest01 import *
class MyForm(QDialog):
def __init__(self, parent=None):
super(MyForm, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.ui.lineEdit_item.setEchoMode(QLineEdit.Normal)
self.ui.lineEdit_MaxlenCount.editingFinished.connect(self.check_length)
self.ui.pushButton_Normal.clicked.connect(self.setNormal)
self.ui.pushButton_NoEcho.clicked.connect(self.setNoEcho)
self.ui.pushButton_Password.clicked.connect(self.setPassword)
self.ui.pushButton_PasswordEchoOnEdit.clicked.connect(self.setPasswordEchoOnEdit)
self.ui.pushButton_setText.clicked.connect(self.Method_setText)
self.ui.pushButton_textShow.clicked.connect(self.Method_textShow)
self.ui.pushButton_Clear.clicked.connect(self.Method_Clear)
self.ui.pushButton_Disable.clicked.connect(self.Method_Disable)
self.ui.pushButton_DisableCSS.clicked.connect(self.Method_DisableCSS)
self.ui.pushButton_editEnable.clicked.connect(self.Method_editEnable)
self.ui.pushButton_setFocus.clicked.connect(self.Method_setFocus)
self.ui.pushButton_readOnly.clicked.connect(self.Method_readOnly)
self.ui.pushButton_readOnlyFalse.clicked.connect(self.Method_readOnlyFalse)
def setNormal(self):
self.ui.lineEdit_item.setEchoMode(QLineEdit.Normal)
def setNoEcho(self):
self.ui.lineEdit_item.setEchoMode(QLineEdit.NoEcho)
def setPassword(self):
self.ui.lineEdit_item.setEchoMode(QLineEdit.Password)
def setPasswordEchoOnEdit(self):
self.ui.lineEdit_item.setEchoMode(QLineEdit.PasswordEchoOnEdit)
def check_length(self):
buf = ''
cnt_bk = 0
string = self.ui.lineEdit_MaxlenCount.text()
for x in string:
print(x)
cnt = get_east_asian_width_count(x)
cnt_bk += cnt
if cnt_bk <= 20:
buf += x
print(buf)
else:
break
self.ui.lineEdit_MaxlenCount.setText(buf)
#print(buf)
def Method_setText(self):
self.ui.lineEdit_sample.setText('いろはにほへとちりぬるを')
def Method_textShow(self):
self.ui.label_display.setText(self.ui.lineEdit_sample.text())
def Method_Clear(self):
self.ui.label_display.clear()
self.ui.lineEdit_sample.clear() #順番が大事、lineEditを後にしないと、setFocusが利かない
def Method_Disable(self):
self.ui.lineEdit_sample.setDisabled(True)
def Method_DisableCSS(self):
self.ui.lineEdit_sample.setDisabled(True)
self.ui.lineEdit_sample.setStyleSheet("background-color:white;color:black")
self.ui.pushButton_Disable.setEnabled(False) #CSS設定してしまうと以降それが有効となるためボタンを無効化
self.ui.pushButton_Disable.setStyleSheet("background-color:rgb(209, 209, 209)") #無効なのか有効なのかわかりにくいため
def Method_editEnable(self):
self.ui.lineEdit_sample.setEnabled(True)
def Method_setFocus(self):
self.ui.lineEdit_sample.setFocus()
def Method_readOnly(self):
self.ui.lineEdit_readOnly.setReadOnly(True)
def Method_readOnlyFalse(self):
self.ui.lineEdit_readOnly.setReadOnly(False)
def get_east_asian_width_count(text):
count = 0
for c in text:
if unicodedata.east_asian_width(c) in 'FWA':
count += 2
else:
count += 1
return count
if __name__=="__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())
コードの説明を少々、
プログラムは、イベント設定しその
MaxLengthは全角・半角ともに1文字とカウントします。
なので、半角は半角、全角は全角としてカウントしたい場合があるはずです。
これに関しては、ここを利用させていだだきます。
Pythonで半角1文字、全角2文字として文字数(幅)カウント
あとはラベルに表示してある通りプログラムは実行します。
##■QPushButtonクラスが提供するメソッドについて
(Qt Documentationから引用)
プッシュボタン、またはコマンドボタンは、おそらく任意のグラフィカルユーザーインターフェースで最も一般的に使用されているウィジェットです。ボタンを押して(クリックして)何らかのアクションを実行するようにコンピュータに指示したり、質問に答えたりします。一般的なボタンは、OK、適用、キャンセル、閉じる、はい、いいえ、およびヘルプです。
コマンドボタンは長方形で、通常はその動作を説明するテキストラベルを表示します。ショートカットキーは、テキスト内で希望の文字の前にアンパサンドを付けることで指定できます。例えば:
QPushButton *button = new QPushButton("&Download", this);
この例では、ショートカットはAlt + Dです。詳細はQShortcutのドキュメントを参照してください(実際のアンパサンドを表示するには、 '&&'を使用してください)。
プッシュボタンは、テキストラベルと、オプションで小さいアイコンを表示します。これらはコンストラクタを使って設定でき、後でsetText()とsetIcon()を使って変更できます。ボタンが無効になっている場合、テキストとアイコンの外観は、ボタンが「無効」に見えるようにするためにGUIスタイルに関して操作されます。
プッシュボタンは、マウス、スペースバー、またはキーボードショートカットでクリックされたときにclicked()シグナルを発します。この信号に接続してボタンの動作を実行します。プッシュボタンはまた、あまり使用されていないシグナルを提供します。例えば、press()やrelease()です。
ダイアログ内のコマンドボタンは、デフォルトでは自動デフォルトボタンです。つまり、キーボード入力フォーカスを受け取ると自動的にデフォルトのプッシュボタンになります。デフォルトボタンは、ユーザがダイアログ内でEnterキーまたはReturnキーを押すとアクティブになるプッシュボタンです。これはsetAutoDefault()で変更できます。自動デフォルトボタンは、デフォルトボタンインジケータを描画するために必要な、少し余分なスペースを予約することに注意してください。ボタンの周囲にこのスペースを置きたくない場合は、setAutoDefault(False)を呼び出します。
ボタンウィジェットは中心的な存在であるため、過去10年間で非常に多くのバリエーションに対応できるようになりました。Microsoftのスタイルガイドには、Windowsのプッシュボタンに関する10種類の状態が表示されています。テキストには、機能のすべての組み合わせを考慮に入れるとさらに数十個あることが示されています。
最も重要なモードまたは状態は次のとおりです。
- 利用可能かどうか(グレー表示、無効)
- 標準プッシュボタン、トグルプッシュボタンまたはメニューボタン。
- オンまたはオフ(プッシュボタンを切り替える場合のみ)
- デフォルトまたは通常:ダイアログのデフォルトボタンは通常、EnterキーまたはReturnキーを使用して「クリック」できます。
- 自動繰り返しかどうか
- 押されたかどうか
一般に、アプリケーションまたはダイアログウィンドウがクリックされたときにアクション([適用]、[キャンセル]、[閉じる]、[ヘルプ]など)を実行し、ウィジェットの幅が長方形の場合はプッシュボタンを使用します。テキストラベル アクションを実行するのではなくウィンドウの状態を変更する小さな、通常は正方形のボタン(QFileDialogの右上隅にあるボタンなど)は、コマンドボタンではなくツールボタンです。Qtはこれらのボタンのための特別なクラス(QToolButton)を提供します。
切り替え動作(setCheckable()を参照)またはスクロールバーの矢印のように押し下げられたときにアクティブ化信号を自動的に繰り返すボタン(setAutoRepeat()を参照)が必要な場合は、コマンドボタンはおそらく必要ないでしょう。 疑問がある場合は、ツールボタンを使用してください。
注:macOSでは、プッシュボタンの幅が50より小さくなったり、高さが30より小さくなったりすると、ボタンの角が丸から四角に変わります。 この動作を防ぐには、setMinimumSize()関数を使用してください。
コマンドボタンのバリエーションはメニューボタンです。 クリックするとオプションのメニューがポップアップ表示されるので、これらは1つのコマンドだけでなく複数のコマンドを提供します。 メソッドsetMenu()を使用してポップアップメニューをプッシュボタンに関連付けます。
他のクラスのボタンはオプションボタン(QRadioButtonを参照)とチェックボックス(QCheckBoxを参照)です。
Qtでは、QAbstractButton基本クラスはほとんどのモードと他のAPIを提供し、QPushButtonはGUIロジックを提供します。 APIの詳細についてはQAbstractButtonを参照してください。
シグナル | トピック |
clicked() | - |
clicked(bool) | - |
pressed() | - |
released() | - |
toggled(bool) | ボタンの状態が変わるたびにアクションをトリガーしたい場合は、有効 |
※checkable(True)にすることでシグナルが有効になります |
##QRadioButtonクラスが提供するメソッドについて
(Qt Documentationから引用)
QRadioButtonは、オン(checked)またはオフ(unchecked)の切り替えが可能なオプションボタンです。ラジオボタンは通常、ユーザーに「1つまたは複数」の選択肢を提示します。ラジオボタンのグループでは、一度にチェックできるラジオボタンは1つだけです。ユーザーが別のボタンを選択した場合、前に選択されていたボタンはオフになります。
ラジオボタンはデフォルトでオートエクスクルーシブです。自動排他が有効な場合、同じ親ウィジェットに属するラジオボタンは、同じ排他ボタングループの一部であるかのように動作します。同じ親ウィジェットに属するラジオボタンに複数の排他ボタングループが必要な場合は、それらをQButtonGroupに配置します。
ボタンがオンまたはオフになるたびに、toggled()シグナルを発行します。ボタンの状態が変わるたびにアクションをトリガーしたい場合は、この信号に接続してください。特定のボタンが選択されているかどうかを確認するには、isChecked()を使用します。
QPushButtonと同じように、ラジオボタンはテキストを表示し、オプションで小さいアイコンを表示します。アイコンはsetIcon()で設定されます。テキストは、コンストラクタ内またはsetText()を使用して設定できます。ショートカットキーは、テキスト内で希望の文字の前にアンパサンドを付けることで指定できます。
例えば:
QRadioButton *button = new QRadioButton("Search from the &cursor", this);
この例ではショートカットはAlt + cです。 詳細はQShortcutのドキュメントを参照してください。 実際のアンパーサンドを表示するには、 '&&'を使用してください。
重要な継承メンバ:text()、setText()、text()、setDown()、isDown()、autoRepeat()、group()、setAutoRepeat()、toggle()、pressed()、release()、clicked()、およびtoggled()。
シグナル | トピック |
clicked() | - |
clicked(bool) | - |
pressed() | - |
released() | - |
toggled(bool) | ボタンの状態が変わるたびにアクションをトリガーしたい場合は、有効 |
##QCheckBoxクラスが提供するメソッドについて
(Qt Documentationから引用)
QCheckBoxは、オン(チェックあり)またはオフ(チェックなし)にできるオプションボタンです。 チェックボックスは通常、他の機能に影響を与えずに有効または無効にできるアプリケーションの機能を表すために使用されます。 さまざまな種類の動作を実装できます。 たとえば、QButtonGroupを使用してチェックボタンを論理的にグループ化し、排他的なチェックボックスを許可することができます。 ただし、QButtonGroupは視覚的表現を提供しません。
以下の画像は、排他的チェックボックスと非排他的チェックボックスの違いをさらに示しています。
チェックボックスがチェックまたはクリアされているときはいつでも、シグナルstateChanged()を発行します。 チェックボックスの状態が変わるたびにアクションをトリガーしたい場合は、この信号に接続してください。 チェックボックスがチェックされているかどうかを問い合わせるためにisChecked()を使うことができます。
通常のチェック済み状態と未チェック状態に加えて、QCheckBoxはオプションで「変更なし」を示す3番目の状態を提供します。 チェックボックスをチェック、未チェックのオプションをユーザに与える必要があるときはいつでもこれは役に立ちます。 この3番目の状態が必要な場合は、setTristate()で有効にし、checkState()を使用して現在の切り替え状態を照会します。
QPushButtonと同じように、チェックボックスはテキストを表示し、オプションで小さいアイコンを表示します。 アイコンはsetIcon()で設定されます。 テキストは、コンストラクタ内またはsetText()を使用して設定できます。 ショートカットキーは、希望する文字の前にアンパサンドを付けることで指定できます。
例えば:
QCheckBox *checkbox = new QCheckBox("C&ase sensitive", this);
この例では、ショートカットはAlt + Aです。 詳細はQShortcutのドキュメントを参照してください。 実際のアンパーサンドを表示するには、 '&&'を使用してください。
継承された重要な機能: text(), setText(), text(), pixmap(), setPixmap(), accel(), setAccel(), isToggleButton(), setDown(), isDown(), isOn(), checkState(), autoRepeat(), isExclusiveToggle(), group(), setAutoRepeat(), toggle(), pressed(), released(), clicked(), toggled(), checkState(), そしてstateChanged()。
シグナル | トピック |
clicked() | - |
clicked(bool) | - |
pressed() | - |
released() | - |
stateChanged(int) | チェックボックスの状態が変わるたびにアクションをトリガーしたい場合は、有効 |
チェック:2 非チェック:0 | |
toggled(bool) |
###Qt Designerでボタングループ(QButtonGroup)を作成する
radioButtonの場合、以下のように並べたボタンを選択し右クリックをして「新しいボタングループ」を選択します。
「exclusive」にチェックがある場合は排他になりチェックがなければ排他ではありません。
これは、checkBox、PushButtonの場合も同じ方法でグループ化することができます。
新しく作ったボタン類を既にあるグループに追加することも可能です。
ボタン類を削除してもグループオブジェクトは残るので、いらない場合は右クリックして破棄します。
###QGroupBoxでグループを作成する
GroupBoxにボタンを配置すれば、デフォルトで排他になります。
###Qt DesignerでQRadioButtonをQPushButtonやQCheckBoxクラスに変更する
画面レイアウトしている場合に、QRadioButtonじゃなくQCheckBoxのほうがいいかなとかQPushButtonに変えたいなどがあると思います。そんな時は以下のように右クリックで簡単に変更できます。
##Button類を使ったアプリケーションを作ってみる
では設計書を見てみます。
- | ui_ButtonEtcTest01.py | main_ButtonEtcTest01.py | |||||||
division | widget | objectName | text | text point | atribute | シグナル | スロット | Input widget | Output widget |
1 | RadioButton | radio_A | Radio_A | 13 | autoExculusive(True) | toggled | dispRadio | this | label_1 |
2 | RadioButton | radio_B | Radio_B | 13 | autoExculusive(True) | toggled | dispRadio | this | label_1 |
3 | RadioButton | radio_C | Radio_C | 13 | autoExculusive(True) | toggled | dispRadio | this | label_1 |
4 | label | label_1 | Null | 13 | - | - | - | radio_A radio_B radio_C | this |
5 | GroupBox | groupBox | チェックするとボタンが有効になります | 13 | checkable(True) | clicked | dispgroup | this | checkBox_1 checkBox_2 checkBox_3 |
6 | CheckBox | checkBox_1 | 本 | 13 | enable(False) | toggled | dispcheck | this | label_2 |
7 | CheckBox | checkBox_2 | CD | 13 | enable(False) | toggled | dispcheck | this | label_2 |
8 | CheckBox | checkBox_3 | DVD | 13 | enable(False) | toggled | dispcheck | this | label_2 |
9 | label | label_2 | Null | 13 | - | - | - | checkBox_1 checkBox_2 checkBox_3 | this |
10 | PushButton | pushButton_A | Button_A | 13 | checkable(True) | toggled | dispbutton | this | label_3 |
11 | PushButton | pushButton_B | Button_B | 13 | checkable(True) | toggled | dispbutton | this | label_3 |
12 | label | label_3 | Null | 13 | - | - | - | pushButton_A pushButton_B | this |
レイアウトはこんな感じです。
上段のラジオボタンは排他にしています。
中断のチェックボックスは排他にしていませんが、グループボックスを使っています。
プッシュボタンはトグルボタンにしています。
このレイアウトをui_ButtonEtcTest01.uiとして保存します。
これをpythonに変換します。コマンドは以下です。
pyuic5 ui_ButtonEtcTest01.ui -o ui_ButtonEtcTest01.py
では、この画面のファイルをインポートするmainのpythonファイルを作成します。
ファイル名はmain_ButtonEtcTest01.pyとしています。
uiファイルとソースは以下になります。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>448</width>
<height>482</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>160</y>
<width>371</width>
<height>91</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="title">
<string>チェックするとボタンが有効になります</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>40</x>
<y>40</y>
<width>301</width>
<height>23</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="checkBox_1">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>本</string>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>CD</string>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>DVD</string>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QLabel" name="label_1">
<property name="geometry">
<rect>
<x>40</x>
<y>90</y>
<width>371</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>30</x>
<y>280</y>
<width>371</width>
<height>18</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>30</x>
<y>410</y>
<width>381</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>110</x>
<y>340</y>
<width>235</width>
<height>36</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_A">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Button_A</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_B">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Button_B</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>40</x>
<y>40</y>
<width>371</width>
<height>23</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QRadioButton" name="radio_A">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Radio_A</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radio_B">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Radio_B</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radio_C">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Radio_C</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_ButtonEtcTest01.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(448, 482)
self.groupBox = QtWidgets.QGroupBox(Dialog)
self.groupBox.setEnabled(True)
self.groupBox.setGeometry(QtCore.QRect(30, 160, 371, 91))
font = QtGui.QFont()
font.setPointSize(13)
self.groupBox.setFont(font)
self.groupBox.setCheckable(True)
self.groupBox.setChecked(False)
self.groupBox.setObjectName("groupBox")
self.layoutWidget = QtWidgets.QWidget(self.groupBox)
self.layoutWidget.setGeometry(QtCore.QRect(40, 40, 301, 23))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.checkBox_1 = QtWidgets.QCheckBox(self.layoutWidget)
self.checkBox_1.setEnabled(False)
font = QtGui.QFont()
font.setPointSize(13)
self.checkBox_1.setFont(font)
self.checkBox_1.setTristate(False)
self.checkBox_1.setObjectName("checkBox_1")
self.horizontalLayout_2.addWidget(self.checkBox_1)
self.checkBox_2 = QtWidgets.QCheckBox(self.layoutWidget)
self.checkBox_2.setEnabled(False)
font = QtGui.QFont()
font.setPointSize(13)
self.checkBox_2.setFont(font)
self.checkBox_2.setTristate(False)
self.checkBox_2.setObjectName("checkBox_2")
self.horizontalLayout_2.addWidget(self.checkBox_2)
self.checkBox_3 = QtWidgets.QCheckBox(self.layoutWidget)
self.checkBox_3.setEnabled(False)
font = QtGui.QFont()
font.setPointSize(13)
self.checkBox_3.setFont(font)
self.checkBox_3.setTristate(False)
self.checkBox_3.setObjectName("checkBox_3")
self.horizontalLayout_2.addWidget(self.checkBox_3)
self.label_1 = QtWidgets.QLabel(Dialog)
self.label_1.setGeometry(QtCore.QRect(40, 90, 371, 21))
font = QtGui.QFont()
font.setPointSize(13)
self.label_1.setFont(font)
self.label_1.setText("")
self.label_1.setObjectName("label_1")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setGeometry(QtCore.QRect(30, 280, 371, 18))
font = QtGui.QFont()
font.setPointSize(13)
self.label_2.setFont(font)
self.label_2.setText("")
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(30, 410, 381, 20))
font = QtGui.QFont()
font.setPointSize(13)
self.label_3.setFont(font)
self.label_3.setText("")
self.label_3.setObjectName("label_3")
self.layoutWidget1 = QtWidgets.QWidget(Dialog)
self.layoutWidget1.setGeometry(QtCore.QRect(110, 340, 235, 36))
font = QtGui.QFont()
font.setPointSize(13)
self.layoutWidget1.setFont(font)
self.layoutWidget1.setObjectName("layoutWidget1")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget1)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton_A = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(13)
self.pushButton_A.setFont(font)
self.pushButton_A.setCheckable(True)
self.pushButton_A.setAutoDefault(False)
self.pushButton_A.setObjectName("pushButton_A")
self.horizontalLayout.addWidget(self.pushButton_A)
self.pushButton_B = QtWidgets.QPushButton(self.layoutWidget1)
font = QtGui.QFont()
font.setPointSize(13)
self.pushButton_B.setFont(font)
self.pushButton_B.setCheckable(True)
self.pushButton_B.setAutoDefault(False)
self.pushButton_B.setObjectName("pushButton_B")
self.horizontalLayout.addWidget(self.pushButton_B)
self.layoutWidget2 = QtWidgets.QWidget(Dialog)
self.layoutWidget2.setGeometry(QtCore.QRect(40, 40, 371, 23))
self.layoutWidget2.setObjectName("layoutWidget2")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.layoutWidget2)
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.radio_A = QtWidgets.QRadioButton(self.layoutWidget2)
font = QtGui.QFont()
font.setPointSize(13)
self.radio_A.setFont(font)
self.radio_A.setObjectName("radio_A")
self.horizontalLayout_3.addWidget(self.radio_A)
self.radio_B = QtWidgets.QRadioButton(self.layoutWidget2)
font = QtGui.QFont()
font.setPointSize(13)
self.radio_B.setFont(font)
self.radio_B.setObjectName("radio_B")
self.horizontalLayout_3.addWidget(self.radio_B)
self.radio_C = QtWidgets.QRadioButton(self.layoutWidget2)
font = QtGui.QFont()
font.setPointSize(13)
self.radio_C.setFont(font)
self.radio_C.setObjectName("radio_C")
self.horizontalLayout_3.addWidget(self.radio_C)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.groupBox.setTitle(_translate("Dialog", "チェックするとボタンが有効になります"))
self.checkBox_1.setText(_translate("Dialog", "本"))
self.checkBox_2.setText(_translate("Dialog", "CD"))
self.checkBox_3.setText(_translate("Dialog", "DVD"))
self.pushButton_A.setText(_translate("Dialog", "Button_A"))
self.pushButton_B.setText(_translate("Dialog", "Button_B"))
self.radio_A.setText(_translate("Dialog", "Radio_A"))
self.radio_B.setText(_translate("Dialog", "Radio_B"))
self.radio_C.setText(_translate("Dialog", "Radio_C"))
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QDialog, QApplication, QRadioButton, QPushButton
from ui_ButtonEtcTest01 import *
class MyForm(QDialog):
def __init__(self, parent=None):
super(MyForm, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.ui.radio_A.toggled.connect(self.dispRadio)
self.ui.radio_B.toggled.connect(self.dispRadio)
self.ui.radio_C.toggled.connect(self.dispRadio)
self.ui.groupBox.clicked.connect(self.dispgroup)
self.ui.checkBox_1.toggled.connect(self.dispcheck)
self.ui.checkBox_2.toggled.connect(self.dispcheck)
self.ui.checkBox_3.toggled.connect(self.dispcheck)
self.ui.pushButton_A.toggled.connect(self.dispbutton)
self.ui.pushButton_B.toggled.connect(self.dispbutton)
self.show()
def dispRadio(self):
radiobutton = self.sender()
if radiobutton is None or not isinstance(radiobutton, QRadioButton):
return
self.ui.label_1.setText("あなたは '%s' のラジオボタンをチェックしました" % radiobutton.text())
def dispgroup(self):
if self.ui.groupBox.isChecked() == True:
self.ui.checkBox_1.setEnabled(True)
self.ui.checkBox_2.setEnabled(True)
self.ui.checkBox_3.setEnabled(True)
else:
self.ui.checkBox_1.setEnabled(False)
self.ui.checkBox_2.setEnabled(False)
self.ui.checkBox_3.setEnabled(False)
self.ui.checkBox_1.setChecked(False)
self.ui.checkBox_2.setChecked(False)
self.ui.checkBox_3.setChecked(False)
self.ui.label_2.setText('')
def dispcheck(self):
btName = [':本 ', ':CD ', ':DVD']
dispTxt = ''
if self.ui.checkBox_1.isChecked():
dispTxt = dispTxt + "{0[0]}".format(btName)
if self.ui.checkBox_2.isChecked():
dispTxt = dispTxt + "{0[1]}".format(btName)
if self.ui.checkBox_3.isChecked():
dispTxt = dispTxt + "{0[2]}".format(btName)
self.ui.label_2.setText("あなたは{}をチェックしました。" .format(dispTxt))
if not self.ui.checkBox_1.isChecked() and not self.ui.checkBox_2.isChecked() and not self.ui.checkBox_3.isChecked():
self.ui.label_2.setText("あなたは何もチェックしていません。")
def dispbutton(self):
pushbutton = self.sender()
if pushbutton is None or not isinstance(pushbutton, QPushButton):
return
self.ui.label_3.setText("あなたは '%s' のボタンをトグルしました" % pushbutton.text())
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())
実行結果は以下のようになります。
見たままなので細かい説明は省略します。
###QComboBoxのラスが提供するメソッドについて
QComboBoxのウィジェットは、結合ボタンとポップアップリストです。
QComboBoxは、画面スペースの最小量を占めるように、ユーザーにオプションのリストを提示する手段を提供します。
コンボボックスは現在の項目を表示する選択ウィジェットで、選択可能な項目のリストをポップアップすることができます。コンボボックスは編集可能な場合があり、ユーザーはリスト内の各項目を変更できます。
コンボボックスには、ピックスマップと文字列を含めることができます。InsertItem()とsetItemText()関数は、適切にオーバーロードされています。編集可能なコンボボックスには、コンボボックスの内容を変更せずに表示された文字列をクリアするための関数clearEditText()が用意されています。
現在のコンボボックスの項目が変更された場合、currentIndexChanged()とactivated()の2つのシグナルが発行されます。 currentIndexChanged()は、変更がプログラムによって行われたかユーザーの操作によって行われたかにかかわらず常に発生します。一方、active()は、変更がユーザーの操作によって発生した場合にのみ発生します。 highlight()シグナルは、ユーザーがコンボボックスポップアップリストの項目をハイライトしたときに発行されます。 3つのシグナルはすべて2つのバージョンで存在します。1つはQString引数、もう1つはint引数です。ユーザーがピックスマップを選択または強調表示すると、intシグナルのみが発行されます。編集可能なコンボボックスのテキストが変更されるたびに、editTextChanged()シグナルが発行されます。
ユーザーが編集可能なコンボボックスに新しい文字列を入力すると、ウィジェットはそれを挿入してもしなくてもよく、いくつかの場所に挿入できます。デフォルトのポリシーはInsertAtBottomですが、setInsertPolicy()を使用してこれを変更できます。
QValidatorを使って編集可能なコンボボックスへの入力を制限することは可能です。setValidator()を参照してください。デフォルトでは、どの入力も受け入れられます。
たとえば、insertItem()およびinsertItems()を使用して、コンボボックスを作成できます。項目はsetItemText()で変更できます。項目はremoveItem()で削除でき、すべての項目はclear()で削除できます。現在の項目のテキストはcurrentText()によって返され、番号付き項目のテキストはtext()によって返されます。現在の項目はsetCurrentIndex()で設定できます。コンボボックス内の項目数はcount()によって返されます。最大項目数はsetMaxCount()で設定できます。setEditableを使って編集を許可することができます()。編集可能なコンボボックスの場合は、setCompleter()を使用して自動補完を設定できます。ユーザーが複製を追加できるかどうかは、setDuplicatesEnabled()を使用して設定します。
QComboBoxはポップアップリストとそのアイテムの保存にモデル/ビューフレームワークを使います。デフォルトではQStandardItemModelはアイテムを格納し、QListViewサブクラスはポップアップリストを表示します。モデルとビューに直接(model()とview()で)アクセスできますが、QComboBoxにはアイテムデータを設定および取得するための関数(setItemData()やitemText()など)もあります。新しいモデルとビューを設定することもできます(setModel()とsetView()を使用)。コンボボックスラベルのテキストとアイコンの場合、Qt :: DisplayRoleとQt :: DecorationRoleが使われています。setSelectionMode()を使用して、view()のSelectionModeを変更することはできません。
QLineEdit、QSpinBox、QRadioButton、QButtonGroup、およびGUIデザインハンドブック:コンボボックス、ドロップダウンリストボックスも参照してください。
###QtDesignerでcomboBoxを設定してみる
QtDesignerだけでコンボボックスを設定してみます。
以下の「Dialog Without Buttons」を選択し画面を作成します。
コンボボックスとラベルを配置します。
コンボボックスを選択し、右クリックで「アイテムを編集...」を選択します。
「+」ボタンをクリックし、アイテムを追加します。
ここではA、B、Cを追加しました。
「F4」キーを押して、「シグナル/スロットエディタ」を開きます。
コンボボックスをクリックし、ラベルにドラッグすると設定画面が表示します。
ここではcurrentIndexChangedシグナルと、setTextスロットを選択します。
するとこんな感じになります。
「F3」キーを押して編集モードに戻り、プレビューしてみます。
コンボボックスを選択すると、ラベルにアイテムが表示されます。
###QComboBoxの使用例(JSONから読み込む)そしてQLineEditのValidationでアプリを作ってみる
完成形はこんな感じです。
今回は設計書はないので、動きを以下の図に示します。
入力制御はValidatorを使用して行います。
コンボボックスは以下のJSONを読み込んでアイテムを設定します。
{
"A":{
"string":"TEST",
"code":"10"
},
"B":{
"string":"BODY",
"code":"20"
},
"C":{
"string":"BALL",
"code":"30"
}
}
では、画面を作っていきます。
1.「Dialog Without Buttons」を選択し、画面を作成します。
2.コンボボックスを配置し、objectNameをcomboBoxにします。
3.コンボボックスを右クリックし、空白のアイテムを追加します。
こんな感じになっていればOKです。
※これをする理由は、コンボブックスのカレントテキストにリストの先頭が表示されるためです。
4.コンボボックスの下にlineEditを配置し、objectNameをlineEditにします。
maxLengthを2にします。
5.toolTipも設定します。「...」の部分をクリックすると編集画面が開きます。
ソースタブに「半角数字の10、20、30のみ入力可能」と入力します。
6.コンボボックスとlineEditの前にlabelを配置しそれぞれのテキストをstringとcodeにします。
7.lineEditの下にlabelを配置し、objectNameをlabel_textにします。テキストは空にしておきます。
8.Horizontal Lineで水平線を引きます。
9.その下にlabelを置き、その横にlineEditを配置し、objectNameをlineEdit_regにします。
lineEditのmaxLengthを5にし、toolTipに
「半角英数(英2数字3)
例:AA123」
と設定します。
10.作成した画面をcombo_JSON.uiとして保存します。
11.以下のコマンドで,uiを.pyに変換します
pyuic5 combo_JSON.ui -o combo_JSON.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'combo_JSON.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(443, 322)
self.comboBox = QtWidgets.QComboBox(Dialog)
self.comboBox.setGeometry(QtCore.QRect(120, 50, 191, 24))
font = QtGui.QFont()
font.setPointSize(13)
self.comboBox.setFont(font)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.setItemText(0, "")
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(50, 40, 61, 31))
font = QtGui.QFont()
font.setPointSize(13)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setGeometry(QtCore.QRect(60, 90, 61, 21))
font = QtGui.QFont()
font.setPointSize(13)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setGeometry(QtCore.QRect(120, 90, 71, 24))
font = QtGui.QFont()
font.setPointSize(13)
self.lineEdit.setFont(font)
self.lineEdit.setInputMask("")
self.lineEdit.setMaxLength(2)
self.lineEdit.setObjectName("lineEdit")
self.label_text = QtWidgets.QLabel(Dialog)
self.label_text.setGeometry(QtCore.QRect(60, 150, 331, 18))
font = QtGui.QFont()
font.setPointSize(13)
self.label_text.setFont(font)
self.label_text.setText("")
self.label_text.setObjectName("label_text")
self.line = QtWidgets.QFrame(Dialog)
self.line.setGeometry(QtCore.QRect(50, 190, 351, 20))
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.lineEdit_reg = QtWidgets.QLineEdit(Dialog)
self.lineEdit_reg.setGeometry(QtCore.QRect(140, 220, 113, 24))
self.lineEdit_reg.setWhatsThis("")
self.lineEdit_reg.setMaxLength(5)
self.lineEdit_reg.setObjectName("lineEdit_reg")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(50, 220, 75, 18))
font = QtGui.QFont()
font.setPointSize(13)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "string"))
self.label_2.setText(_translate("Dialog", "code"))
self.lineEdit.setToolTip(_translate("Dialog", "半角数字の10、20、30のみ入力可能"))
self.lineEdit_reg.setToolTip(_translate("Dialog", "半角英数(英2数字3)\n"
"例:AA123"))
self.label_3.setText(_translate("Dialog", "TextLabel"))
そして次にすることは、combo_JSON.pyをインポートするmainのファイルを作成することです。
# -*- coding: utf-8 -*-
import sys
import json
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5.QtGui import QIntValidator, QRegExpValidator
from PyQt5.QtCore import QRegExp
from combo_JSON import *
class MyForm(QDialog):
json_dict = {}
def __init__(self, parent=None):
super(MyForm, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.setcombo()
#------1から99までの数字を許可
#self.ui.lineEdit.setValidator(QIntValidator(1, 99, self))
reg_code = QRegExp("10|20|30")
vali = QRegExpValidator(reg_code, self.ui.lineEdit)
self.ui.lineEdit.setValidator(vali)
reg_ex = QRegExp("^[A-Z]{2}\\d{3}")
validator = QRegExpValidator(reg_ex, self.ui.lineEdit_reg)
self.ui.lineEdit_reg.setValidator(validator)
self.ui.comboBox.activated[str].connect(self.act_combobox)
self.ui.lineEdit.textEdited.connect(self.in_lineedit)
self.show()
def act_combobox(self, text):
global json_dict
self.ui.label_text.setText(text)
for key in json_dict:
if text == json_dict[key]["string"]:
self.ui.lineEdit.setText(json_dict[key]["code"])
def in_lineedit(self):
global json_dict
text = self.ui.lineEdit.text()
for key in json_dict:
if text == json_dict[key]["code"]:
index = self.ui.comboBox.findText(json_dict[key]["string"])
self.ui.comboBox.setCurrentIndex(index)
self.ui.label_text.setText(json_dict[key]["string"])
def setcombo(self):
global json_dict
with open('combo.json', 'r') as f:
json_dict = json.load(f)
for key in json_dict:
self.ui.comboBox.addItem(json_dict[key]['string'])
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())
入力制御でよく見るのは、入力させてからチェックして「それは違います」、「~は入力できません」とアラートで知らせるようなものですが、QtのValidatorはパターンに合わないものは入力させないという究極のものです。
初めて見ました、こんなui。感動すら覚えます。
###Validatorをもうすこし
参考例なので、そんなに詳しくは記載しません。
画面はこんな感じです。
正規表現が得意なら入力制御は無敵です。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>443</width>
<height>322</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>120</x>
<y>50</y>
<width>191</width>
<height>24</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<item>
<property name="text">
<string/>
</property>
</item>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>40</y>
<width>61</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>string</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>60</x>
<y>90</y>
<width>61</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>code</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>120</x>
<y>90</y>
<width>71</width>
<height>24</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="toolTip">
<string>半角数字の10、20、30のみ入力可能</string>
</property>
<property name="inputMask">
<string comment="DD"/>
</property>
<property name="maxLength">
<number>2</number>
</property>
</widget>
<widget class="QLabel" name="label_text">
<property name="geometry">
<rect>
<x>60</x>
<y>150</y>
<width>331</width>
<height>18</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>50</x>
<y>190</y>
<width>351</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_reg">
<property name="geometry">
<rect>
<x>140</x>
<y>220</y>
<width>113</width>
<height>24</height>
</rect>
</property>
<property name="toolTip">
<string>半角英数(英2数字3)
例:AA123</string>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="maxLength">
<number>5</number>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>50</x>
<y>220</y>
<width>75</width>
<height>18</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'Validator_test.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(650, 373)
self.widget = QtWidgets.QWidget(Dialog)
self.widget.setGeometry(QtCore.QRect(41, 32, 561, 302))
self.widget.setObjectName("widget")
self.gridLayout = QtWidgets.QGridLayout(self.widget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.label_7 = QtWidgets.QLabel(self.widget)
self.label_7.setObjectName("label_7")
self.gridLayout.addWidget(self.label_7, 6, 0, 1, 1)
self.label_10 = QtWidgets.QLabel(self.widget)
self.label_10.setObjectName("label_10")
self.gridLayout.addWidget(self.label_10, 9, 0, 1, 1)
self.label_8 = QtWidgets.QLabel(self.widget)
self.label_8.setObjectName("label_8")
self.gridLayout.addWidget(self.label_8, 7, 0, 1, 1)
self.label_5 = QtWidgets.QLabel(self.widget)
self.label_5.setObjectName("label_5")
self.gridLayout.addWidget(self.label_5, 4, 0, 1, 1)
self.label_6 = QtWidgets.QLabel(self.widget)
self.label_6.setObjectName("label_6")
self.gridLayout.addWidget(self.label_6, 5, 0, 1, 1)
self.label_4 = QtWidgets.QLabel(self.widget)
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1)
self.label_3 = QtWidgets.QLabel(self.widget)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1)
self.lineEdit_A = QtWidgets.QLineEdit(self.widget)
self.lineEdit_A.setMaxLength(12)
self.lineEdit_A.setObjectName("lineEdit_A")
self.gridLayout.addWidget(self.lineEdit_A, 0, 1, 1, 1)
self.label_9 = QtWidgets.QLabel(self.widget)
self.label_9.setObjectName("label_9")
self.gridLayout.addWidget(self.label_9, 8, 0, 1, 1)
self.lineEdit_EE = QtWidgets.QLineEdit(self.widget)
self.lineEdit_EE.setObjectName("lineEdit_EE")
self.gridLayout.addWidget(self.lineEdit_EE, 9, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 0, 2, 1, 1)
self.lineEdit_B = QtWidgets.QLineEdit(self.widget)
self.lineEdit_B.setObjectName("lineEdit_B")
self.gridLayout.addWidget(self.lineEdit_B, 1, 1, 1, 2)
self.lineEdit_C = QtWidgets.QLineEdit(self.widget)
self.lineEdit_C.setObjectName("lineEdit_C")
self.gridLayout.addWidget(self.lineEdit_C, 2, 1, 1, 2)
self.lineEdit_D = QtWidgets.QLineEdit(self.widget)
self.lineEdit_D.setObjectName("lineEdit_D")
self.gridLayout.addWidget(self.lineEdit_D, 3, 1, 1, 2)
self.lineEdit_E = QtWidgets.QLineEdit(self.widget)
self.lineEdit_E.setObjectName("lineEdit_E")
self.gridLayout.addWidget(self.lineEdit_E, 4, 1, 1, 2)
self.lineEdit_AA = QtWidgets.QLineEdit(self.widget)
self.lineEdit_AA.setObjectName("lineEdit_AA")
self.gridLayout.addWidget(self.lineEdit_AA, 5, 1, 1, 2)
self.lineEdit_BB = QtWidgets.QLineEdit(self.widget)
self.lineEdit_BB.setObjectName("lineEdit_BB")
self.gridLayout.addWidget(self.lineEdit_BB, 6, 1, 1, 2)
self.lineEdit_CC = QtWidgets.QLineEdit(self.widget)
self.lineEdit_CC.setObjectName("lineEdit_CC")
self.gridLayout.addWidget(self.lineEdit_CC, 7, 1, 1, 2)
self.lineEdit_DD = QtWidgets.QLineEdit(self.widget)
self.lineEdit_DD.setObjectName("lineEdit_DD")
self.gridLayout.addWidget(self.lineEdit_DD, 8, 1, 1, 2)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
Dialog.setTabOrder(self.lineEdit_A, self.lineEdit_B)
Dialog.setTabOrder(self.lineEdit_B, self.lineEdit_C)
Dialog.setTabOrder(self.lineEdit_C, self.lineEdit_D)
Dialog.setTabOrder(self.lineEdit_D, self.lineEdit_E)
Dialog.setTabOrder(self.lineEdit_E, self.lineEdit_AA)
Dialog.setTabOrder(self.lineEdit_AA, self.lineEdit_BB)
Dialog.setTabOrder(self.lineEdit_BB, self.lineEdit_CC)
Dialog.setTabOrder(self.lineEdit_CC, self.lineEdit_DD)
Dialog.setTabOrder(self.lineEdit_DD, self.lineEdit_EE)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label_7.setText(_translate("Dialog", "全角ひらがな"))
self.label_10.setText(_translate("Dialog", "IPアドレス"))
self.label_8.setText(_translate("Dialog", "全角カタカナ"))
self.label_5.setText(_translate("Dialog", "郵便番号"))
self.label_6.setText(_translate("Dialog", "全角(すべて)"))
self.label_4.setText(_translate("Dialog", "半角英数記号のみ"))
self.label_3.setText(_translate("Dialog", "半角英数字のみ"))
self.lineEdit_A.setToolTip(_translate("Dialog", "12桁まで入寮可能"))
self.label_9.setText(_translate("Dialog", "半角カタカナ"))
self.label_2.setText(_translate("Dialog", "半角英字のみ"))
self.label.setText(_translate("Dialog", "半角数値のみ"))
import sys
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5.QtGui import QDoubleValidator, QIntValidator, QRegExpValidator
from PyQt5.QtCore import QRegExp
from Validator_test import *
class MyForm(QDialog):
def __init__(self, parent=None):
super(MyForm, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
#self.ui.lineEdit_A.setValidator(QIntValidator(1, 999999, self))
#self.ui.lineEdit_A.setValidator(QDoubleValidator(1, 999999999999, 0, self))
reg_A = QRegExp("^[0-9]+$")
vali_A = QRegExpValidator(reg_A, self.ui.lineEdit_A)
self.ui.lineEdit_A.setValidator(vali_A)
reg_B = QRegExp("^[a-zA-Z]+$")
vali_B = QRegExpValidator(reg_B, self.ui.lineEdit_B)
self.ui.lineEdit_B.setValidator(vali_B)
reg_C = QRegExp("^[0-9a-zA-Z]+$")
vali_C = QRegExpValidator(reg_C, self.ui.lineEdit_C)
self.ui.lineEdit_C.setValidator(vali_C)
reg_D = QRegExp("^[a-zA-Z0-9!-/:-@¥[-`{-~]+$")
vali_D = QRegExpValidator(reg_D, self.ui.lineEdit_D)
self.ui.lineEdit_D.setValidator(vali_D)
reg_E = QRegExp("^\d{3}-\d{4}$")
vali_E = QRegExpValidator(reg_E, self.ui.lineEdit_E)
self.ui.lineEdit_E.setValidator(vali_E)
reg_AA = QRegExp("^[^ -~。-゚]+$")
#reg_AA = QRegExp("^[^\x00\x00-\x7F\x00。-゚]+$") #① -⑳が入力できないので却下
vali_AA = QRegExpValidator(reg_AA, self.ui.lineEdit_AA)
self.ui.lineEdit_AA.setValidator(vali_AA)
reg_BB = QRegExp("^[ぁ-ん]+$")
vali_BB = QRegExpValidator(reg_BB, self.ui.lineEdit_BB)
self.ui.lineEdit_BB.setValidator(vali_BB)
reg_CC = QRegExp("^[ァ-ヴ]+$")
vali_CC = QRegExpValidator(reg_CC, self.ui.lineEdit_CC)
self.ui.lineEdit_CC.setValidator(vali_CC)
reg_DD = QRegExp("^[ヲ-゚]+$")
vali_DD = QRegExpValidator(reg_DD, self.ui.lineEdit_DD)
self.ui.lineEdit_DD.setValidator(vali_DD)
reg_EE = QRegExp("((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))")
vali_EE = QRegExpValidator(reg_EE, self.ui.lineEdit_EE)
self.ui.lineEdit_EE.setValidator(vali_EE)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())
純粋に数値のみの場合はQDoubleValidatorでは実現できないようです、指数と少数入力が許されてしまうんですね。かといって、QIntValidatorだと6桁以上は入力できない。
やはり正規表現で行くのが良いようです。
ソースも修正しておきます。
###lineEditのタブ順を設定する
タブ順を設定する場合はQtDesignerのメニューから編集⇢タブ順を編集をクリックします。
画面に数字が現れるので順番にクリックすることで、タブ順が設定できます。
###QDialogのラスが提供するメソッドについて
(Qt Documentationから引用)
####詳細な説明
QDialogクラスはダイアログウィンドウの基本クラスです。
ダイアログウィンドウは、主に短期間の作業やユーザーとの簡単なコミュニケーションに使用されるトップレベルのウィンドウです。 QDialogsはモーダルまたはモードレスです。 QDialogsは戻り値を提供することができ、それらはデフォルトボタンを持つことができます。 QDialogsは、setSizeGripEnabled()を使って、右下隅にQSizeGripを持つこともできます。
QDialog(およびQt::Dialog型の他のウィジェット)は、親ウィジェットをQtの他のクラスとは少し異なる方法で使用します。ダイアログは常にトップレベルのウィジェットですが、親がある場合、デフォルトの位置は親のトップレベルのウィジェットの最上部の中央になります(最上位のウィジェットではない場合)。また、親のタスクバーエントリも共有します。
QDialogウィジェットの所有権を変更するには、QWidget::setParent()関数のオーバーロードを使用してください。この関数はあなたが明示的に再親ウィジェットのウィンドウフラグを設定することを可能にします。オーバーロードされた関数を使うと、ウィジェットのウィンドウシステムのプロパティを指定しているウィンドウフラグがクリアされます(特にQt::Dialogフラグがリセットされます)。
モーダルダイアログ
モーダルダイアログは、同じアプリケーション内の他の可視ウィンドウへの入力をブロックするダイアログです。ユーザーにファイル名を要求するために使用されるダイアログ、またはアプリケーション設定を設定するために使用されるダイアログは通常モーダルです。ダイアログは、アプリケーションモーダル(デフォルト)またはウィンドウモーダルにすることができます。
アプリケーションモーダルダイアログが開かれたとき、ユーザはダイアログとの対話を終了し、アプリケーション内の他のウィンドウにアクセスする前にそれを閉じる必要があります。ウィンドウモーダルダイアログは、そのダイアログに関連するウィンドウへのアクセスをブロックするだけなので、ユーザーはアプリケーション内の他のウィンドウを引き続き使用できます。
モーダルダイアログを表示する最も一般的な方法は、そのexec()関数を呼び出すことです。ユーザーがダイアログを閉じると、exec()が有用な戻り値を返します。通常、ダイアログを閉じて適切な値を返すようにするには、デフォルトボタンを接続します。 OK、accept()スロット、Cancelボタンはreject()スロットです。あるいは、AcceptedまたはRejectedでdone()スロットを呼び出すこともできます。
別の方法は、setModal(true)またはsetWindowModality()を呼び出してからshow()を呼び出すことです。 exec()とは異なり、show()は呼び出し元にすぐに制御を返します。 setModal(true)を呼び出すことは、ユーザーがダイアログと対話する機能を持っている必要がある進行状況ダイアログで特に役立ちます。長時間実行されている操作をキャンセルします。長い操作を実行するためにshow()とsetModal(true)を一緒に使用する場合は、処理中にQApplication::processEvents()を定期的に呼び出して、ユーザーがダイアログと対話できるようにする必要があります。 (QProgressDialogを参照してください。)
モードレスダイアログ
モードレスダイアログは、同じアプリケーション内の他のウィンドウとは無関係に動作するダイアログです。ワープロでダイアログを検索して置換することは、ユーザーがアプリケーションのメインウィンドウとダイアログの両方と対話できるようにするために、しばしばモードレスです。
モードレスダイアログはshow()を使用して表示されます。これは呼び出し元に制御をすぐに返します。
ダイアログを隠した後にshow()関数を呼び出すと、ダイアログは元の位置に表示されます。これは、ウィンドウマネージャが、プログラマによって明示的に配置されていないウィンドウの位置を決定するためです。ユーザーが移動したダイアログの位置を保持するには、closeEvent()ハンドラーにその位置を保存してから、ダイアログをその位置に移動してから再度表示します。
デフォルトボタン
ダイアログのデフォルトボタンは、ユーザがEnter(Return)を押したときに押されるボタンです。このボタンは、ユーザーがダイアログの設定を受け入れてダイアログを閉じたいことを示すために使用されます。 QPushButton::setDefault()、QPushButton::isDefault()およびQPushButton::autoDefault()を使用して、ダイアログのデフォルトボタンを設定および制御します。
エスケープキー
ユーザーがダイアログでEscキーを押すと、QDialog::reject()が呼び出されます。これによりウィンドウが閉じます。closeイベントは無視できません。
拡張性
拡張性は、2つの方法でダイアログを表示する機能です。最も一般的に使用されるオプションを表示する部分的なダイアログと、すべてのオプションを表示する完全なダイアログです。通常、拡張可能なダイアログは最初は部分的なダイアログとして表示されますが、[その他]トグルボタンが付いています。ユーザがMoreボタンを押すと、ダイアログは拡大されます。拡張の例はQtを使って拡張可能なダイアログを実現する方法を示しています。
戻り値(モーダルダイアログ)
モーダルダイアログは、戻り値が必要な状況でよく使用されます。ユーザーが[OK]または[キャンセル]を押したかどうかを示します。 accept()またはreject()スロットを呼び出すことでダイアログを閉じることができ、exec()は必要に応じてAcceptedまたはRejectedを返します。 exec()呼び出しはダイアログの結果を返します。ダイアログが破棄されていない場合、結果はresult()からも利用できます。
ダイアログの閉じる動作を変更するために、関数accept()、reject()、またはdone()を再実装することができます。 closeEvent()関数は、ダイアログの位置を維持するため、または標準のcloseまたはrejectの動作をオーバーライドするためにのみ再実装する必要があります。
###Qt Designerで作成した複数ウィンドウでの値渡しを試す(Dialog編)
下記の図のようにMainWindowのボタンが押されることでDialogが表示されて、lineeditに入力したテキストがOKボタンを押すことでMainWindowのlineeditに渡されるアプリを作ってみます。
設計としては以下のようになります。
ui_mainVal.py | |||||||||
division | widget | objectName | text | text point | atribute | シグナル | スロット | Input widget | Output widget |
1 | QMainWindow | MainWindow | |||||||
2 | QLine Edit | lineEdit_main | Null | 13 | enable(False) | lineEdit_sub | |||
3 | QPush Button | Button_subwin | Sub Win | 13 |
ui_subVal.py | |||||||||
division | widget | objectName | text | text point | atribute | シグナル | スロット | Input widget | Output widget |
1 | QDialog | Dialog | - | - | modal(True) | - | - | - | - |
2 | QLine Edit | lineEdit_sub | Null | 13 | - | - | - | this | lineEdit_main |
3 | QDialogButtonBox | buttonBox | OK | 13 | - | accepted | accept | - | - |
4 | キャンセル | 13 | - | rejected | reject | - | - |
main_PassValue.py | |||||||||
division | widget | objectName | text | text point | atribute | シグナル | スロット | Input widget | Output widget |
1 | QPush Button | Button_subwin | Sub Win | 13 | - | clicked | sub_dlg | - | - |
メインウィンドウのレイアウトは以下のようになります。
サブウインドウのレイアウトは以下のようにボタンボックスの各ボタンをシグナルとスロットに接続しておきます。
そしてpyuic5で.uiファイルを.pyに変換します。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<height>183</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLineEdit" name="lineEdit_main">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>40</y>
<width>291</width>
<height>24</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777213</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="Button_subwin">
<property name="geometry">
<rect>
<x>110</x>
<y>90</y>
<width>112</width>
<height>34</height>
</rect>
</property>
<property name="text">
<string>Sub Win</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>360</width>
<height>125</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>60</x>
<y>70</y>
<width>233</width>
<height>34</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_sub">
<property name="geometry">
<rect>
<x>30</x>
<y>20</y>
<width>291</width>
<height>24</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>129</x>
<y>88</y>
</hint>
<hint type="destinationlabel">
<x>23</x>
<y>64</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>250</x>
<y>81</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>61</y>
</hint>
</hints>
</connection>
</connections>
</ui>
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_mainVal.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(356, 183)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineEdit_main = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_main.setEnabled(False)
self.lineEdit_main.setGeometry(QtCore.QRect(30, 40, 291, 24))
self.lineEdit_main.setMaximumSize(QtCore.QSize(16777215, 16777213))
self.lineEdit_main.setObjectName("lineEdit_main")
self.Button_subwin = QtWidgets.QPushButton(self.centralwidget)
self.Button_subwin.setGeometry(QtCore.QRect(110, 90, 112, 34))
self.Button_subwin.setObjectName("Button_subwin")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 356, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.Button_subwin.setText(_translate("MainWindow", "Sub Win"))
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_subVal.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(360, 125)
Dialog.setModal(True)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setGeometry(QtCore.QRect(60, 70, 233, 34))
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.lineEdit_sub = QtWidgets.QLineEdit(Dialog)
self.lineEdit_sub.setGeometry(QtCore.QRect(30, 20, 291, 24))
self.lineEdit_sub.setObjectName("lineEdit_sub")
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
そしてこれらをインポートするメインをコーデングします。
import sys
from PyQt5.QtWidgets import QMainWindow, QDialog, QApplication
import ui_mainVal
import ui_subVal
class mainWin(QMainWindow):
def __init__(self, parent=None):
super(QMainWindow, self).__init__(parent)
self.ui = ui_mainVal.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Button_subwin.clicked.connect(self.sub_dlg)
self.show()
def sub_dlg(self):
dialog = SubForm()
if dialog.exec():
self.ui.lineEdit_main.setText(dialog.dlg.lineEdit_sub.text())
class SubForm(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.dlg = ui_subVal.Ui_Dialog()
self.dlg.setupUi(self)
if __name__=="__main__":
app = QApplication(sys.argv)
w = mainWin()
w.show()
sys.exit(app.exec_())
ダイアログはモーダルに設定してあるので表示したときにexec()が実行されるようです。
したがって、if dialog.exec():はTrueになります。
OKボタンにはaccept()に接続されているので、setText後ダイアログは閉じられます。
###Qt Designerで作成した複数ウィンドウでの値渡しを試す(custom signal編)
こちらは図のようにcustom signalでテキストを送ります。
ダイアログはモードレスで、メイン側が閉じられるとダイアログも閉じます。
uiはメイン側は同じものを使用します。
ダイアログは以下になります。
Closeボタンはclose()またはreject()スロットに接続しておきます。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>360</width>
<height>125</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="modal">
<bool>false</bool>
</property>
<widget class="QLineEdit" name="lineEdit_sub">
<property name="geometry">
<rect>
<x>30</x>
<y>20</y>
<width>291</width>
<height>24</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pushButton_Send">
<property name="geometry">
<rect>
<x>50</x>
<y>60</y>
<width>113</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>Send Text</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_Close">
<property name="geometry">
<rect>
<x>190</x>
<y>60</y>
<width>113</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>Close</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton_Close</sender>
<signal>clicked()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>276</x>
<y>74</y>
</hint>
<hint type="destinationlabel">
<x>338</x>
<y>68</y>
</hint>
</hints>
</connection>
</connections>
</ui>
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_subVal02.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(360, 125)
Dialog.setModal(False)
self.lineEdit_sub = QtWidgets.QLineEdit(Dialog)
self.lineEdit_sub.setGeometry(QtCore.QRect(30, 20, 291, 24))
self.lineEdit_sub.setObjectName("lineEdit_sub")
self.pushButton_Send = QtWidgets.QPushButton(Dialog)
self.pushButton_Send.setGeometry(QtCore.QRect(50, 60, 113, 32))
self.pushButton_Send.setObjectName("pushButton_Send")
self.pushButton_Close = QtWidgets.QPushButton(Dialog)
self.pushButton_Close.setGeometry(QtCore.QRect(190, 60, 113, 32))
self.pushButton_Close.setAutoDefault(False)
self.pushButton_Close.setObjectName("pushButton_Close")
self.retranslateUi(Dialog)
self.pushButton_Close.clicked.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton_Send.setText(_translate("Dialog", "Send Text"))
self.pushButton_Close.setText(_translate("Dialog", "Close"))
これらをインポートするmainは以下となります。
import sys
from PyQt5.QtWidgets import QMainWindow, QDialog, QApplication
from PyQt5 import QtCore
import ui_mainVal
import ui_subVal02
class mainWin(QMainWindow):
def __init__(self, parent=None):
super(QMainWindow, self).__init__(parent)
self.ui = ui_mainVal.Ui_MainWindow()
self.ui.setupUi(self)
self.sub_dialog = SubForm(self) #Create a dialog with a parent
self.sub_dialog.sendString.connect(self.sub_dlg)
self.ui.Button_subwin.clicked.connect(self.get_text)
self.show()
def get_text(self):
self.sub_dialog.show()
self.sub_dialog.dlg.lineEdit_sub.setText('')
def sub_dlg(self, text):
self.ui.lineEdit_main.setText(text)
class SubForm(QDialog):
sendString = QtCore.pyqtSignal(str) #Custom signal
def __init__(self, parent_win):
super().__init__(parent_win)
self.dlg = ui_subVal02.Ui_Dialog()
self.dlg.setupUi(self)
self.dlg.pushButton_Send.clicked.connect(self.send_clicked)
def send_clicked(self):
self.sendString.emit(self.dlg.lineEdit_sub.text())
if __name__=="__main__":
app = QApplication(sys.argv)
w = mainWin()
w.show()
sys.exit(app.exec_())
###Dialogのサンプルを作ってみる
QColorDialog、QInputDialog、QFontDialogを使ったサンプルを作成します。
サンプルを提示するだけなので、設計書は作っていません。
画面の仕様は図で示します。
このサンプルでは、tooBoxを使っています。
toolBoxダイアログはtabWidgetを縦に並べたようなWidgetです。
画面はこんな感じです。
実際の画面はこうなっています。
どんどん先に勧めます。
画面はui_testDialog_etc.uiです。
中にちょっとstylesheetを使った部分がありますが、これは別の機会にもっと突っ込んでやりたいと思います。
とりあえず.uiを.pyに変換します。
コマンドは以下になります。
pyuic5 ui_testDialog_etc.ui -o ui_testDialog_etc.py
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>776</width>
<height>402</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>321</width>
<height>111</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<widget class="QLabel" name="label_color">
<property name="geometry">
<rect>
<x>160</x>
<y>20</y>
<width>141</width>
<height>71</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(170, 255, 127);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QPushButton" name="button_setColor">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>121</width>
<height>34</height>
</rect>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>153</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
border:2px solid #8f8f91; border-radius:6px; min-width:80px;
background-color:rgb(153, 255, 255);
}
QPushButton:pressed {
background-color:rgb(60, 152, 255);
}
QPushButton:flat {
border: none;
}
QPushButton:default {
border-color: navy;
}</string>
</property>
<property name="text">
<string>Select Color</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QFrame" name="frame_2">
<property name="geometry">
<rect>
<x>370</x>
<y>30</y>
<width>381</width>
<height>341</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">border-width: 1px;border-color: black;border-style: solid;</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>361</width>
<height>281</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="button_font">
<property name="geometry">
<rect>
<x>130</x>
<y>300</y>
<width>112</width>
<height>31</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
border:2px solid #8f8f91; border-radius:6px; min-width:80px;
background-color:rgb(153, 255, 255);
}
QPushButton:pressed {
background-color:rgb(60, 152, 255);
}
QPushButton:flat {
border: none;
}
QPushButton:default {
border-color: navy;
}</string>
</property>
<property name="text">
<string>Adjust Font</string>
</property>
</widget>
</widget>
<widget class="QToolBox" name="toolBox">
<property name="geometry">
<rect>
<x>30</x>
<y>170</y>
<width>321</width>
<height>201</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>317</width>
<height>95</height>
</rect>
</property>
<attribute name="label">
<string>Page 1</string>
</attribute>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>50</x>
<y>0</y>
<width>231</width>
<height>86</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="text">
<string>ボタンを押して星座を入力します</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="lineEdit_AA">
<property name="enabled">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButton_AA">
<property name="text">
<string>ボタン</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="page_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>317</width>
<height>95</height>
</rect>
</property>
<attribute name="label">
<string>Page 2</string>
</attribute>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>50</x>
<y>0</y>
<width>221</width>
<height>82</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>ボタンを押して数字を入力します</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="lineEdit_BB">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButton_BB">
<property name="text">
<string>ボタン</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="page_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>317</width>
<height>95</height>
</rect>
</property>
<attribute name="label">
<string>Page 3</string>
</attribute>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>50</x>
<y>10</y>
<width>241</width>
<height>82</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>ボタンを押して動物を入力します</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="lineEdit_CC">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButton_CC">
<property name="text">
<string>ボタン</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_testDialog_etc.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(776, 402)
self.frame = QtWidgets.QFrame(Dialog)
self.frame.setGeometry(QtCore.QRect(30, 30, 321, 111))
self.frame.setStyleSheet("")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Sunken)
self.frame.setObjectName("frame")
self.label_color = QtWidgets.QLabel(self.frame)
self.label_color.setGeometry(QtCore.QRect(160, 20, 141, 71))
self.label_color.setStyleSheet("background-color: rgb(170, 255, 127);")
self.label_color.setText("")
self.label_color.setObjectName("label_color")
self.button_setColor = QtWidgets.QPushButton(self.frame)
self.button_setColor.setGeometry(QtCore.QRect(20, 20, 121, 34))
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(153, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
self.button_setColor.setPalette(palette)
self.button_setColor.setStyleSheet("QPushButton {\n"
" border:2px solid #8f8f91; border-radius:6px; min-width:80px;\n"
" background-color:rgb(153, 255, 255);\n"
"}\n"
"QPushButton:pressed {\n"
" background-color:rgb(60, 152, 255);\n"
"}\n"
"QPushButton:flat {\n"
" border: none;\n"
"}\n"
"QPushButton:default {\n"
" border-color: navy;\n"
"}")
self.button_setColor.setAutoDefault(True)
self.button_setColor.setDefault(True)
self.button_setColor.setFlat(True)
self.button_setColor.setObjectName("button_setColor")
self.frame_2 = QtWidgets.QFrame(Dialog)
self.frame_2.setGeometry(QtCore.QRect(370, 30, 381, 341))
self.frame_2.setStyleSheet("border-width: 1px;border-color: black;border-style: solid;")
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.textEdit = QtWidgets.QTextEdit(self.frame_2)
self.textEdit.setGeometry(QtCore.QRect(10, 10, 361, 281))
self.textEdit.setObjectName("textEdit")
self.button_font = QtWidgets.QPushButton(self.frame_2)
self.button_font.setGeometry(QtCore.QRect(130, 300, 112, 31))
self.button_font.setStyleSheet("QPushButton {\n"
" border:2px solid #8f8f91; border-radius:6px; min-width:80px;\n"
" background-color:rgb(153, 255, 255);\n"
"}\n"
"QPushButton:pressed {\n"
" background-color:rgb(60, 152, 255);\n"
"}\n"
"QPushButton:flat {\n"
" border: none;\n"
"}\n"
"QPushButton:default {\n"
" border-color: navy;\n"
"}")
self.button_font.setObjectName("button_font")
self.toolBox = QtWidgets.QToolBox(Dialog)
self.toolBox.setGeometry(QtCore.QRect(30, 170, 321, 201))
self.toolBox.setStyleSheet("")
self.toolBox.setFrameShape(QtWidgets.QFrame.WinPanel)
self.toolBox.setFrameShadow(QtWidgets.QFrame.Sunken)
self.toolBox.setObjectName("toolBox")
self.page = QtWidgets.QWidget()
self.page.setGeometry(QtCore.QRect(0, 0, 317, 95))
self.page.setObjectName("page")
self.layoutWidget = QtWidgets.QWidget(self.page)
self.layoutWidget.setGeometry(QtCore.QRect(50, 0, 231, 86))
self.layoutWidget.setObjectName("layoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.label = QtWidgets.QLabel(self.layoutWidget)
self.label.setFrameShape(QtWidgets.QFrame.NoFrame)
self.label.setFrameShadow(QtWidgets.QFrame.Plain)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.lineEdit_AA = QtWidgets.QLineEdit(self.layoutWidget)
self.lineEdit_AA.setEnabled(False)
self.lineEdit_AA.setStyleSheet("")
self.lineEdit_AA.setObjectName("lineEdit_AA")
self.gridLayout.addWidget(self.lineEdit_AA, 1, 0, 1, 1)
self.pushButton_AA = QtWidgets.QPushButton(self.layoutWidget)
self.pushButton_AA.setDefault(True)
self.pushButton_AA.setObjectName("pushButton_AA")
self.gridLayout.addWidget(self.pushButton_AA, 2, 0, 1, 1)
self.toolBox.addItem(self.page, "")
self.page_2 = QtWidgets.QWidget()
self.page_2.setGeometry(QtCore.QRect(0, 0, 317, 95))
self.page_2.setObjectName("page_2")
self.layoutWidget1 = QtWidgets.QWidget(self.page_2)
self.layoutWidget1.setGeometry(QtCore.QRect(50, 0, 221, 82))
self.layoutWidget1.setObjectName("layoutWidget1")
self.gridLayout_2 = QtWidgets.QGridLayout(self.layoutWidget1)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setObjectName("gridLayout_2")
self.label_2 = QtWidgets.QLabel(self.layoutWidget1)
self.label_2.setObjectName("label_2")
self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1)
self.lineEdit_BB = QtWidgets.QLineEdit(self.layoutWidget1)
self.lineEdit_BB.setEnabled(False)
self.lineEdit_BB.setObjectName("lineEdit_BB")
self.gridLayout_2.addWidget(self.lineEdit_BB, 1, 0, 1, 1)
self.pushButton_BB = QtWidgets.QPushButton(self.layoutWidget1)
self.pushButton_BB.setDefault(True)
self.pushButton_BB.setObjectName("pushButton_BB")
self.gridLayout_2.addWidget(self.pushButton_BB, 2, 0, 1, 1)
self.toolBox.addItem(self.page_2, "")
self.page_3 = QtWidgets.QWidget()
self.page_3.setGeometry(QtCore.QRect(0, 0, 317, 95))
self.page_3.setObjectName("page_3")
self.layoutWidget2 = QtWidgets.QWidget(self.page_3)
self.layoutWidget2.setGeometry(QtCore.QRect(50, 10, 241, 82))
self.layoutWidget2.setObjectName("layoutWidget2")
self.gridLayout_3 = QtWidgets.QGridLayout(self.layoutWidget2)
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
self.gridLayout_3.setObjectName("gridLayout_3")
self.label_3 = QtWidgets.QLabel(self.layoutWidget2)
self.label_3.setObjectName("label_3")
self.gridLayout_3.addWidget(self.label_3, 0, 0, 1, 1)
self.lineEdit_CC = QtWidgets.QLineEdit(self.layoutWidget2)
self.lineEdit_CC.setEnabled(False)
self.lineEdit_CC.setObjectName("lineEdit_CC")
self.gridLayout_3.addWidget(self.lineEdit_CC, 1, 0, 1, 1)
self.pushButton_CC = QtWidgets.QPushButton(self.layoutWidget2)
self.pushButton_CC.setDefault(True)
self.pushButton_CC.setObjectName("pushButton_CC")
self.gridLayout_3.addWidget(self.pushButton_CC, 2, 0, 1, 1)
self.toolBox.addItem(self.page_3, "")
self.retranslateUi(Dialog)
self.toolBox.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.button_setColor.setText(_translate("Dialog", "Select Color"))
self.button_font.setText(_translate("Dialog", "Adjust Font"))
self.label.setText(_translate("Dialog", "ボタンを押して星座を入力します"))
self.pushButton_AA.setText(_translate("Dialog", "ボタン"))
self.toolBox.setItemText(self.toolBox.indexOf(self.page), _translate("Dialog", "Page 1"))
self.label_2.setText(_translate("Dialog", "ボタンを押して数字を入力します"))
self.pushButton_BB.setText(_translate("Dialog", "ボタン"))
self.toolBox.setItemText(self.toolBox.indexOf(self.page_2), _translate("Dialog", "Page 2"))
self.label_3.setText(_translate("Dialog", "ボタンを押して動物を入力します"))
self.pushButton_CC.setText(_translate("Dialog", "ボタン"))
self.toolBox.setItemText(self.toolBox.indexOf(self.page_3), _translate("Dialog", "Page 3"))
これをインポートするmainは以下となります。
import sys
from PyQt5.QtWidgets import QDialog, QApplication, QColorDialog, QFontDialog, QInputDialog
import ui_testDialog_etc
class mainForm(QDialog):
def __init__(self, parent=None):
super(QDialog, self).__init__(parent)
self.ui = ui_testDialog_etc.Ui_Dialog()
self.ui.setupUi(self)
self.ui.toolBox.setCurrentIndex(0)
self.ui.button_setColor.clicked.connect(self.showDialog)
self.ui.button_font.clicked.connect(self.adjustfont)
self.ui.pushButton_AA.clicked.connect(self.dispmessage1)
self.ui.pushButton_BB.clicked.connect(self.dispmessage2)
self.ui.pushButton_CC.clicked.connect(self.dispmessage3)
def showDialog(self):
getcolor = QColorDialog.getColor()
if getcolor.isValid():
self.ui.label_color.setStyleSheet("QWidget { background-color: %s }" % getcolor.name())
def adjustfont(self):
font, ok = QFontDialog.getFont()
if ok:
self.ui.textEdit.setFont(font)
def dispmessage1(self):
text, ok = QInputDialog.getText(self, 'Input Dialog', 'あなたの星座は?')
if ok:
self.ui.lineEdit_AA.setText(str(text))
def dispmessage2(self):
text, ok = QInputDialog.getInt(self, 'Input Dialog', '数字を選択願います', 0, 1, 10, 1)
if ok:
self.ui.lineEdit_BB.setText(str(text))
def dispmessage3(self):
animal = ("", "犬", "猫", "さる", "キリン",
"ライオン", "トラ", "ワシ", "フラミンゴ",
"ゴリラ", "コブラ", "アルマジロ", "カワウソ")
animalName, ok = QInputDialog.getItem(self, "Input Dialog", "好きな動物は?", animal, 0, False)
if ok and animalName:
self.ui.lineEdit_CC.setText(animalName)
if __name__=="__main__":
app = QApplication(sys.argv)
w = mainForm()
w.show()
sys.exit(app.exec_())
###QDarkStyleをインストールして使ってみる
pypiにQDarkStyleなるものがアップされています。
https://pypi.org/project/QDarkStyle/
これを以下のコマンドでインストールしてみます。
pip install QDarkStyle
使い方はインポートして、宣言して、設定するという感じです。
先のコードに入れて試してみます。
import sys
from PyQt5.QtWidgets import QDialog, QApplication, QColorDialog, QFontDialog, QInputDialog
import qdarkstyle
import ui_testDialog_etc
class mainForm(QDialog):
def __init__(self, parent=None):
super(QDialog, self).__init__(parent)
self.ui = ui_testDialog_etc.Ui_Dialog()
self.ui.setupUi(self)
self.ui.toolBox.setCurrentIndex(0)
self.ui.button_setColor.clicked.connect(self.showDialog)
self.ui.button_font.clicked.connect(self.adjustfont)
self.ui.pushButton_AA.clicked.connect(self.dispmessage1)
self.ui.pushButton_BB.clicked.connect(self.dispmessage2)
self.ui.pushButton_CC.clicked.connect(self.dispmessage3)
def showDialog(self):
getcolor = QColorDialog.getColor()
if getcolor.isValid():
self.ui.label_color.setStyleSheet("QWidget { background-color: %s }" % getcolor.name())
def adjustfont(self):
font, ok = QFontDialog.getFont()
if ok:
self.ui.textEdit.setFont(font)
def dispmessage1(self):
text, ok = QInputDialog.getText(self, 'Input Dialog', 'あなたの星座は?')
if ok:
self.ui.lineEdit_AA.setText(str(text))
def dispmessage2(self):
text, ok = QInputDialog.getInt(self, 'Input Dialog', '数字を選択願います', 0, 1, 10, 1)
if ok:
self.ui.lineEdit_BB.setText(str(text))
def dispmessage3(self):
animal = ("", "犬", "猫", "さる", "キリン",
"ライオン", "トラ", "ワシ", "フラミンゴ",
"ゴリラ", "コブラ", "アルマジロ", "カワウソ")
animalName, ok = QInputDialog.getItem(self, "Input Dialog", "好きな動物は?", animal, 0, False)
if ok and animalName:
self.ui.lineEdit_CC.setText(animalName)
if __name__=="__main__":
app = QApplication(sys.argv)
dark_stylesheet = qdarkstyle.load_stylesheet_pyqt5()
app.setStyleSheet(dark_stylesheet)
w = mainForm()
w.show()
sys.exit(app.exec_())
設定しているのは以下です。
import qdarkstyle
app = QApplication(sys.argv)
dark_stylesheet = qdarkstyle.load_stylesheet_pyqt5()
app.setStyleSheet(dark_stylesheet)
画面はこんな感じです。
stylesheetをいじった部分が読みづらいですね、最初からこの設定でレイアウトしていくとかっこいいのかも知れません。
別画面で試してみました。
これが
こうなります。
ネットで調べたところ、Qt5のCSSはCSS2で3には対応していないよう、
したがってbox-shadowのようなものは無視されてしまう。
###QTableWidgetが提供するメソッドについて
(Qt Documentationから引用)
詳細な説明
QTableWidgetクラスは、デフォルトモデルを持つアイテムベースのテーブルビューを提供します。
テーブルウィジェットは、アプリケーションに標準のテーブル表示機能を提供します。 QTableWidgetの項目はQTableWidgetItemによって提供されます。
独自のデータモデルを使用するテーブルが必要な場合は、このクラスではなくQTableViewを使用してください。
テーブルウィジェットは、必要な行数と列数で構成できます。
tableWidget = new QTableWidget(12, 3, this);
あるいは、与えられたサイズを指定せずにテーブルを作成し、後でサイズを変更することもできます。
tableWidget = new QTableWidget(this);
tableWidget->setRowCount(10);
tableWidget->setColumnCount(5);
項目はテーブルの外側に(親ウィジェットなしで)作成され、setItem()を使ってテーブルに挿入されます。
QTableWidgetItem *newItem = new QTableWidgetItem(tr("%1").arg(
(row+1)*(column+1)));
tableWidget->setItem(row, column, newItem);
テーブルウィジェットでソートを有効にしたい場合は、それをアイテムで埋めた後にそうしてください。そうしないと、ソートが挿入順序を妨げる可能性があります(詳細はsetItem()を参照)。
テーブルには、水平方向と垂直方向の両方のヘッダーを指定できます。 ヘッダを作成する最も簡単な方法は、setHorizontalHeaderLabels()およびsetVerticalHeaderLabels()関数に文字列のリストを提供することです。 これらはテーブルの列と行に単純なテキストのヘッダを提供します。 通常はテーブルの外側に構築される既存のテーブル項目から、より洗練されたヘッダを作成できます。 たとえば、アイコンとテキストを揃えてテーブルアイテムを作成し、それを特定の列のヘッダーとして使用できます。
QTableWidgetItem *cubesHeaderItem = new QTableWidgetItem(tr("Cubes"));
cubesHeaderItem->setIcon(QIcon(QPixmap(":/Images/cubed.png")));
cubesHeaderItem->setTextAlignment(Qt::AlignVCenter);
テーブルの行数はrowCount()で、列数はcolumnCount()で見つけることができます。 テーブルは、clear()関数でクリアできます。
QTableWidgetItem、QTableView、およびModel / View Programmingも参照してください。
###TableWidgetでテストアプリを作ってみる
TableWidgetを使ったアプリはちまたにありふれているので、ちょっと変わったものを作ってみたい。
PCのフォントをすべて読み込み、フォント名とサンプルを並べて表示するというものを作ってみます。
画面はこんな感じです。
サイズは固定されていますが、スクロールは動きます。
これは、Designerは使っていません。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.setGeometry(0, 0, 800, 500)
self.setMinimumHeight(400)
self.setMinimumWidth(900)
self.setMaximumHeight(400)
self.setMaximumWidth(900)
# Create table
fontdata = QFontDatabase()
allFonts = fontdata.families()
self.tableWidget = QTableWidget()
self.tableWidget.setGeometry(QRect(0, 0, 800, 400))
self.tableWidget.setMinimumWidth(800)
self.tableWidget.setMaximumWidth(600)
self.tableWidget.setRowCount(len(allFonts))
self.tableWidget.setColumnCount(2)
self.tableWidget.setHorizontalHeaderLabels(["font", "image"])
self.tableWidget.horizontalHeader().setDefaultSectionSize(400)
self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.setCentralWidget(self.tableWidget)
for cnt, item in enumerate(allFonts):
self.tableWidget.setItem(cnt, 0, QTableWidgetItem(item))
font = QFont()
font.setFamily(item)
font.setPointSize(14)
tableFontitem = QTableWidgetItem("Abc123あいうアイウ")
tableFontitem.setFont(font)
self.tableWidget.setItem(cnt, 1, tableFontitem)
# table selection change
self.tableWidget.doubleClicked.connect(self.on_click)
@pyqtSlot()
def on_click(self):
print("\n")
for currentQTableWidgetItem in self.tableWidget.selectedItems():
print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
コードはフォントをQFontDatabaseから読み込み、そのフォント名でフォントを指定しています。
##comboBoxで実験
comboBoxで複数列を表示するものを、擬似的に作ってみたいと思います。
早速、画面はこれです。
コードは後で載せます。
擬似的にとはcomboBoxは複数列には対応していないようなので、表示部分の行をラベルで代替えするためです。comboBoxのテキストはそのままにして、ラベルで隠してしまいます。
レイアウトはこんな感じです。
ズレないように全部の部品をFrameに乗せています。
uiファイルは以下になります。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>644</width>
<height>175</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>90</x>
<y>60</y>
<width>431</width>
<height>41</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">border-style : solid;border-color :rgb(0, 0, 0);border-width : 1px;</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>41</height>
</rect>
</property>
<item>
<property name="text">
<string/>
</property>
</item>
<item>
<property name="text">
<string>aaa</string>
</property>
</item>
<item>
<property name="text">
<string>bbb</string>
</property>
</item>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>411</width>
<height>41</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_1">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
.pyに変換します。コマンドは以下です。
pyuic5 MultipleCombo.ui -o MultipleCombo.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'MultipleCombo.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(644, 175)
self.frame = QtWidgets.QFrame(Dialog)
self.frame.setGeometry(QtCore.QRect(90, 60, 431, 41))
self.frame.setStyleSheet("border-style : solid;border-color :rgb(0, 0, 0);border-width : 1px;")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.comboBox = QtWidgets.QComboBox(self.frame)
self.comboBox.setGeometry(QtCore.QRect(0, 0, 431, 41))
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.setItemText(0, "")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.layoutWidget = QtWidgets.QWidget(self.frame)
self.layoutWidget.setGeometry(QtCore.QRect(0, 0, 411, 41))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_1 = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(13)
self.label_1.setFont(font)
self.label_1.setStyleSheet("background-color: rgb(255, 255, 255);")
self.label_1.setText("")
self.label_1.setObjectName("label_1")
self.horizontalLayout.addWidget(self.label_1)
self.label_2 = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(13)
self.label_2.setFont(font)
self.label_2.setStyleSheet("background-color: rgb(255, 255, 255);")
self.label_2.setText("")
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.label_3 = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(13)
self.label_3.setFont(font)
self.label_3.setStyleSheet("background-color: rgb(255, 255, 255);")
self.label_3.setText("")
self.label_3.setObjectName("label_3")
self.horizontalLayout.addWidget(self.label_3)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.comboBox.setItemText(1, _translate("Dialog", "aaa"))
self.comboBox.setItemText(2, _translate("Dialog", "bbb"))
そして、インポートするメインはこちらです。
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.Qt import *
import sys
import MultipleCombo
class MyWin(QDialog):
def __init__(self, parent=None):
super(QDialog, self).__init__(parent)
self.ui = MultipleCombo.Ui_Dialog()
self.ui.setupUi(self)
tableView = QTableView()
headers = ['000', '001']
tableData0 = [
['abc', '100'],
['fff', '130'],
['jjj', '190'],
['ppp', '700'],
['yyy', '800']
]
model = MyTableModel(tableData0, headers)
self.ui.comboBox.setView(tableView)
self.ui.comboBox.setModel(model)
tableView.setModel(model)
self.ui.comboBox.view().setSelectionBehavior(QAbstractItemView.SelectRows)
self.ui.comboBox.view().setSelectionMode(QAbstractItemView.SingleSelection)
self.ui.comboBox.activated.connect(self.setComboString)
def setComboString(self):
index = self.ui.comboBox.currentIndex()
rowData = self.ui.comboBox.view().model().getData(index)
self.ui.label_1.setText('No.' + str(index + 1))
self.ui.label_2.setText(rowData[0])
self.ui.label_3.setText(rowData[1])
class MyTableModel(QAbstractTableModel):
def __init__(self, list, headers=[], parent=None):
QAbstractTableModel.__init__(self, parent)
self.list = list
self.headers = headers
def rowCount(self, parent):
return len(self.list)
def columnCount(self, parent):
return len(self.list[0])
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def data(self, index, role):
if role == Qt.EditRole:
row = index.row()
column = index.column()
return self.list[row][column]
if role == Qt.DisplayRole:
row = index.row()
column = index.column()
value = self.list[row][column]
return value
def setData(self, index, value, role = Qt.EditRole):
if role == Qt.EditRole:
row = index.row()
column = index.column()
self.list[row][column] = value
self.dataChanged.emit(index, index)
return True
return False
def getData(self, index):
return self.list[index]
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
if section < len(self.headers):
return self.headers[section]
else:
return "not implemented"
else:
return "No %d" % (section + 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = MyWin()
dialog.show()
sys.exit(app.exec_())
モデルをcomboBoxのviewに設定することで、このようなドロップダウンの形式を表示できます。
本来のcomboBoxの使用目的には合わないかもしれません。