вызывать различные классы окон в главное окно в PQt5 - python - PullRequest
0 голосов
/ 07 августа 2020

У меня есть функциональный код, запускающий 2 процедуры и отображающий 2 windows отдельно. каждая процедура генерирует собственное окно. Я хочу выбрать процедуру, которая будет отображаться или и то, и другое в главном окне. 2 варианта представляют интерес. Я попытался определить окно, в котором я мог бы вызывать каждый элемент, но поскольку создание отдельного windows (Mainwindow_1 и 2) принадлежит классу, уже определяющему окно, я не знаю, как продолжить отображение только одного окна в время при нажатии на соответствующий пункт.

import logging
log = logging.getLogger(__name__)
log.addHandler(logging.NullHandler())
import sys
import random
import datetime
from datetime import datetime as dt, timedelta
import time
from time import sleep
import pandas as pd
from pymeasure.log import console_log
from pymeasure.display.Qt import QtGui
from PyQt5.QtWidgets import *

# import GUItest


from pymeasure.display.windows import ManagedWindow
from pymeasure.experiment import Procedure, Results
from pymeasure.experiment import IntegerParameter, FloatParameter, Parameter, ListParameter

class RandomProcedure_1(Procedure):

    iterations = IntegerParameter('Loop Iterations', default=10)
    delay = FloatParameter('Delay Time', units='s', default=0.2)
    seed = Parameter('Random Seed', default='10')
    mode = IntegerParameter('Measurement mode : must be 2 or 4 probes', default=2)
    # instruments = ListParameter('procedure to run ', ('RandomProcedure_1', 'RandomProcedure_2'), default='RandomProcedure_1')  # devices under test

    DATA_COLUMNS = ['Mode', 'Iteration', 'Timecode', 'Elapsed', 'Random Number']

    def startup(self):
        log.info("Setting the time of the random number generator")
        random.seed(self.seed)

    def execute(self):
        log.info("Starting the loop of %d iterations" % self.iterations)
        start = datetime.datetime.now()
        for i in range(self.iterations):
            timecode = dt.now()
            elapsed = (datetime.datetime.now() - start).total_seconds()
            data = {
                'Mode': self.mode,
                'Iteration': i,
                'Timecode': timecode,
                'Elapsed': elapsed,
                # 'instruments': self.instruments,
                'Random Number': random.randint(1, 50)
            }
            self.emit('results', data)
            log.debug("Emitting results: %s" % data)
            sleep(self.delay)
            if self.should_stop():
                log.warning("Caught the stop flag in the procedure")
                break

class RandomProcedure_2(Procedure):

    iterations = IntegerParameter('Loop Iterations', default=15)
    delay = FloatParameter('Delay Time', units='s', default=0.1)
    seed = Parameter('Random Seed', default='40')
    mode = IntegerParameter('Measurement mode : must be 2 or 4 probes', default=2)
    # instruments = ListParameter('procedure to run ', ('RandomProcedure_1', 'RandomProcedure_2'), default='RandomProcedure_1')  # devices under test

    DATA_COLUMNS = ['Mode', 'Iteration', 'Timecode', 'Elapsed', 'Random Number']

    def startup(self):
        log.info("Setting the time of the random number generator")
        random.seed(self.seed)

    def execute(self):
        log.info("Starting the loop of %d iterations" % self.iterations)
        start = datetime.datetime.now()
        for i in range(self.iterations):
            timecode = dt.now()
            elapsed = (datetime.datetime.now() - start).total_seconds()
            data = {
                'Mode': self.mode,
                'Iteration': i,
                'Timecode': timecode,
                'Elapsed': elapsed,
                # 'instruments': self.instruments,
                'Random Number': random.randint(1, 100)
            }
            self.emit('results', data)
            log.debug("Emitting results: %s" % data)
            sleep(self.delay)
            if self.should_stop():
                log.warning("Caught the stop flag in the procedure")
                break

class MainWindow_1(ManagedWindow):

    def __init__(self):
            super(MainWindow_1, self).__init__(
                procedure_class=RandomProcedure_1,
                inputs=['mode', 'iterations', 'delay'],
                displays=['mode', 'iterations', 'delay'],
                x_axis='Iteration',
                y_axis='Random Number',
                # sequencer=True,  # Added line
                # sequencer_inputs=['iterations', 'delay', 'seed', 'mode'],  # Added line
                # # inputs_in_scrollarea=True
                # sequence_file="gui_sequencer_example_sequence.txt",  # Added line, optional
            )
            self.setWindowTitle('RandomProcedure_1')
            self.count = 0

    def queue(self, *, procedure=None):
        self.count = self.count + 1
        if procedure is None:
            procedure = self.make_procedure()
        filename = '.\\test\\experiment_1\\' + str(dt.now().strftime("%m%d%Y")) + '_' + 'mode_' + str(self.count) + '.csv'  # working directory
        log.info("Constructing the Results with a data file: %s" % filename)
        results = Results(procedure, filename)
        experiment = self.new_experiment(results)
        self.manager.queue(experiment)

class MainWindow_2(ManagedWindow):

    def __init__(self):

        super(MainWindow_2, self).__init__(
            procedure_class=RandomProcedure_2,
            inputs=['mode', 'iterations', 'delay'],
            displays=['mode', 'iterations', 'delay'],
            x_axis='Iteration',
            y_axis='Random Number',
            # sequencer=True,  # Added line
            # sequencer_inputs=['iterations', 'delay', 'seed', 'mode'],  # Added line
            # # inputs_in_scrollarea=True
            # sequence_file="gui_sequencer_example_sequence.txt",  # Added line, optional
        )
        self.setWindowTitle('RandomProcedure_2')
        self.count = 0

    def queue(self, *, procedure=None):
        self.count = self.count + 1
        if procedure is None:
            procedure = self.make_procedure()
        filename = '.\\test\\experiment_2\\' + str(dt.now().strftime("%m%d%Y")) + '_' + 'mode_' + str(self.count) + '.csv'  # working directory
        log.info("Constructing the Results with a data file: %s" % filename)
        results = Results(procedure, filename)
        experiment = self.new_experiment(results)
        self.manager.queue(experiment)

# in this window i would like to call only one procedure upon choosing the name on the list or have both displayed in one window
# as it is only one window 2 appears and i cannot trigger the queue experiemnts
class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QGridLayout()
        self.setLayout(layout)
        self.listwidget = QListWidget()
        self.listwidget.insertItem(0, "RandomProcedure_1")
        self.listwidget.clicked.connect(self.MainWindow_1)
        self.listwidget.insertItem(1, "RandomProcedure_2")
        self.listwidget.clicked.connect(self.MainWindow_2)
        layout.addWidget(self.listwidget)
    #
    def MainWindow_1(self):
        window_1 = MainWindow_1()
        window_1.show()
        window_1.exec_()

    def MainWindow_2(self):
        window_1 = MainWindow_2()
        window_1.show()
        window_1.exec_()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    # window_1 = MainWindow_1()
    # window_2 = MainWindow_2()
    # window_1.show()
    # window_2.show()
    screen = Window()
    screen.show()
    sys.exit(app.exec_())

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Проблема в том, что вы подключили к clicked две функции, поэтому, как только вы нажмете любой элемент, будет выполнена первая подключенная функция (MainWindow_1()), а вторая не запустится до тех пор, пока не будет запущена первая. возвращается (после того, как его exec_ возвращается по очереди).

Вы должны подключиться к одному слоту и дифференцировать согласно параметру сигнала. Поскольку вы используете QListWidget, вы можете использовать itemClicked(), который возвращает QListWidgetItem, который был нажат, тогда вы можете запустить соответствующее окно / процедуру соответственно.

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QGridLayout()
        self.setLayout(layout)
        self.listwidget = QListWidget()
        self.procedureItem1 = QListWidgetItem('RandomProcedure_1')
        self.listwidget.addItem(self.procedureItem1)
        self.procedureItem1 = QListWidgetItem('RandomProcedure_2')
        self.listwidget.addItem(self.procedureItem2)
        self.listwidget.itemClicked.connect(self.startProcedure)
        layout.addWidget(self.listwidget)

    def startProcedure(self, item):
        if item == self.procedureItem1:
            window = MainWindow_1()
        elif item == self.procedureItem2:
            window = MainWindow_2()
        else:
            return
        window.show()
        window.exec_()

Примечание. Я не смог проверить приведенный выше код на вашем примере, поскольку вы не предоставили минимальный воспроизводимый пример , что означает, что вы всегда должны включать весь требуемый код, но стараться сохранить ваш пример максимально минимален. В вашем случае вы используете импортированные классы, о которых мы ничего не знаем, но в любом случае они совершенно не нужны для области вашего вопроса.

0 голосов
/ 07 августа 2020

Используйте void QListWidget::itemClicked(QListWidgetItem *item) В документации указано, что:

этот сигнал испускается с указанным элементом, когда кнопка мыши нажимается на элемент в виджете.

И именно этого вы ожидаете именно от своего кода. Не используйте две функции в одном методе.

Документация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...