【问题标题】:Mapping a Qt base class signal to a slot in a derived class将 Qt 基类信号映射到派生类中的插槽
【发布时间】:2014-09-19 20:17:28
【问题描述】:

我遇到了 Qt 信号和插槽的问题。我只是在学习 Qt,但我有很多 C++ 经验。我从 QTreeView 派生了一个类,我想处理 columnResized 信号。该插槽从未被调用,我在“应用程序输出”中看到了这一点:

QObject::connect: No such signal TRecListingView::columnResized(int,int,int) in ../ec5/reclistingwidget.cpp:142

类声明如下所示:

class TRecListingView : public QTreeView
{
    Q_OBJECT
public:
    TRecListingView(QWidget *parent, TTopicPtr topic);
    ~TRecListingView();

private slots:
    void onColumnResized(int index, int oldsize, int newsize);

private:
    TRecListingModel *Model = 0;
};

在构造函数中我这样做:

connect(this,SIGNAL(columnResized(int,int,int)),
        this,SLOT(onColumnResized(int,int,int)));

在实现派生类之前,我早先已经完成了这项工作。然后我将信号映射到父小部件中的插槽。

我已经尝试运行 qmake 并重建项目。我也试过这个:

QTreeView *tv = this;
connect(tv,SIGNAL(columnResized(int,int,int)),
        this,SLOT(onColumnResized(int,int,int)));

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    columnResized 不是信号,而是槽,所以不能连接。

    相反,您可以连接到QHeaderView::sectionResized

    connect(this->horizontalHeader(),SIGNAL(sectionResized(int,int,int)),
            this,                    SLOT(onColumnResized(int,int,int)));
    

    【讨论】:

    • QTableView 没有 Horizo​​ntalHeader(),只有一个 header()。所以我正在处理这个:connect(this->header(),SIGNAL(sectionResized(int,int,int)), this, SLOT(onColumnResized(int,int,int)));
    【解决方案2】:

    因为它不是信号:

    来自文档:

    void QTreeView::columnResized ( int column, int oldSize, int newSize ) [protected slot]
    

    尝试重新实现它:

    #include <QTreeView>
    #include <QHeaderView>
    #include <QTimer>
    #include <QDebug>
    
    
    class TRecListingView : public QTreeView
    {
        Q_OBJECT
    public:
        TRecListingView(QWidget *parent=0):
            QTreeView(parent)
    
        {
            QTimer::singleShot(0, this, SLOT(fixHeader()));
        }
    
    
    public slots:
    
        void fixHeader()
        {
            QHeaderView *hv = new QHeaderView(Qt::Horizontal, this);
            hv->setHighlightSections(true);
            this->setHeader(hv);
            hv->show();
        }
    protected slots:
        void columnResized(int a, int b, int col)
        {
            qDebug() << "This is called";
        }
    
    public slots:
    
    };
    

    简单用法:

    TRecListingView trec;
    
    QStringList stringList;
    stringList << "#hello" << "#quit" << "#bye";
    QStringListModel *mdl = new QStringListModel(stringList);
    trec.setModel(mdl);
    trec.show();
    

    现在它可以正常工作了,当您调整标题大小时,您会看到许多 This is called 字符串。

    【讨论】:

    • 实际上你不能覆盖它,因为它不是虚拟的,但你可以连接到QHeaderView::sectionResized信号
    • @nicktook 有一种方法可以改变它。我完全重写了我的答案,现在示例有效(我在我的电脑上测试了它)。请看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 2010-11-26
    相关资源
    最近更新 更多