首页 > 解决方案 > QMetaObject::invokeMethod 的槽参数

问题描述

玩的QMetaObject::invokeMethod方法:

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

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

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

void MainWindow::setText( int value)
{
    QString s = QString::number(value);
    ui->textEdit->setText(s);
}





void MainWindow::on_pushButton_clicked()
{
    QGenericArgument genericArg =  Q_ARG(int, 321);
    bool inv = QMetaObject::invokeMethod( this,"setText",Qt::BlockingQueuedConnection, genericArg);
    qDebug("inv = %d\n", inv);
}

QMetaObject::invokeMethod返回假。

我不确定 slot "setText"。我从函数名称中获取它,我想它可能是相关的。我在哪里可以找到插槽列表?我应该创建特殊插槽"setText"吗?

也许这与我从同一个线程运行它的事实有关?

升级版:

我添加了公共插槽而不是公共方法:

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    //void setText( int value);


private slots:
    void on_pushButton_clicked();

public slots:
void setText(int value);

private:
    Ui::MainWindow *ui;
};

这有帮助,但为什么我的setText价值是 0 呢?

标签: c++qt

解决方案


您的按钮事件由拥有 MainWindow 对象的事件循环处理,并且该对象还包含您希望调用的方法 (setText())。这意味着在您的情况下,调用者和被调用者(或信号和插槽)位于同一个线程上,并且您不能使用Qt::BlockingQueuedConnection!引用手册:使用这种连接类型在同一线程中的对象之间进行通信会导致死锁。

如果您打算在setText()方法完成后在on_pushButton_clicked()中进行处理,请改用Qt::DirectConnection,然后您的setText()将被调用,就好像它是一个简单的函数一样,并且控制权返回到您单击的setText()完成后的()函数。

如果您打算在处理setText()函数开始之前完成on_pushButton_clicked()中的所有代码的处理,请使用Qt::QueuedConnection

如果您希望 setText() 与 on_pushButton_clicked() 并行执行则将setText ( )方法移动到另一个对象(由另一个线程拥有)。只有在这种情况下Qt::BlockingQueuedConnection才有意义。


推荐阅读