For my Qt application, I'm trying to use a QLinkedList
which the user can cycle through the new window screens that the user has created. The windows are created dynamically when the user clicks the "New Window" button on the MainWindow
which the MainWindow
object is added to the QLinkedList
.
I'm trying to use the QLinkedListIterator
for the Back and Forward button to point to towards the previous screen and next screen. So far it works for the Forward button but for the Back button, it crashes and if I click Back on the first screen, it also crashes.
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QLabel>
#include <QTextEdit>
#include <QLinkedList>
#include <QLinkedListIterator>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QLinkedList<MainWindow*> window_list;
private:
Ui::MainWindow *ui;
QPushButton *button;
MainWindow* new_window;
// Add new Window
void input_new_window();
// Forward and back buttons
void input_back_button();
void input_forward_button();
void go_back();
void go_forward();
void addWindow();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->resize(800, 400);
//---------------------------
// Show buttons
//----------------------------
this->input_back_button();
this->input_forward_button();
this->input_new_window();
}
MainWindow::~MainWindow()
{
delete ui;
}
// Add Window to the front of the list
void MainWindow::addWindow()
{
// Create new Window Object
new_window = new MainWindow();
// Add the New Window to the list
window_list.append(new_window);
// Display the New Window
new_window->show();
}
void MainWindow::go_back()
{
// Go back to previous window in the linkedlist
QMutableLinkedListIterator<MainWindow*> i(window_list);
if(i.hasPrevious())
{
new_window->show();
this->hide();
}
}
void MainWindow::go_forward()
{
// Go forward to next window in the linkedlist
QMutableLinkedListIterator<MainWindow*> i(window_list);
if(i.hasNext())
{
new_window->show();
this->hide();
}
}
//----------------------------------------------------------
// Open New Window
//----------------------------------------------------------
void MainWindow::input_new_window()
{
button = new QPushButton("New Window", this);
button->setGeometry(QRect(QPoint(10, 30), QSize(200, 50)));
button->show();
QObject::connect(button, &QPushButton::pressed, this, &MainWindow::addWindow);
}
//--------------------------------------------------------
// Going forward and back with windows
//--------------------------------------------------------
void MainWindow::input_back_button()
{
button = new QPushButton("Back", this);
button->setGeometry(QRect(QPoint(10, 340), QSize(200, 50)));
button->show();
// Link back button with going back a screen
QObject::connect(button, &QPushButton::pressed, this, &MainWindow::go_back);
}
void MainWindow::input_forward_button()
{
button = new QPushButton("Forward", this);
button->setGeometry(QRect(QPoint(580, 340), QSize(200, 50)));
button->show();
// Link forward button with going forward a screen
QObject::connect(button, &QPushButton::pressed, this, &MainWindow::go_forward);
}
You are working with different lists of windows: each new window you add is holding its own list, so cycling is actually not possible. In addition, the
new_window
variable is not necessary as a member and I think it is creating a bit of mess for you.The reason it is working for the forward is because
new_window
already holds the next window (you assigned it when calling theaddWindow
method, so it is actually the next window). On the other hand, the back is also using thenew_window
(the next), so it will not work as expected.To solve your problem try using a shared list of windows, may be a global list, or pass it when constructing each window.
Solution below is not the most elegant and may have race conditions, but will illustrate my point. It uses a global list of windows: each time you want to move forward or backward it searches for the current window and cycles on the list. Also, I've removed the
new_window
member ;)In the header file
In the .cpp file
Now, you should also add the very first window to the list too. Probably you are using the default Qt template, like:
Instead of creating the object on the stack, do it dynamically and add it to the list:
it
iterators are actuallyQLinkedList::iterator
, and STL-like iterator, not the Java-like ones. Not a big deal, just that I'm more familiarised with the first ones.I haven't been able to test the code since now I don't have access to my development environment, so please forgive me any typo or compilation error.
Improvements
addWindowToList
method manually, you can do it in theMainWindow
constructor instead (addWindowToList(this)
) so you only have to create them and they will be added automatically.