4

相互に通信するウィジェットが必要です。

私の中央のウィジェットには 2つウィジェットwidget AインスタンスがありA()ます。次に、この処理済みデータを に渡す必要があります。これは、からこのデータを受け取ると、このデータを使用して関数を呼び出し、処理し、さらに何かを行います。widget BB()widget AmouseReleasewidget Awidget Bwidget A

これらのウィジェットは両方とも、 から派生したカスタム ウィジェットQWidgetです。シグナルとスロットを使用する必要があることはほぼ確実ですが、関数呼び出し部分の実装方法がわかりません。

ここで Qt の説明を何度も読みました: http://qt-project.org/wiki/Signals_and_Slots_in_PySideしかし、データを処理して送信する 2 つのウィジェットを接続する方法がわかりません。

ここで助けていただければ幸いです。Python で答えられないのに C++ の能力がある場合は、まったく控えるのではなく、それを使用して説明してください。

4

4 に答える 4

12

PyQt4 の 2 つのウィジェット間のシグナル/スロット接続を示す例を次に示します。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from PyQt4 import QtCore, QtGui

class widgetB(QtGui.QWidget):
    procDone = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(widgetB, self).__init__(parent)

        self.lineEdit = QtGui.QLineEdit(self)
        self.button = QtGui.QPushButton("Send Message to A", self)
        self.layout = QtGui.QHBoxLayout(self)
        self.layout.addWidget(self.lineEdit)
        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.on_button_clicked)

    @QtCore.pyqtSlot()
    def on_button_clicked(self):
        self.procDone.emit(self.lineEdit.text())

    @QtCore.pyqtSlot(str)
    def on_procStart(self, message):
        self.lineEdit.setText("From A: " + message)

        self.raise_()

class widgetA(QtGui.QWidget):
    procStart = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(widgetA, self).__init__(parent)

        self.lineEdit = QtGui.QLineEdit(self)
        self.lineEdit.setText("Hello!")

        self.button = QtGui.QPushButton("Send Message to B", self)
        self.button.clicked.connect(self.on_button_clicked)

        self.layout = QtGui.QHBoxLayout(self)
        self.layout.addWidget(self.lineEdit)
        self.layout.addWidget(self.button)

    @QtCore.pyqtSlot()
    def on_button_clicked(self):
        self.procStart.emit(self.lineEdit.text())

    @QtCore.pyqtSlot(str)
    def on_widgetB_procDone(self, message):
        self.lineEdit.setText("From B: " + message)

        self.raise_()


class mainwindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(mainwindow, self).__init__(parent)

        self.button = QtGui.QPushButton("Click Me", self)
        self.button.clicked.connect(self.on_button_clicked)

        self.setCentralWidget(self.button)

        self.widgetA = widgetA()
        self.widgetB = widgetB()

        self.widgetA.procStart.connect(self.widgetB.on_procStart)
        self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)

    @QtCore.pyqtSlot()
    def on_button_clicked(self):
        self.widgetA.show()
        self.widgetB.show()

        self.widgetA.raise_()


if __name__ == "__main__":
    import sys

    app  = QtGui.QApplication(sys.argv)
    main = mainwindow()
    main.show()
    sys.exit(app.exec_())
于 2012-12-30T15:07:39.167 に答える
3

ここでは 2 つの異なるアプローチを使用できると思います。ABクラスを密結合にするか、メイン ウィンドウをメディエーターとして使用します。

最初のケースでは、「知らせる」必要がありますA。これは、 への参照があるBことを意味します。この場合、シグナルとスロットをまったく実行する必要さえありませんが、のメソッドを直接呼び出すだけです。ABB

もう 1 つの方法は、が受信するデータを含む引数Aを指定してシグナルを発行することです。メイン ウィンドウはこのシグナルをキャッチし、データを呼び出します。または、データをの属性に入れ、シグナルの引数として渡さずに、メインウィンドウにここから直接データを取得させることもできます。BBA

A後者の方法を使用するとB、もう少し自由に記述できるため、 のA呼び出し方法を知る必要がありませんB

コードで説明すると、次のようになります。

class A(QWidget):
    the_signal = Signal(...)
    def mouseReleaseEvent(self, event):
        self.a_function()
        self.the_data = self.produce_data()
        self.the_signal.emit()

class B(QWidget):
    def process_data(self, data):
        pass

class MainWindow(QMainWindow):
    def __init__(self):
        self.a_widget = A()
        self.b_widget = B()
        self.a_widget.the_signal.connect(self.do_process)
        # if the signal has the data as argument:
        # self.a_widget.the_signal.connect(self.b_widget.process_data)
    def do_process(self):
        self.b_widget.process_data(self.a_widget.the_data)
于 2012-12-30T15:05:20.037 に答える
1

いくつかの方法を使用して実行できますが、最も簡単な方法 (最も賢い方法ではありません) は、オブジェクト A からメインウィンドウ、メインウィンドウから B への中間接続を作成することです。

メインウィンドウ.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "classa.h"
#include "classb.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    classA *a;
    classB *b;

signals:
    void TosignalA();
    void TosignalB();

public slots:
    void emitB();

private slots:
    void on_pushButton_clicked();
};

#endif // MAINWINDOW_H

メインウィンドウ.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    a = new classA(this);
    b=new classB(this);
    connect(this,SIGNAL(TosignalA()),this->a,SLOT(emitsig()));
    connect(this->a,SIGNAL(signal()),this,SLOT(emitB()));
    connect(this,SIGNAL(TosignalB()),this->b,SLOT(on_signal()));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::emitB()
{
    emit TosignalB();
}

void MainWindow::on_pushButton_clicked()
{
    emit TosignalA();
}

classa.h

#ifndef CLASSA_H
#define CLASSA_H

#include <QObject>

class classA : public QObject
{
    Q_OBJECT
public:
    explicit classA(QObject *parent = 0);

signals:
    void signal();

public slots:
    void emitsig();

};

#endif // CLASSA_H

classa.cpp

#include "classa.h"

classA::classA(QObject *parent) :
    QObject(parent)
{

}

void classA::emitsig()
{
    emit signal();
}

classb.h

#ifndef CLASSB_H
#define CLASSB_H

#include <QObject>
#include <QtGui>

class classB : public QObject
{
    Q_OBJECT
public:
    explicit classB(QObject *parent = 0);

signals:

public slots:
    void on_signal();

};

#endif // CLASSB_H

classb.cpp

#include "classb.h"

classB::classB(QObject *parent) :
    QObject(parent)
{
}
void classB::on_signal()
{
    QMessageBox *msgBox = new QMessageBox();
     msgBox->setText("signal emitted!");
     msgBox->exec();
}
于 2012-12-30T15:09:43.143 に答える