2012-07-04 31 views
1

对于我的GUI的多个信号我想有两对上下了scrollarea向上滚动的按钮。第一组按钮应该说scrollarea1工作,第二组按钮应在scrollarea2工作。我把在scrollarea窗口小部件被称为viewport1和viewport2。 因为两个都设置按钮也应该这样做(上下滚动),我想我会做两个插槽称为scrollUp和下滚,将处理滚动两个按钮组。不幸的是,我无法完成这项工作,需要一些帮助。我已经尝试了以下几种:一个时隙

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))); 

但是,再次没有成功。有谁能够帮助我?

+0

可能的复制[我可以有几个信号一个插槽?( https://stackoverflow.com/questions/24313530/can-i-have-one-slot-for-several-signals) – ymoreau

回答

5

首先,“它不工作”并不意味着什么,这是很难帮助你,如果你不说你得到了什么错误。然后,几乎没有问题。

所有的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()插槽,它是你的主窗口谁做:

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

(因为connect在主窗口的构造函数被调用this指向当前的主窗口对象)。

另外在C++中,单个=符号表示赋值,用于相等比较使用=='. And 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`. 
}; 
5

有在你的代码的几个误区:

  • 关于信号的发送者:有没有一个叫“sender”,而是一个方法QObject * QObject::sender() const;返回的信号的发送者的指针QObject
  • 在if条件:你是铸造QPushButton**QPushButton(QPushButton) &sender),你不要比较你的按钮up(2)down(2)那件事。
  • 在插槽和信号之间的连接中:scrollUpscrollDown插槽不属于QPushButton类,而是属于MainWindow类。

最后,你应该写这样的事情:

所有插槽
connect(&up, SIGNAL(clicked()), this, SLOT(scrollUp())); 
connect(&up2, SIGNAL(clicked()), this, SLOT(scrollUp())); 
connect(&down, SIGNAL(clicked()), this, SLOT(scrollDown())); 
connect(&down2, SIGNAL(clicked()), this, SLOT(scrollDown())); 

void MainVindow::scrollDown() { 
    // [...] 

    QPushButton * senderButton = qobject_cast<QPushButton *>(this->sender()); 
    // QPushButton * senderButton = (QPushButton *) this->sender(); works too 

    if (senderButton == &down) { 
     // [...] 
    } 

    if (senderButton == &down2) { 
     // [...] 
    } 

    // [...] 
} 

void MainVindow::scrollUp() { 
    // [...] 

    QPushButton * senderButton = qobject_cast<QPushButton *>(this->sender()); 
    // QPushButton * senderButton = (QPushButton *) this->sender(); works too 

    if (senderButton == &up) { 
     // [...] 
    } 

    if (senderButton == &up2) { 
     // [...] 
    } 
    // [...] 
} 
0

首先可以没有其他参数比信号手吧。 Clicked没有参数,因此槽可以没有参数。

我认为,最简单的方法来检查scrollArea 1或2是否已经集中,并从其中一个应该移动决定。

我还以为有你的代码中的错误。如果不是这样的:

if((QPushButton) &sender = down2) 
{ 
    area=scrollArea; 
    view=viewport; 
} 

是这样的:

if((QPushButton) &sender = down2) 
{ 
    area=scrollArea2; 
    view=viewport2; 
} 
0

首先,这是伪代码。它不会编译,但它应该包含必要的信息。

我相信这个问题可以使用QSignalMapper类最优雅地解决。它允许来自多个发送者的无参数信号连接到一个插槽。

在标题中写的是这样的:

class QSignalMapper; 

class MainWindow : public QMainWindow 
{ 

public: 
    void init(); 

public slots: 
    void handleScrollButtons(int id); 

private: 
enum { ScrollUp1, ScrollDown1, ScrollUp2, ScrollDown2 } // just makes it more convenient to use 

QSignalMapper *m_scrollbuttonhandler; 
} 

在源文件中,写这样的事情

#include <QSignalMapper> 

void MainWindow::init() 
{ 
    m_scrollbuttonhandler = new QSignalMapper(this); 
    m_scrollbuttonhandler->setMapping(scrollup1button, ScrollUp1); 
    m_scrollbuttonhandler->setMapping(scrolldown1button, ScrollDown1); 
    m_scrollbuttonhandler->setMapping(scrollup2button, ScrollUp2); 
    m_scrollbuttonhandler->setMapping(scrolldown2button, ScrollDown2); 
    connect(scrollup1button, SIGNAL(clicked(bool)), m_scrollbuttonhandler, SLOT(map())); 
    connect(scrolldown1button, SIGNAL(clicked(bool)), m_scrollbuttonhandler, SLOT(map())); 
    connect(scrollup2button, SIGNAL(clicked(bool)), m_scrollbuttonhandler, SLOT(map())); 
    connect(scrolldown2button, SIGNAL(clicked(bool)), m_scrollbuttonhandler, SLOT(map())); 

    connect(m_scrollbuttonhandler, SIGNAL(mapped(int)), this, SLOT(handleScrollButtons(int))); 
} 

void MainWindow::handleScrollButtons(int id) 
{ 
    switch (id) 
    { 
    case ScrollUp1: 
    // stuff to do for scrollup1button 
    case ScrollDown1: 
    // stuff to do for scrolldown1button 
    case ScrollUp2: 
    // stuff to do for scrollup2button 
    case ScrollDown2: 
    // stuff to do for scrolldown2button 
    } 
}