【问题标题】:How can I connect a signal to QWidget::update slot?如何将信号连接到 QWidget::update 插槽?
【发布时间】:2019-02-07 14:13:52
【问题描述】:

我正在使用具有新信号/插槽语法的 Qt5。
我不知道为什么下面的代码不起作用:

QWidget *widget = new QWidget();
connect(pipeline, &Pipeline::NewFrame, widget, &QWidget::update);

我得到错误: no matching member function for call to 'connect'为什么?

Pipeline 类继承自 QObject 和 NewFrame 信号与 QWidget::update 具有相同的签名

class Pipeline
  : public QObject
{
    Q_OBJECT
    Q_DISABLE_COPY(Pipeline)
public:
    Pipeline(QObject *parent);

signals:
    void NewFrame();
};

我在带有 g++ 的 Arch Linux 上使用 QtCreator。

【问题讨论】:

    标签: qt


    【解决方案1】:

    TL;DR:管道应该发出图像信号,小部件应该有一个SetImage 方法:

    class Pipeline : public QObject {
      Q_OBJECT // important
    public:
      Q_SIGNAL void NewFrame(const QImage &);
      ...
    };
    
    class Viewer : public QWidget {
      Q_OBJECT // important
      QImage m_image;
    public:
      Q_SLOT void SetImage(const QImage &image) {
        m_image = image;
        update();
      }
      ...
    };
    

    这就是您使用它的方式 - 请注意,ViewerPipeline 一无所知,因为它不应该:它只是显示新帧,无论它们来自哪里。

    int main(int argc, char *argv[]) {
      QApplication app(argc, argv);
      Pipeline pipeline;
      Viewer viewer;
      QObject::connect(&pipeline, &Pipeline::NewFrame, &viewer, &Viewer::SetImage);
      return app.exec();
    }
    

    将任何东西直接连接到QWidget::update,尤其是从外部来源,通常是设计不佳的标志。

    为了满足您的好奇心,您可以使用 lambda 或 qOverload 来指定您要连接的内容,以修复您所看到的错误 - 由方法指针类型的歧义引起。以下任何一项都可以:

    connect(…, widget, qOverload<>(&QWidget::update));
    

    auto constexpr update = qOverload<>(&QWidget::update));
    connect(…, widget, update);
    

    connect(…, widget, [widget]{ widget->update(); });
    

    【讨论】:

    • 这是一个糟糕的设计,不仅因为重构,还因为YourWidget::paintEvent 无法访问它应该使用的图像,并且直接使用它,比如Pipeline::getImage() const 方法不是只有紧耦合,但不能跨线程使用,或者如果getImage 很昂贵(除了绘画本身应该在paintEvent 中完成之外没有任何昂贵的)等等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    相关资源
    最近更新 更多