change page of stackwidget with scrollarea
-
i want to change the stackwidget pages with scrollarea.
i tried scrollbar with satckwidget by signal and slot of qt designer ,problem is mouse pointer needs to be in scrollbar and i have to select the bar and move up and down to change the page.
On the scrollarea mouse pointer scroll works on whole widgeti could not find ant function in scrollarea to do this.
this is a picture stackwidget with scrollbar.(not scrollarea)
-
Hi
You can hook it up from code. You can get the scroll areas scrollbar with
http://doc.qt.io/qt-5/qabstractscrollarea.html#verticalScrollBar
Im not sure why a scroll area works best but assume it allows mwheel mouse (center mouse button)
events over the qstackedwidget and could switch ? -
If I understand you correctly you want to use mouse wheel to change current stack widget page and reflect that on a scrollbar. Is that correct?
If that is the case then there are two things to do.
First connect scrollbar's
valueChanged
signal to the stack widget'ssetCurrentIndex
slot. (I see you already did that)Second - you need to forward stack widget's wheel events to the scrollbar (this is how scrollarea does it). This part can't be done from the designer. Install an event filter on the stack widget and check for
WheelEvent
. Alternatively you can subclass the stackwidget and implement wheelEvent(). In any case, when you get a wheel event forward it to the scrollbar using QCoreApplication::sendEvent() method. -
If I understand you correctly you want to use mouse wheel to change current stack widget page and reflect that on a scrollbar. Is that correct?
If that is the case then there are two things to do.
First connect scrollbar's
valueChanged
signal to the stack widget'ssetCurrentIndex
slot. (I see you already did that)Second - you need to forward stack widget's wheel events to the scrollbar (this is how scrollarea does it). This part can't be done from the designer. Install an event filter on the stack widget and check for
WheelEvent
. Alternatively you can subclass the stackwidget and implement wheelEvent(). In any case, when you get a wheel event forward it to the scrollbar using QCoreApplication::sendEvent() method.@Chris-Kawa
i understood the steps .but i not sure how i can get the wheel event to scrollbar. -
Lets say you have a stacked widget named
stackedWidget
, a scrollbar namedverticalScrollBar
and they are both placed in aMainWindow
class.In
MainWindow
's constructor you install event filter:MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->stackedWidget->installEventFilter(this); //this is the important line }
Then you override the
eventFilter()
method ofMainWindow
:bool MainWindow::eventFilter(QObject* obj, QEvent* evt) { if (obj == ui->stackedWidget && evt->type() == QEvent::Wheel) { QWheelEvent* wheel_evt = static_cast<QWheelEvent*>(evt); if (wheel_evt->orientation() == Qt::Vertical) { QCoreApplication::sendEvent(ui->verticalScrollBar, wheel_evt); return true; } } return QMainWindow::eventFilter(obj, evt); }
If you also have a horizontal scroll you can handle it similarly.
-
Lets say you have a stacked widget named
stackedWidget
, a scrollbar namedverticalScrollBar
and they are both placed in aMainWindow
class.In
MainWindow
's constructor you install event filter:MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->stackedWidget->installEventFilter(this); //this is the important line }
Then you override the
eventFilter()
method ofMainWindow
:bool MainWindow::eventFilter(QObject* obj, QEvent* evt) { if (obj == ui->stackedWidget && evt->type() == QEvent::Wheel) { QWheelEvent* wheel_evt = static_cast<QWheelEvent*>(evt); if (wheel_evt->orientation() == Qt::Vertical) { QCoreApplication::sendEvent(ui->verticalScrollBar, wheel_evt); return true; } } return QMainWindow::eventFilter(obj, evt); }
If you also have a horizontal scroll you can handle it similarly.
-
Lets say you have a stacked widget named
stackedWidget
, a scrollbar namedverticalScrollBar
and they are both placed in aMainWindow
class.In
MainWindow
's constructor you install event filter:MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->stackedWidget->installEventFilter(this); //this is the important line }
Then you override the
eventFilter()
method ofMainWindow
:bool MainWindow::eventFilter(QObject* obj, QEvent* evt) { if (obj == ui->stackedWidget && evt->type() == QEvent::Wheel) { QWheelEvent* wheel_evt = static_cast<QWheelEvent*>(evt); if (wheel_evt->orientation() == Qt::Vertical) { QCoreApplication::sendEvent(ui->verticalScrollBar, wheel_evt); return true; } } return QMainWindow::eventFilter(obj, evt); }
If you also have a horizontal scroll you can handle it similarly.
-
Lets say you have a stacked widget named
stackedWidget
, a scrollbar namedverticalScrollBar
and they are both placed in aMainWindow
class.In
MainWindow
's constructor you install event filter:MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->stackedWidget->installEventFilter(this); //this is the important line }
Then you override the
eventFilter()
method ofMainWindow
:bool MainWindow::eventFilter(QObject* obj, QEvent* evt) { if (obj == ui->stackedWidget && evt->type() == QEvent::Wheel) { QWheelEvent* wheel_evt = static_cast<QWheelEvent*>(evt); if (wheel_evt->orientation() == Qt::Vertical) { QCoreApplication::sendEvent(ui->verticalScrollBar, wheel_evt); return true; } } return QMainWindow::eventFilter(obj, evt); }
If you also have a horizontal scroll you can handle it similarly.
@Chris-Kawa thanks for the sovle.
i made some changes.
first i removed the signal and slot. instead of signal i added the code in the event filter.
second changed some value of verticalScrollBar in designer .
Now it is working .but there is a problem when i move the verticalScrollBar up.it took mouse click to change the stackwidget page.
any solve for that leg problem?#include "mainwindow.h" #include "ui_mainwindow.h" #include <QMouseEvent> #include <QWheelEvent> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->stackedWidget->installEventFilter(this); //this is the important line } MainWindow::~MainWindow() { delete ui; } bool MainWindow::eventFilter(QObject* obj, QEvent* evt) { if (obj == ui->stackedWidget && evt->type() == QEvent::Wheel) { QWheelEvent* wheel_evt = static_cast<QWheelEvent*>(evt); if (wheel_evt->orientation() == Qt::Vertical) { QCoreApplication::sendEvent(ui->verticalScrollBar, wheel_evt); return true; } } int s = ui->verticalScrollBar->value(); ui->stackedWidget->setCurrentIndex(s); return QMainWindow::eventFilter(obj, evt); }
here is the value of verticalScrollBar in designer .
-
The way you modified
eventFilter
is completely wrong. ThiseventFilter
method is called not only for mouse wheel events but for any kind of events - paint, resize, mouse clicks, keyboard, focus and tons more. That's why I put those if statements. You shouldn't put that scrollbar code outside the ifs.If you don't want to use the designer for the connection put it in the
MainWindow
's constructor:MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //you don't have to copy my comments too ;) ui->stackedWidget->installEventFilter(this); connect(ui->verticalScrollBar, &QScrollBar::valueChanged, ui->stackedWidget, &QStackedWidget::setCurrentIndex); }
and remove that code you added to the event filter.
-
The way you modified
eventFilter
is completely wrong. ThiseventFilter
method is called not only for mouse wheel events but for any kind of events - paint, resize, mouse clicks, keyboard, focus and tons more. That's why I put those if statements. You shouldn't put that scrollbar code outside the ifs.If you don't want to use the designer for the connection put it in the
MainWindow
's constructor:MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //you don't have to copy my comments too ;) ui->stackedWidget->installEventFilter(this); connect(ui->verticalScrollBar, &QScrollBar::valueChanged, ui->stackedWidget, &QStackedWidget::setCurrentIndex); }
and remove that code you added to the event filter.
@Chris-Kawa
thanks.
i will do it.
any idea why click is needed to show the changed page, if scrollbar goes from down to up. -
It's not required with the solution I proposed so it has to be some problem specific to your code or changes you made in the designer. From your screenshots I see you have most of the properties modified (bold font) although they are set to their default values. You should reset them to default if you don't want to modify them (the red arrow that appears on the right when you click on a property).
Could you reproduce the issue on a small, clean project with just the stack widget and a scrollbar? Alternatively could you package your project and share it so we could take a look?
-
It's not required with the solution I proposed so it has to be some problem specific to your code or changes you made in the designer. From your screenshots I see you have most of the properties modified (bold font) although they are set to their default values. You should reset them to default if you don't want to modify them (the red arrow that appears on the right when you click on a property).
Could you reproduce the issue on a small, clean project with just the stack widget and a scrollbar? Alternatively could you package your project and share it so we could take a look?
i will try in a clean project.
yes.i could do it .it is an GPLv2 app.
but it huge in cpp ,ui etc.
i will be releasing it within this month .i will inform you.
thanks for the reply. -
It's not required with the solution I proposed so it has to be some problem specific to your code or changes you made in the designer. From your screenshots I see you have most of the properties modified (bold font) although they are set to their default values. You should reset them to default if you don't want to modify them (the red arrow that appears on the right when you click on a property).
Could you reproduce the issue on a small, clean project with just the stack widget and a scrollbar? Alternatively could you package your project and share it so we could take a look?