1

こんにちは、非メンバー関数から ui を更新したいと思います。「this」ポインターを非メンバーとして渡す以外のヘルプは、ライブラリからのコールバックです。

以下は私のコードです:

メインウィンドウ.cpp

static void callback(QString result) 
{
ui->textBrowser->append(result);
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

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

void MainWindow::on_pushButton_clicked()
{
int a=1,b=2;
QLibrary myLib("myaddlib");
myLib.load();
add = (myadd)myLib.resolve("add_function");
add(callback, a, b);
}

したがって、私が必要とするのは、非メンバーのコールバックから UI にデータを追加できることだけです。私を助けてください。

編集:コールバックを変更することは許可されていません

コメントに基づく編集:callback別のスレッドで呼び出されるため、そこからウィジェットメソッドを呼び出すとエラーが発生します'cannot send events to objects owned by a different thread'

4

4 に答える 4

2

あなたのコメントで行く

「グローバル ポインター Ui::MainWindow *myui を作成しようとし、コンストラクターで myui を ui に割り当てましたが、次のエラーがスローされます:「別のスレッドが所有するオブジェクトにイベントを送信できません」。」

問題は、callback間違ったスレッドで呼び出されることです。ここに1つの解決策があります:

  1. 実際のメイン ウィンドウ インスタンスへのグローバル ポインターを作成し、それを と呼びましょうMainWindow *mainWinInstance;。また、メイン ウィンドウ インスタンスは、コールバックの対象となるライブラリ/スレッドよりも長く存続することに注意してください。または、メイン ウィンドウが破棄された後でも呼び出されるQPointerリスクがある場合に使用してください。callback

  2. 次のスロット メソッドを に追加しますMainWindow

    MainWindow::appendText(const QString &text) { // use const ref for efficiency
        ui->textBrowser->append(result);
    }
    
  3. キュー接続タイプを使用してcallbackそのメソッドを呼び出すように変更します。QMetaObject::invokeMethod

    static void callback(QString result) {
        bool r = QMetaObject::invokeMethod(mainWinInstance, 
                                           "appendText", 
                                           Qt::QueuedConnection,
                                           Q_ARG(QString, result));
        Q_ASSERT(r); // should only fail if there's a mistake in above code
    }
    

    使用するQt::QueuedConnectionことが重要です。メソッド呼び出しをターゲット オブジェクトの正しいスレッドのイベント キューに配置し、すぐに戻ります。次に、ターゲット スレッドのイベント ループが実際の呼び出しを行います。

于 2014-11-13T21:55:08.603 に答える
0

ここで言及されていることはどれも私にとってはうまくいきませんでした。メインウィンドウに信号を送信するパブリック関数を持つダミーの Qobject を作成することで解決しました。このダミー qobject のインスタンスを作成し、コールバック内で public 関数を呼び出します。

PS:コールバックを変更しないという制限があるため、上記の解決策があります。

于 2014-12-02T13:51:01.323 に答える
0

を使用してメイン ウィンドウを見つけることができますQApplication::topLevelWidgets()

メイン ウィンドウが見つかったら、 を使用mainWindow->findChild<QTextBrowser*>()してブラウザ ウィジェットを見つけ、必要に応じてそのコンテンツを変更します。

編集:
例:

Q_ASSERT(QApplication::topLevelWidgets() == 1);
QWidget* mainWindow = QApplication::topLevelWidgets().first();
QTextEditor* editor = mainWindow->findChild<QTextBrowser*>();
Q_ASSERT(editor != NULL);
editor->append(QLatin1String("abc"));
于 2014-11-11T14:45:21.063 に答える