qt - 一个插槽的多个信号

标签 qt signals sender slot

对于我的 GUI,我希望有两对在滚动区域上下滚动的按钮。第一组按钮应该在 scrollarea1 上工作,第二组按钮应该在 scrollarea2 上工作。我放在滚动区中的小部件称为 viewport1 和 viewport2。 由于两组按钮都应该做同样的事情(向上和向下滚动),我想我会制作两个名为 scrollUp 和 scrollDown 的插槽来处理两组按钮的滚动。不幸的是,我无法完成这项工作,需要一些帮助。我尝试了以下方法:

QPushButton up;
QPushButton down;
QPushButton up2;
QPushButton down2;

connect(&up,SIGNAL(clicked()),&up,SLOT(scrollUp()));
connect(&up2,SIGNAL(clicked()),&up,SLOT(scrollUp()));
connect(&down,SIGNAL(clicked()),&down,SLOT(scrollDown()));
connect(&down2,SIGNAL(clicked()),&down,SLOT(scrollDown()));

void MainWindow::scrollDown()
{
QScrollArea area;
QWidget view;

if((QPushButton) &sender = down)
{
    area=scrollArea;
    view=viewport;
}
if((QPushButton) &sender = down2)
{
    area=scrollArea;
    view=viewport;
}
int curpos = area.verticalScrollBar()->value();
area.verticalScrollBar()->setValue(curpos+15);
int newpos = area.verticalScrollBar()->value();
QPoint topLeft = area.viewport()->rect().topLeft();
view.move(topLeft.x(),topLeft.y()-(newpos));
}

void MainWindow::scrollUp()
{
QScrollArea area;
QWidget view;

if((QPushButton) &sender = up)
{
    area=scrollArea;
    view=viewport;
}
if((QPushButton) &sender = up2)
{
    area=scrollArea2;
    view=viewport2;
}
int curpos = area.verticalScrollBar()->value();
area.verticalScrollBar()->setValue(curpos-15);
int newpos = area.verticalScrollBar()->value();
QPoint topLeft = area.viewport()->rect().topLeft();
view.move(topLeft.x(),topLeft.y()-(newpos));
}

但由于多种原因,这不起作用。我也尝试给插槽一些参数,比如:

connect(&up,SIGNAL(clicked()),&up,SLOT(scrollUp(scrollarea1,viewport1)));
connect(&up2,SIGNAL(clicked()),&up,SLOT(scrollUp(scrollarea2,viewport2)));

但还是没有成功。谁能帮帮我?

最佳答案

首先,“它不起作用”没有任何意义,如果你不说你得到了什么错误,很难帮助你。然后,几乎没有问题。

所有QObject的派生类都是不可复制的,也就是说你不能做

QWidget a;
QWidget b;
b = a; // Wrong

你应该使用指针(或者引用)。

QWidget a;
QWidget * b = new QWidget(...);
QWidget * c;
c = & a; // Ok
c = b; // Ok

那么你的connect调用是错误的:

connect(&up, SIGNAL(clicked()), &up, SLOT(scrollUp()));

第三个参数是拥有插槽的对象。 up 是一个 QPushButton,它没有 scrollUp() 插槽,它是您的 MainWindow :

connect(&up, SIGNAL(clicked()), this, SLOT(scrollUp()));

(因为在 MainWindow 的构造函数中调用了 connect this 指向当前的 MainWindow 对象)。

同样在 C++ 中,单个 = 符号表示赋值,要进行相等比较,请使用 =='。 sender` 是一个函数。

如果以正确的方式实现,您的方法应该有效:

class MainWindow: public QWidget
{
    QScrollArea * scroll1;
    QScrollArea * scroll2;
    QWidget * view1;
    QWidget * view2;
    QPushButton * up1;
    QPushButton * up2;
    QPushButton * down1;
    QPushButton * down2;

public:
    MainWindow()
    {
        // Here initialize member variables.
        ...

        connect(up1, SIGNAL(clicked()), this, SLOT(scrollUp()));
        connect(up2, SIGNAL(clicked()), this, SLOT(scrollUp()));
        connect(down1, SIGNAL(clicked()), this, SLOT(scrollDown()));
        connect(down2, SIGNAL(clicked()), this, SLOT(scrollDown()));
    }

public slots:
    void scrollDown()
    {
        QScrollArea * area;
        QWidget * view;

        if(qobject_cast<QPushButton>(sender()) == down1) {
            area = & scroll1;
            view = & view1;
        } else if(qobject_cast<QPushButton>(sender()) == down2) {
            area = & scroll2;
            view = & view2;
        } else {
            // Error.
        }

        // Now `area` and `view` point to the right widgets.
        ...
    }

    void scrollUp()
    {
        // The same as before.
    }
};

另一种方法是将实际的滚动指令提取到一个单独的函数中:

class MainWindow: public QWidget
{
    // Same variables as before
    ...

public:
    MainWindow()
    {
        // Here initialize member variables.
        ...

        connect(up1, SIGNAL(clicked()), this, SLOT(scrollUp1()));
        connect(up2, SIGNAL(clicked()), this, SLOT(scrollUp2()));
        connect(down1, SIGNAL(clicked()), this, SLOT(scrollDown1()));
        connect(down2, SIGNAL(clicked()), this, SLOT(scrollDown2()));
    }

public slots:
    void scrollDown(QScrollArea * area, QWidget * view)
    {
        // Here you scroll over `area` and `view`.
    }

    void scrollDown1()
    {
        scrollDown(scroll1, area1);
    }

    void scrollDown2()
    {
        scrollDown(scroll2, area2);
    }

    // Again, the same for `scrollUp`.
};

关于qt - 一个插槽的多个信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11328788/

相关文章:

ios - Swift : How to access one object (ie. 一个按钮)在@IBAction 集合中将发件人返回到新函数?

email - 带有grails邮件插件的电子邮件发件人

c++ - 构建libssh时在qt和cmake错误上找不到libssh的功能

qt - 将 QVariant 转换为 QStringList

c++ - 如何遍历 QStack 对象的元素?

multithreading - Perl:信号和线程。如何使用qx()杀死线程

delphi - 如何使用 SENDER 优化此代码?

c++ - Qt 客户端发送一个结构数据来 boost asio 服务器

variables - 信号与变量

c - XOPEN_SOURCE 和信号处理