C++ 使用QLinkedList循环浏览不同的窗口屏幕
对于我的Qt应用程序,我尝试使用一个C++ 使用QLinkedList循环浏览不同的窗口屏幕,c++,qt,linked-list,qlinkedlist,C++,Qt,Linked List,Qlinkedlist,对于我的Qt应用程序,我尝试使用一个QLinkedList,用户可以循环浏览用户创建的新窗口屏幕。当用户单击MainWindow上的“新建窗口”按钮时,窗口将动态创建,而MainWindow对象将添加到QLinkedList 我试图使用qlinkedlistierator作为后退和前进按钮,指向上一个屏幕和下一个屏幕。到目前为止,它适用于前进按钮,但对于后退按钮,它会崩溃,如果我在第一个屏幕上单击后退,它也会崩溃 main window.h #ifndef MAINWINDOW_H #defin
QLinkedList
,用户可以循环浏览用户创建的新窗口屏幕。当用户单击MainWindow
上的“新建窗口”按钮时,窗口将动态创建,而MainWindow
对象将添加到QLinkedList
我试图使用qlinkedlistierator
作为后退和前进按钮,指向上一个屏幕和下一个屏幕。到目前为止,它适用于前进按钮,但对于后退按钮,它会崩溃,如果我在第一个屏幕上单击后退,它也会崩溃
main window.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
\ifndef主窗口
#定义主窗口
#包括
#包括
#包括
#包括
#包括
#包括
名称空间用户界面{
类主窗口;
}
类主窗口:公共QMainWindow
{
Q_对象
公众:
显式主窗口(QWidget*parent=0);
~main窗口();
QLinkedList窗口_列表;
私人:
Ui::MainWindow*Ui;
QPushButton*按钮;
主窗口*新窗口;
//添加新窗口
无效输入\新建\窗口();
//前进和后退按钮
无效输入返回按钮();
无效输入\前进\按钮();
无效返回();
无效前进();
void addWindow();
};
#endif//main窗口
main window.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);
}
#包括“mainwindow.h”
#包括“ui_main window.h”
主窗口::主窗口(QWidget*父窗口):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
用户界面->设置用户界面(此);
这->调整大小(800400);
//---------------------------
//显示按钮
//----------------------------
此->输入返回按钮();
此->输入前进按钮();
此->输入新窗口();
}
MainWindow::~MainWindow()
{
删除用户界面;
}
//将窗口添加到列表的前面
void MainWindow::addWindow()
{
//创建新窗口对象
新建_窗口=新建主窗口();
//将新窗口添加到列表中
窗口列表。追加(新窗口);
//显示新窗口
新建窗口->显示();
}
void主窗口::返回()
{
//返回linkedlist中的上一个窗口
qmutableLinkedListerator i(窗口列表);
if(i.hasPrevious())
{
新建窗口->显示();
这个->隐藏();
}
}
void主窗口::前进()
{
//转到linkedlist中的下一个窗口
qmutableLinkedListerator i(窗口列表);
if(i.hasNext())
{
新建窗口->显示();
这个->隐藏();
}
}
//----------------------------------------------------------
//打开新窗口
//----------------------------------------------------------
void main window::input_new_window()
{
按钮=新的QPushButton(“新窗口”,此按钮);
按钮->设置几何体(QRect(QPoint(10,30),QSize(200,50));
按钮->显示();
QObject::connect(按钮,&QPushButton::按下,此,&MainWindow::addWindow);
}
//--------------------------------------------------------
//使用windows前后移动
//--------------------------------------------------------
void主窗口::输入\返回\按钮()
{
按钮=新的QPushButton(“后退”,此按钮);
按钮->设置几何体(QRect(QPoint(10340),QSize(20050));
按钮->显示();
//带返回屏幕的链接返回按钮
QObject::connect(按钮,&QPushButton::按下,此,&MainWindow::返回);
}
void主窗口::输入\前进\按钮()
{
按钮=新的QPushButton(“前进”,此按钮);
按钮->设置几何体(QRect(QPoint(580340),QSize(200,50));
按钮->显示();
//链接前进按钮与前进屏幕
QObject::connect(按钮,&QPushButton::按下,此,&MainWindow::前进);
}
您使用的是不同的窗口列表:您添加的每个新窗口都有自己的列表,因此循环实际上是不可能的。此外,new_window
变量作为成员是不必要的,我认为这会给您带来一些麻烦
它用于转发的原因是new\u window
已经保存了下一个窗口(您在调用addWindow
方法时分配了它,因此它实际上是下一个窗口)。另一方面,背面也使用了新窗口(下一个),因此它将无法按预期工作
要解决您的问题,请尝试使用共享的窗口列表,可以是全局列表,也可以在构造每个窗口时传递它
下面的解决方案不是最优雅的,可能有竞争条件,但可以说明我的观点。它使用一个全局窗口列表:每次您想要向前或向后移动时,它都会搜索当前窗口和列表上的周期。此外,我还删除了new_窗口
member;)
在头文件中
class MainWindow ... {
public:
static void addWindowToList(MainWindow* w);
}
在.cpp文件中
// ...
#include <cassert>
namespace {
QLinkedList<MainWindow*> window_list; // global list
}
// ...
void MainWindow::addWindowToList(MainWindow* w)
{
window_list.append(w);
}
void MainWindow::addWindow()
{
addWindowToList(new MainWindow());
go_forward(); // shows new window
}
void MainWindow::go_back()
{
if (window_list.count() == 1) return; // no other windows
if (window_list.first() == this) { // has to go the last one
window_list.back()->show();
} else {
auto it = std::find(window_list.begin(), window_list.end(), this);
assert(it != window_list.end()); // should be in the list
(*(--it))->show();
}
hide();
}
void MainWindow::go_forward()
{
if (window_list.count() == 1) return; // no other windows
if (window_list.back() == this) { // has to go to the first one
window_list.first()->show();
} else {
auto it = std::find(window_list.begin(), window_list.end(), this);
assert(it != window_list.end()); // should be in the list
(*(++it))->show();
}
hide();
}
// ...
动态创建对象并将其添加到列表中,而不是在堆栈上创建对象:
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
auto w = new MainWindow();
MainWindow::addWindowToList(w);
w->show();
return a.exec();
}
it
迭代器实际上是类似STL的迭代器,而不是类似Java的迭代器。没什么大不了的,只是我更熟悉第一个
- 我无法测试代码,因为现在我无法访问我的开发环境,所以请原谅我的任何打字错误或编译错误
改进
- 与手动使用
addWindowToList
方法不同,您可以在main window
构造函数中执行此操作(addWindowToList(this)
),因此您只需创建它们,它们就会自动添加
- 代码没有显示任何关于销毁窗口的内容。关闭/销毁窗口时,应注意将其从列表中删除,否则在循环窗口时会崩溃。与使用构造函数类似,您可以在析构函数上执行此操作,并从列表中删除窗口
再次感谢您的解决方案,我正在尝试编译代码,但它显示了编译器的“(-it)->show();”和“(++it)->show();”的错误
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
auto w = new MainWindow();
MainWindow::addWindowToList(w);
w->show();
return a.exec();
}