【问题标题】:QProgressBar connect progress between classes - "no matching function for call"QProgressBar 连接类之间的进度 - “呼叫没有匹配功能”
【发布时间】:2017-09-04 11:51:48
【问题描述】:

在我进行一些计算的一个类和另一个包含带有我的进度条的 GUI 的类之间,我在正确设置信号和插槽方面遇到了一些麻烦。我对 qt 的经验很少,所以我对信号/插槽的工作方式感觉不太好。我尝试了一些手册和教程,但我仍然不知道如何设置它。

我们调用进度条类mainwindow

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow: public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow*ui;
};

#endif // LOADING_H

mainwindow.cpp

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

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->progressBar->setValue(0);
    calc sender;
    connect(&sender, SIGNAL( inprogress(int) ), ui->progressBar, SLOT( setValue(int) ) );
}


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

void MainWindow::on_pushButton_clicked()
{
    calc clc;
    clc.doData();
}

计算类发出信号,简称为短calc

calc.h

#ifndef CALC_H
#define CALC_H

#include <QObject>

class calc : public QObject
{
Q_OBJECT
public:
    calc(QObject *parent=0);
    void doData();
    void printResults(int t);
signals:
    void inprogress(int progr);

};

#endif // CALC_H

calc.cpp

#include "calc.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

int t = 0;
int t_end = 100;
int progr = 0;

void calc::printResults(int t)
{
    progr = t;
    emit inprogress(progr);
    QCoreApplication::processEvents(); //Prevent GUI freeze.
}

void calc::doData()
{
    for ( int i = 1; i <= t_end; i++ )
    {
        t++;
        printResults(t);
        qDebug()<<t;
    }
}

calc::calc(QObject *parent)
{

}

Archiev 部分(上面的代码已编辑) 编译以这个错误结束: 没有匹配函数调用'loading::connect(calc*, const char*, QProgressBar*&, const char*) 我是否以正确的方式使用信号,或者我误解了这个概念? >在此计算期间更新进度条值的正确方法是什么?

编辑: 将代码编辑得更清楚,现在它显示当前问题 - 信号有效,但对 qprogressbar 没有影响。

EDIT2: 现在可以工作了 - 函数必须调用 sender-&gt;doData()。另外正确的分配是sender = new calc(this)calc *sender 添加到 mainwidnow.h 的私有部分)。谢谢大家的帮助,特别是@eyllanesc 指出正确的方法!

【问题讨论】:

  • calc 必须是基于 QObject 的。正确的方法是 class calc : public QObject { Q_Object public: calc(QObject *prnt) : QObject(prtn) {....} ..... 你创建了你的 calc 但你没有创建它。因此,当您超出构造函数范围时,您的计算示例将被销毁
  • 什么时候调用doData函数?
  • 当用户按下进度条下的按钮时调用,看:void MainWindow::on_pushButton_clicked()

标签: c++ qt qt-signals qprogressbar qt-slot


【解决方案1】:

只有继承自QObject 的类才能有信号,此外它们必须有宏Q_OBJECT,因为这通过MOC 为信号和槽之间的连接创建了所有必要的元类。在你的情况下:

*.h

class calc: public QObject
{
Q_OBJECT
    public:
        calc(QObject *parent=0);
        void signalProgress();
    signals:
        void inprogress();

};

*.cpp

[...]

calc::calc(QObject *parent): QObject(parent)
{

}

还可以通过指针创建一个 calc 实例,因为垃圾收集器会在您使用构造函数后删除该数据。

*.h

private:
    Ui::loading *ui;
    calc *sender;

*.cpp

loading::loading(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::loading)
{
    ui->setupUi(this);
    ui->progressBar->setValue(0);
    sender = new calc(this);
    connect(sender, SIGNAL( inprogress(int) ), ui->progressBar, SLOT( setValue(int) ) );
}

【讨论】:

  • 评论不适用于扩展讨论或调试会话;这个对话是moved to chat。如果您有后续问题或想要分享更多代码,请编辑问题。如果对此答案有什么需要澄清的地方,请编辑它。
  • 感谢您的建议,问题已用完整代码编辑。
【解决方案2】:

您需要使用基于 QObject 的类来建立连接

在您的 calc 头文件中,您必须从 QObject 继承,然后添加 Q_OBJECT

计算.h

class calc : pubilc QObject
{
   Q_OBJECT
public:
    calc();
    void signalProgress();
signals:
    void inprogress(int progr);

};

有大量使用 Qt 信号和插槽的示例和文档,您可以开始阅读 here

附言

QProgressBar 也是基于对象的类,所以这里已经实现了相同的逻辑。

【讨论】:

  • 感谢您的回答,但正如我在之前的回答中所说(这是迟到的,我不知道为什么)在此更改后编译,但emit 对进度条没有影响。它始终保持默认值。我在不同的配置中做了一些测试,似乎它只有在以特定方式执行时才有效。看看之前讨论中的这个例子:gist.github.com/eyllanesc/b2e2d63ea8bfe1b4e6e580f9ba0eddbc 但是如果你将emitconnect(timer, &amp;QTimer::timeout, [this]{ signalProgress();progr++;qDebug()&lt;&lt;progr;}); 移动到例如其他功能,它就会停止工作。
  • 我将代码编辑得更具体,现在更清楚我需要以哪种方式调用emit
猜你喜欢
  • 2014-12-08
  • 2021-01-11
  • 1970-01-01
  • 2020-07-07
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
相关资源
最近更新 更多