[SOLVED] Change QStackedLayout Index with QPushButton not QComboBox



  • Bismillahirrahmanirrahim.

    Can I change my QStackedWidget (it contains 3 different frames) content by using only QPushButton? I have tried internal examples in Qt Documentation but all of them use QComboBox only. It seems that changing what frame shown on QStackedWidget is always done by int, and I can't do it with my clicked() SLOT. How to do QStackedWidget content changing by QPushButton?

    My code while I want if I click D button then index 1 of QStackWidget appear:

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    Dialog::Dialog()
    {
    QVBoxLayout *mainlayout = new QVBoxLayout;
    QVBoxLayout *layouta = new QVBoxLayout;
    QVBoxLayout *layoutb = new QVBoxLayout;
    QPushButton *tombola = new QPushButton("A");
    QPushButton *tombolb = new QPushButton("B");
    QPushButton *tombolc = new QPushButton("C");
    QFrame *framea = new QFrame;
    QFrame *frameb = new QFrame;
    QStackedLayout *stackia = new QStackedLayout;

    layouta->addWidget(tombola);
    layoutb->addWidget(tombolb);
    
    framea->setLayout(layouta);
    frameb->setLayout(layoutb);
    framea->setMinimumSize(88,88);
    frameb->setMinimumSize(88,88);
    
    //building frame
    framea->setFrameShape(QFrame::StyledPanel);
    framea->setFrameShadow(QFrame::Raised);
    frameb->setFrameShape(QFrame::StyledPanel);
    frameb->setFrameShadow(QFrame::Raised);
    
    //get c button smaller
    tombolc->setMaximumWidth(33);
    
    stackia->addWidget(framea);
    stackia->addWidget(frameb);
    stackia->addWidget(tombolc);
    
    mainlayout->addLayout(stackia);
    QPushButton     *tombold    =   new QPushButton("D");
    mainlayout->addWidget(tombold);
    setLayout(mainlayout);
    
    connect(tombold, SIGNAL(clicked()), stackia, SLOT(setCurrentIndex(1)));
    

    }@

    When I compile that code, Qt Creator says:

    Object::connect: No such slot QStackedLayout::setCurrentIndex(1)



    • Define a slot function
    • connect clicked() signal to this slot
    • in this slot call the setCurrentIndex()

  • Lifetime Qt Champion

    Hi,

    There is also "QSignalMapper":http://qt-project.org/doc/qt-4.8/qsignalmapper.html



  • I have done that too, this is my code for connect:

    @connect(tombold, SIGNAL(clicked()), stackia, SLOT(change_stack()));@

    and this code for the function:

    @void Dialog::change_stack()
    {
    stackia->setCurrentIndex(1);
    }@

    but Qt Creator says:

    bq. Object::connect: No such slot QStackedLayout::change_stack()

    And the result my QStackedLayout is still not changing when the button clicked. What is my mistake?


  • Lifetime Qt Champion

    This
    @connect(tombold, SIGNAL(clicked()), stackia, SLOT(change_stack()));@

    is wrong. The change_stack method belongs to your Dialog class not stackia



  • Thank you. Oukay, I have done it too. This is the code:

    @connect(tombold, SIGNAL(clicked()), this, SLOT(change_stack()));@

    but the result is always:

    bq. The program has unexpectedly finished.

    with the window closed when I click the D button, no stack changing. Strange for me, surely. What is my mistake?

    If I change the receiver name unto Dialog like this:

    @connect(tombold, SIGNAL(clicked()), Dialog, SLOT(change_stack()));@

    then Qt Creator says:

    bq. error: expected primary-expression before ',' token

    What is my mistake?



  • -the program crashes because you do not have tombold either declared or is a unreferenced pointer... add tombold = new QPushButton("asd"); and it should work-

    you should add tombold to your header file just to be sure


  • Lifetime Qt Champion

    Dialog is the class name, not the instance, replace it by "this"

    Are you sure you initialized all your pointers ?



  • [quote author="b1gsnak3" date="1374820506"]-the program crashes because you do not have tombold either declared or is a unreferenced pointer... add tombold = new QPushButton("asd"); and it should work-

    you should add tombold to your header file just to be sure[/quote]

    Thank you. I have added it before I ask here. This is the code:

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QtGui>

    class Dialog : public QDialog
    {
    Q_OBJECT

    public:
    Dialog();
    QVBoxLayout *mainlayout;
    QVBoxLayout *layouta;
    QVBoxLayout *layoutb;
    QPushButton *tombola;
    QPushButton *tombolb;
    QPushButton *tombolc;
    QPushButton *tombold;
    QFrame *framea;
    QFrame *frameb;
    QStackedLayout *stackia;

    public slots:
    void change_stack();

    private:

    };

    #endif // MAINWINDOW_H@

    [quote author="SGaist" date="1374826305"]Dialog is the class name, not the instance, replace it by "this"

    Are you sure you initialized all your pointers ?[/quote]

    Thank you. Oukay, my first code was using this. But fails. Then my code above shows us that I have done pointers initializing. Now, maybe a mistake on my header? What is my mistake? Thank you, all.


  • Lifetime Qt Champion

    @
    QVBoxLayout *mainlayout = new QVBoxLayout;
    QVBoxLayout *layouta = new QVBoxLayout;
    QVBoxLayout *layoutb = new QVBoxLayout;
    QPushButton *tombola = new QPushButton("A");
    QPushButton *tombolb = new QPushButton("B");
    QPushButton *tombolc = new QPushButton("C");
    QFrame *framea = new QFrame;
    QFrame *frameb = new QFrame;
    QStackedLayout *stackia = new QStackedLayout;
    @

    You are shadowing all your class members, that's the problem



  • Thank you. Umm, but what is shadowing? And what I should do to fix it?


  • Lifetime Qt Champion

    @
    class Foo {
    public:
    Foo();
    int bar;
    };

    Foo::Foo()
    {
    int bar = 0; << same name as the member variable = shadowing
    << member variable is not initialized
    }
    @



  • [quote author="SGaist" date="1374869962"]@
    class Foo {
    public:
    Foo();
    int bar;
    };

    Foo::Foo()
    {
    int bar = 0; << same name as the member variable = shadowing
    << member variable is not initialized
    }
    @[/quote]
    Thank you, but what should I do to implement your sample code? Truly I am new in Qt and I don't understand.


  • Lifetime Qt Champion

    It's nothing Qt related, it's basic c/c++ knowledge. My example only shows what is happening in your code.

    @
    Foo::Foo()
    {
    bar = 0; << initializes the class member
    }
    @



  • Oukay, so now, what should I do to fix my code?


  • Lifetime Qt Champion

    Compare my two examples and apply the difference to your code.



  • Hi, you need to make yourself familiar with C++ ASAP.
    [quote author="Ade Malsasa Akbar" date="1374967552"]Oukay, so now, what should I do to fix my code?[/quote]



  • Thank you, but my problem actually quite simple. I just don't know what to do in one piece of field. Can you give a clue?



  • SOLVED!

    Now I can change the stack index, and the layer is changing by pusbutton click. The code is:

    HEADER

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QtGui>

    class Dialog : public QDialog
    {
    Q_OBJECT

    public:
    Dialog();
    QVBoxLayout *mainlayout; //deklarasi objek-objek seharusnya dilakukan di sini saja
    QVBoxLayout *layouta; //nanti di mainwindow.cpp hanya diulang deklarasinya tanpa nama kelas awal
    QVBoxLayout *layoutb;
    QPushButton *tombola;
    QPushButton *tombolb;
    QPushButton *tombolc;
    QPushButton *tombold;
    QFrame *framea;
    QFrame *frameb;
    QStackedLayout *stackia;

    public slots:
    void change_stack(); //harus public, kalau private maka stack tidak berganti sama sekali

    private:
    //ini dibiarkan kosong saja
    };

    #endif // MAINWINDOW_H@

    CPP

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    Dialog::Dialog()
    {
    mainlayout = new QVBoxLayout; //kesalahan kode sehingga tidak bisa berubah indeks stack-nya
    layouta = new QVBoxLayout; //adalah gara-gara dideklarasikan ulang nama kelasnya
    layoutb = new QVBoxLayout; //contoh yang SALAH: QVBoxLayout *layout = new QVBoxLayout;
    tombola = new QPushButton("A"); //contoh yang BENAR: layout = new QVBoxLayout;
    tombolb = new QPushButton("B"); //dan harus dideklarasikan juga slot bertipe void di header
    tombolc = new QPushButton("C"); //dan slot itu harus bertipe public tidak boleh private
    framea = new QFrame;
    frameb = new QFrame;
    stackia = new QStackedLayout;

    layouta->addWidget(tombola);
    layoutb->addWidget(tombolb);
    
    framea->setLayout(layouta);
    frameb->setLayout(layoutb);
    framea->setMinimumSize(88,88);
    frameb->setMinimumSize(88,88);
    
    //building frame
    framea->setFrameShape(QFrame::StyledPanel);
    framea->setFrameShadow(QFrame::Raised);
    frameb->setFrameShape(QFrame::StyledPanel);
    frameb->setFrameShadow(QFrame::Raised);
    
    //get c button smaller
    tombolc->setMaximumWidth(33);
    
    stackia->addWidget(framea);
    stackia->addWidget(frameb);
    stackia->addWidget(tombolc);
    
    mainlayout->addLayout(stackia);
    QPushButton     *tombold    =   new QPushButton("D");
    mainlayout->addWidget(tombold);
    setLayout(mainlayout);
    
    connect(tombold, SIGNAL(clicked()), this, SLOT(change_stack()));
    

    }

    void Dialog::change_stack()
    {
    stackia->setCurrentIndex(a);
    }
    @

    My mistakes:

    I repeated the declaration in HEADER into CPP. The repeated declaration (the wrong one) is something like *QPushButton button = new QPushButton; and the correct one is something like button = new QPushButton;. I dont know what is the name for this but i don't care, my problem solved.

    I dont know the correct code for my change_stack() function. The code for that should call setCurrentIndex() function for stack objeck.

    I don't know the correct receiver and SLOT for my code. The correct one is what appeared in the code above.

    The Best Answer

    Thank you, Mr SGaist. My friend from Indonesia, kcin, tells me what is the meaning of your answer. Actually I don't understand. But after he says difference between int n = 1 and n = 1, I change my code and boom. Solved. Your clue was true. Thank you.


  • Lifetime Qt Champion

    You're welcome, like 1+1=2 suggested, get a good book about C++. You'll understand better what your problems were.

    Also, "it works so I don't care to understand" is a very bad philosophy, even more when programming in C++, this will result in poor/bad code that will bite you back at the worse time.



  • Thank you, but my religion forbid me hardly from philosophy. But your suggestion to learn is good. I accept it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.