プロセスの実行中に、説明テキストを含むQDialogボックスを表示する方法

spaTimeCoder

概要:ボタンやメニュー選択項目に多数の機能が組み込まれているGUIベースのプログラムがあります。プロセスの多くは瞬時に実行されますが、5、10、または20秒以上かかるプロセスもあります。

現在の問題:ダイアログボックスが表示されているのに、「プロセスを完了しています。しばらくお待ちください...」などのテキストがボックス内に表示されません。

目標:長いプロセスの実行中に、[お待ちください]ダイアログボックスを表示して、プログラムが停止しておらず、ユーザーが選択した機能に取り組んでいることをユーザーに知らせたいと思います。

背景情報:GUIはPySide2(別名PyQt5)とPython3.6.5で構築されています

現在の試み:


方法1-最初に、threadingモジュールを使用して、実行する主要な機能を開始しました。関数の開始時に、ダイアログボックスを表示するための呼び出しがあります。ダイアログボックスは意図したとおりに表示され、関数の残りの部分はバックグラウンドで処理/完了します。

方法1の問題-プログラムがより複雑になり、ThreadPoolExecutorを使用して処理を高速化する必要が生じるまで、これはうまく機能しました。ThreadPoolExecutorとスレッドモジュールが一緒に機能すると、エラーメッセージなしでクラッシュするため、そのメソッドを放棄する必要がありました。


方法2 -私が使用してみましたsetModalQDialogボックスの機能をと呼ばれるexec_機能を

方法2問題-ダイアログボックスに必要なテキストが表示および表示されますが、setModal(False)は効果がなく、ウィンドウが閉じるまでプロセスが停止していました。


方法3(現在使用されている方法)-ProcessRunningダイアログウィンドウクラスの初期化で、文字列(表示するメッセージである文字列)を受け取るPySide2シグナルを作成しました。長いプロセスを呼び出す前の前の行でemit()、ダイアログボックスを表示する関数であるシグナル関数を呼び出しました

方法3問題-ウィンドウが表示され、バックグラウンドプロセスが実行されますが、プロセスのその部分がバックグラウンドプロセスによって保持されているように、ウィンドウにテキストが表示されません。


概要:質問のタイトルは、QDialogボックスを表示する方法がわからないことを示唆していますが、実際の問題は、ユーザーに「待機」するように指示するテキストをウィンドウ内に表示することです。これは私の現在の方法では起こらないので、ボックスを「正しく」表示していないように感じます。したがって、これを達成するための「正しい」方法が私が探しているものです。

これは、私の完全なプログラムにある概念を使用した「短い」例です。

import sys
import math
import PySide2
from PySide2 import QtCore, QtGui, QtWidgets
import pandas

class Ui_functionRunning(object):
    def setupUi(self, functionRunning):
        functionRunning.setObjectName("functionRunning")
        functionRunning.resize(234, 89)
        self.labelProcessStatus = QtWidgets.QLabel(functionRunning)
        self.labelProcessStatus.setGeometry(QtCore.QRect(10, 0, 221, 51))
        self.labelProcessStatus.setAlignment(QtCore.Qt.AlignCenter)
        self.labelProcessStatus.setWordWrap(True)
        self.labelProcessStatus.setObjectName("labelProcessStatus")
        self.buttonProcessCompleted = QtWidgets.QPushButton(functionRunning)
        self.buttonProcessCompleted.setEnabled(False)
        self.buttonProcessCompleted.setGeometry(QtCore.QRect(60, 60, 111, 23))
        self.buttonProcessCompleted.setObjectName("buttonProcessCompleted")

class FunctionRunning(PySide2.QtWidgets.QDialog, Ui_functionRunning):
    display_box = PySide2.QtCore.Signal(str)

    def __init__(self):
        super(FunctionRunning, self).__init__()
        self.setupUi(self)

    def showDialog(self, displayText):
        MasterClass.process_running.labelProcessStatus.setText(displayText)
        MasterClass.process_running.show()

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(335, 255, 126, 23))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        MainWindow.setStatusBar(self.statusbar)
        self.pushButton.setText("PUSH TO TEST ")

class MainWindowUI(PySide2.QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindowUI, self).__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.test_function_running)

    def test_function_running(self):
        MasterClass.process_running.display_box.emit('testing running and displaying a message')        
        df = pandas.DataFrame({'id': [0,1,2,3,4,5,6,7,8,9],'lon':[-121.28473, -121.29511, -121.32834, -121.29569, -121.29251, -121.25374, -121.28417, -121.29854, -121.21188, -121.25812], 'lat': 
            [37.986450, 37.911396, 37.969345, 37.923443, 37.990696, 37.975395, 37.942062, 37.993350, 37.979430, 37.975790]})

        `If your system processes all this too quickly to notice the problem, increase the value in 
         `this first loop, from 10 to something like 20 or 30    
        for x in range(10):
            for i in df.index:
                for r in df.index:
                    if df.loc[i, 'lat'] != '':
                        df.loc[i, 'DIST_to_%s' % df.loc[i, 'id']] = self.dist(float(df.loc[i, 'lat']), float(df.loc[i, 'lon']), float(df.loc[r, 'lat']), float(df.loc[r, 'lon']))
                print('%s pass completed - %s times through' % (i, x))
        
        print('finished calculating distances')
        MasterClass.process_running.labelProcessStatus.setText('All Done!')        

    def dist(self, lat_1, lon_1, lat_2, lon_2):
        if lat_1 != lat_2 and lon_1 != lon_2:
            val_1 = math.radians(90 - float(lat_1))
            val_2 = math.cos(val_1)
            val_3 = math.radians(90 - float(lat_2))
            val_4 = math.cos(val_3)
            val_5 = math.radians(90 - float(lat_1))
            val_6 = math.sin(val_5)
            val_7 = math.radians(90 - float(lat_2))
            val_8 = math.sin(val_7)
            val_9 = math.radians(float(lon_1) - float(lon_2))
            val_10 = math.cos(val_9)
            distance = round(math.acos(val_2 * val_4 + val_6 * val_8 * val_10) * 3958.756, 1)
            return distance
        else:
            return 0

class MasterClass:

    def __init__(self):
        super(MasterClass, self).__init__()
        MasterClass.app = PySide2.QtWidgets.QApplication(sys.argv)
        MasterClass.process_running = FunctionRunning()
        MasterClass.process_running.display_box.connect(MasterClass.process_running.showDialog)
        MasterClass.main_ui = MainWindowUI()
        MasterClass.main_ui.show()
        MasterClass.app.exec_()

if __name__ == '__main__':
    MasterClass()
NL23コード

参照する方法1は機能する可能性がありますが、いくつかの考慮事項があります。UIを更新するための呼び出しは、シグナルを使用して行う必要があります。PySide2.QtCore.Signal()

MainWindowUIクラスを次のように変更しますdist関数を保持し、変更は必要ありません)。

class MainWindowUI(PySide2.QtWidgets.QMainWindow, Ui_MainWindow):
    # Create your signal here
    initiate_function = PySide2.QtCore.Signal()

    def __init__(self):
        super(MainWindowUI, self).__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.test_function_running)

    def test_function_running(self):
        MasterClass.process_running.display_box.emit('testing running and displaying a message')

        def test():  
            df = pandas.DataFrame({'id': [0,1,2,3,4,5,6,7,8,9],'lon':[-121.28473, -121.29511, -121.32834, -121.29569, -121.29251, -121.25374, -121.28417, -121.29854, -121.21188, -121.25812], 'lat': 
                [37.986450, 37.911396, 37.969345, 37.923443, 37.990696, 37.975395, 37.942062, 37.993350, 37.979430, 37.975790]})

            for x in range(10):
                for i in df.index:
                    for r in df.index:
                        if df.loc[i, 'lat'] != '':
                            df.loc[i, 'DIST_to_%s' % df.loc[i, 'id']] = self.dist(float(df.loc[i, 'lat']), float(df.loc[i, 'lon']), float(df.loc[r, 'lat']), float(df.loc[r, 'lon']))
                    print('%s pass completed - %s times through' % (i, x))
                    # You could even update you dialog box mid-process
                    MasterClass.process_running.labelProcessStatus.setText('%s pass completed - %s times through' % (i, x))        
            
            print('finished calculating distances')
            # Below, the signal is emitted and simultaneously runs the function assigned below, in the MasterClass __init__
            MasterClass.main_ui.initiate_function.emit()
            MasterClass.process_running.labelProcessStatus.setText('All Done!')        
        
        t = threading.Thread(target=test)
        t.daemon = True
        t.start()
        
    def update_ui(self):
        print('Updating UI here')
        self.pushButton.setText('New Button Text')

次に、次のMasterClassように更新します

class MasterClass:

    def __init__(self):
        super(MasterClass, self).__init__()
        MasterClass.app = PySide2.QtWidgets.QApplication(sys.argv)
        MasterClass.process_running = FunctionRunning()
        MasterClass.process_running.display_box.connect(MasterClass.process_running.showDialog)
        MasterClass.main_ui = MainWindowUI()
        # After the MasterClass object is initialized, you can connect a function to the signal that was added to the MainWindowUI class
        MasterClass.main_ui.initiate_function.connect(MasterClass.main_ui.update_ui)
        # update_ui is the new function added above, all it does is change the text on the button, but it could be more complex if needed
        MasterClass.main_ui.show()
        MasterClass.app.exec_()

これは、PySide2でスレッドを使用する場合や、問題が発生しthreadingたり問題が発生したりする場合に役立ちThreadPoolExecutorます。したがって、ここで重要なポイントは、UIの更新など、メインスレッドでプロセスを実行する必要がある場合にシグナルを使用することです。他の用途にも使用できますが、UIを更新する必要がある場合にのみ絶対に必要です。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

実行時に生成された説明/値を含むMVC4チェックボックスリストを作成する方法

分類Dev

テキストの説明を含むファイルをアップロードする

分類Dev

角度jsが非表示のテキストボックスを含むjquerymobileに行が表示されます

分類Dev

C#ボタンが押されたときにテキスト(テキストボックスからのテキストを含む)を表示する

分類Dev

プロセスの実行中にSwiftUIのテキストを更新する

分類Dev

テキストボックスに特定のテキストを含むアイテムのみを追加する

分類Dev

リッチテキストボックスで「admin」を含むすべての行を強調表示します

分類Dev

実行中のプロセスを非表示にする方法は?

分類Dev

C#実行時以前にプロセスの説明を設定する

分類Dev

Shopifyの商品説明のテキストを非表示にする

分類Dev

プロセスのクラッシュ時に行番号を含むerror_loggerレポートを確実に取得する方法

分類Dev

そのテキストボックスのテキストを含むテキストボックスdivから作成する方法。出来ますか?

分類Dev

Pythontkinterを使用して他のフレームのテキストボックスにプロセス出力を表示する方法

分類Dev

それぞれの削除ボタンをクリックして、テキストボックスを含むテーブルの行を削除する方法

分類Dev

Winformテキストボックスのコードスニペットの説明をクリアする

分類Dev

特定のテキストを子に含む親をクリックする方法

分類Dev

ボタンをクリックしてjQueryを実行すると、キーアップイベントを含む追加テキストが消えます

分類Dev

テキストボックスに入力された文を含む結果を表示する

分類Dev

実行中のプロセスPythonのリストを表示する方法は?

分類Dev

VB.NET-「テキスト」を含むすべてのリストボックスアイテムを他のリストに分割する方法

分類Dev

matlabの作業ディレクトリを実行中のブロックを含む現在のスクリプトディレクトリに変更する

分類Dev

中括弧を含むテキストを表示する方法

分類Dev

テーブル内のセルの値を取得してテキストボックスに表示する方法

分類Dev

複数行のテキストボックスに行ごとのテキストを表示する

分類Dev

2ステッププロセスの場合にfinish()を実行する方法

分類Dev

ベースラインより下のテキストを含むプロット上のテキストの境界ボックスを計算します

分類Dev

色付きのテキストでプロットの外側に説明を追加する

分類Dev

c#-ログインテキストボックスのプロパティを非表示に設定する

分類Dev

HTML / CSS divをh1、p、pictruesを含む4つのテキストボックスに揃える方法

Related 関連記事

  1. 1

    実行時に生成された説明/値を含むMVC4チェックボックスリストを作成する方法

  2. 2

    テキストの説明を含むファイルをアップロードする

  3. 3

    角度jsが非表示のテキストボックスを含むjquerymobileに行が表示されます

  4. 4

    C#ボタンが押されたときにテキスト(テキストボックスからのテキストを含む)を表示する

  5. 5

    プロセスの実行中にSwiftUIのテキストを更新する

  6. 6

    テキストボックスに特定のテキストを含むアイテムのみを追加する

  7. 7

    リッチテキストボックスで「admin」を含むすべての行を強調表示します

  8. 8

    実行中のプロセスを非表示にする方法は?

  9. 9

    C#実行時以前にプロセスの説明を設定する

  10. 10

    Shopifyの商品説明のテキストを非表示にする

  11. 11

    プロセスのクラッシュ時に行番号を含むerror_loggerレポートを確実に取得する方法

  12. 12

    そのテキストボックスのテキストを含むテキストボックスdivから作成する方法。出来ますか?

  13. 13

    Pythontkinterを使用して他のフレームのテキストボックスにプロセス出力を表示する方法

  14. 14

    それぞれの削除ボタンをクリックして、テキストボックスを含むテーブルの行を削除する方法

  15. 15

    Winformテキストボックスのコードスニペットの説明をクリアする

  16. 16

    特定のテキストを子に含む親をクリックする方法

  17. 17

    ボタンをクリックしてjQueryを実行すると、キーアップイベントを含む追加テキストが消えます

  18. 18

    テキストボックスに入力された文を含む結果を表示する

  19. 19

    実行中のプロセスPythonのリストを表示する方法は?

  20. 20

    VB.NET-「テキスト」を含むすべてのリストボックスアイテムを他のリストに分割する方法

  21. 21

    matlabの作業ディレクトリを実行中のブロックを含む現在のスクリプトディレクトリに変更する

  22. 22

    中括弧を含むテキストを表示する方法

  23. 23

    テーブル内のセルの値を取得してテキストボックスに表示する方法

  24. 24

    複数行のテキストボックスに行ごとのテキストを表示する

  25. 25

    2ステッププロセスの場合にfinish()を実行する方法

  26. 26

    ベースラインより下のテキストを含むプロット上のテキストの境界ボックスを計算します

  27. 27

    色付きのテキストでプロットの外側に説明を追加する

  28. 28

    c#-ログインテキストボックスのプロパティを非表示に設定する

  29. 29

    HTML / CSS divをh1、p、pictruesを含む4つのテキストボックスに揃える方法

ホットタグ

アーカイブ