QT5 插槽未在子类中调用

Posted

技术标签:

【中文标题】QT5 插槽未在子类中调用【英文标题】:QT5 Slot not called in subclass 【发布时间】:2014-12-09 12:50:33 【问题描述】:

我有一个超类BackgroundWorkerWithWaitDialog,它管理一个WaitDialog,它实现了一个带有“中止”按钮的进度条框。它在 QThread 中用作 QObject。

我的意图是从 BackgroundWorker 派生任何后台任务并仅实现 execute() 命令,轮询 aborted 标志以停止它。

BackgroundWorkerWithWaitDialog 派生自BackgroundWorker,它是一个 QObject,所有类都是 Q_OBJECT,并且工作类能够使用信号和槽更新 gui。这种通信(Worker 到 Gui 对象)工作正常。

问题在于,尽管 WaitDialog 响应按钮单击,但从 WaitDialog 发出 aborted() 信号但 BackGroundWorker 没有接收到。 (桂 -> 工人)

class WaitDialog : public QDialog

    Q_OBJECT

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

public slots:
    void setText(QString text);
    void setProgress(bool shown, int max);
    void enableAbort(bool enable);
    void setProgression (int level);

signals:
    void aborted();

private slots:
    void on_cmdAbort_clicked();

private:
    Ui::WaitDialog *ui;

;


void WaitDialog::on_cmdAbort_clicked()

    qDebug() << "ABORT";
    emit aborted();

...

/// BackgroundWorker is QObject-derived.
class BackgroundWorkerWithWaitDialog : public BackgroundWorker

    Q_OBJECT
public:
    explicit BackgroundWorkerWithWaitDialog(MainWindow *main, WaitDialog *dialog);
...
public slots:
    virtual void abortIssued();

....

BackgroundWorkerWithWaitDialog::BackgroundWorkerWithWaitDialog(MainWindow *main, WaitDialog *dialog)
: BackgroundWorker(main),
  mWaitDialog(dialog),
  mAborted(false)

    connect (this, SIGNAL(progress(int)), mWaitDialog, SLOT(setProgression(int)));
    connect (this, SIGNAL(messageChanged(QString)), mWaitDialog, SLOT(setText(QString)));
    connect (this, SIGNAL(progressBarVisibilityChanged(bool,int)), mWaitDialog, SLOT(setProgress(bool,int)));
    connect (this, SIGNAL(abortButtonVisibilityChanged(bool)), mWaitDialog, SLOT(enableAbort(bool)));
    connect (mWaitDialog, SIGNAL(aborted()), this, SLOT(abortIssued()));


void BackgroundWorkerWithWaitDialog::abortIssued()

    // THIS IS NEVER EXECUTED
    mAborted = true;

我有什么遗漏吗?我暂时用监听器模式修复了这个问题,但坦率地说,我不喜欢这种混合修复。

为什么不调用 abortIssued 插槽?

提前致谢。


总结一下:

BackgroundWorkerWithWaitDialog (BWWWD) 从继承自 QObject 的 BackgroundWorker 派生 BackgroundWorkerWithWaitDialog 在构造函数中接收派生自 QDialog 的 WaitDialog (WD) BWWWD 在构造函数 connect() 中使用 abortIssued() 槽传递 waitDialog aborted() 信号 WD 发出信号,但未调用 abortIssued BWWWD 在单独的 QThread 中执行

值得一提的是,BWWWD 类是由其他 SpecificWorker 类派生的,这些类实现了利用 aborted() 函数中断处理的特定函数。

【问题讨论】:

【参考方案1】:

你的问题是:

我有一个超类 BackgroundWorker,它管理一个 WaitDialog,它实现了一个带有“中止”按钮的进度条框。

BackgroundWorkerWithWaitDialog 构造函数中,不要将dialog 传递给BackgroundWorker 的构造函数,也不要在设置连接时使用BackgroundWorker 成员变量。

要么你的问题开头陈述是错误的,要么你连接到一个从未使用过的对话框。

【讨论】:

这并没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。 你说得对,我正在更正文字。我想简化上下文,但实际上我忘记更改代码中的某些名称。 BackgroundWorker 对对话框一无所知,它是用于 QThread 的通用 QObject;并且在BackgroundWorkerWithGui中正确连接了waitdialog。 @HappyCactus 所以要确认一下,您完全可以将BackgroundWorker 排除在外,它不会改变任何东西吗?如果是这种情况,请继续进行编辑。 嗯,不是 100% 肯定,但我相信 BW 类可以被排除在外。 WaitDialog 只是与 BWWWD 有关系,并且关注两者之间的信号/插槽。谢谢。 @HappyCactus 所以我会先让“BWWWD”成为一个不继承自“BW”的类,然后看看会发生什么。如果这不能解决您需要调整问题的问题,那么这是一个与继承无关的connect 问题。

以上是关于QT5 插槽未在子类中调用的主要内容,如果未能解决你的问题,请参考以下文章

子类UIButton:属性未在super.init调用时初始化

在插槽中调用 QDialog::exec 会阻塞主事件循环吗?

从 Qt5Widgets 调用 setFixedSize() 时出现未处理的异常

Qt5 信号捕获到插槽生成运行时错误“信号不存在”

尽管有 pyqtSlot 装饰器,但 Slot 被调用了两次

connect(QObject*, SIGNAL(signal()), functor) 未在 qt5 中连接