2

私のGUIでは、スクロールエリアを上下にスクロールする2組のボタンが必要です。最初のボタン セットは scrollarea1 で動作し、2 番目のボタン セットは scrollarea2 で動作するはずです。スクロールエリアに配置したウィジェットは、viewport1 と viewport2 と呼ばれます。どちらのボタン セットも同じ (上下にスクロールする) 必要があるため、両方のボタン セットのスクロールを処理する scrollUp と scrollDown という 2 つのスロットを作成することにしました。残念ながら、私はこれを機能させることができず、助けが必要です。私は次のことを試しました:

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

しかし、やはり成功しません。誰でも私を助けることができますか?

4

4 に答える 4

7

まず第一に、「それは機能しません」は何の意味もありません、そしてあなたがどんなエラーを得るかを言わなければあなたを助けるのは難しいです。そして、問題はほとんどありません。

すべての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()));

3番目の引数は、スロットを持つオブジェクトです。はQPushButtonであり、スロットupはありません。次のことを行うのはMainWindowです。scrollUp()

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

connectMainWindowのコンストラクターで呼び出されるthisため、現在のMainWindowオブジェクトを指します)。

また、C ++では、シングル=サインオンは割り当てを意味します。等式比較の場合、 =='. Andsender`は関数です。

正しい方法で実装すれば、アプローチは機能するはずです。

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`.
};
于 2012-07-04T13:56:21.980 に答える
5

あなたのコードにはいくつかの間違いがあります:

  • シグナルの送信元について : QObject" sender" というメソッドではなくQObject * QObject::sender() const;、シグナルの送信元へのポインターを返すメソッドがあります。
  • QPushButton**if 条件では、 a を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) {
        // [...]
    }
    // [...]
}
于 2012-07-04T13:38:17.137 に答える
0

まず、これは疑似コードです。コンパイルされませんが、必要な情報が含まれている必要があります。

この問題は、QSignalMapper クラスを使用して最もエレガントに解決できると思います。複数の送信者からのパラメーターなしの信号を 1 つのスロットに接続できます。

ヘッダーに、次のように記述します。

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
  }
}
于 2016-06-17T05:47:42.883 に答える
0

まず第一に、スロットはそれに渡されるシグナル以外の引数を持つことはできません。Clicked には引数がないため、スロットには引数を指定できません。

scrollArea 1または2にフォーカスがあるかどうかを確認し、どちらを移動するかを決定する最も簡単な方法だと思います。

また、コードにエラーがあると思います。これはいけません:

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

これである:

if((QPushButton) &sender = down2)
{
    area=scrollArea2;
    view=viewport2;
}
于 2012-07-04T13:43:52.593 に答える