网上看到的许多方法都是打开新窗口,或者直接return this,来覆盖当前页面

我们可以通过信号的方式结合tabWidget来实现类似浏览器的选项卡的效果

在继承的类里自定义信号:

signals:
	void opennewpage(QWidget*,MyWebView*);

然后重写creatWindow,发射信号

QWebEngineView* MyWebView::createWindow(QWebEnginePage::WebWindowType type)
{
	QWidget* newwidget = new QWidget();
	MyWebView* newpage = new MyWebView(newwidget);
	emit opennewpage(newwidget,newpage);//发射信号,将页面传递过去
	return newpage;//在newpage里打开新页面
}

主界面 

class QWebDialog : public QDialog
{
	Q_OBJECT

public:
	QWebDialog(QWidget *parent,QUrl page);//page是打开之后的主页
	~QWebDialog();
	void resizeEvent(QResizeEvent*);
private:
	Ui::QWebDialog ui;
	MyWebView* webview;//主页
	QList<MyWebView*> weblist;//页面列表
private slots:
	void settitle(QString title);
	void seticon(QIcon icon);
	void addpage(QWidget*,MyWebView*);
	void closepage(int index);
};

主界面的构造函数

QWebDialog::QWebDialog(QWidget *parent,QUrl page)
	: QDialog(parent)
{
	ui.setupUi(this);
    ui.tabWidget->setTabsClosable(true);//在tabWidget的标签右边显示关闭按钮
	webview = new MyWebView(ui.widget1);
	webview->load(page);//加载主页
	weblist.append(webview);//追加到页面列表
	webview->show();//打开主页
	ui.widget1->resize(this->size());//设置tabWidget的子Widget的尺寸
	webview->resize(ui.widget1->size());//设置页面尺寸
	connect(webview, SIGNAL(titleChanged(QString)), this, SLOT(settitle(QString)));//页面标签标题改变
	connect(webview, SIGNAL(iconChanged(QIcon)), this, SLOT(seticon(QIcon)));//页面标签图标改变
	connect(webview, SIGNAL(opennewpage(QWidget*,MyWebView*)),
		this, SLOT(addpage(QWidget*,MyWebView*)));//如果页面请求打开新的页面
	connect(ui.tabWidget, SIGNAL(tabCloseRequested(int)),
		this, SLOT(closepage(int)));//如果点击了标签的关闭按钮
}

槽函数的实现:

void QWebDialog::addpage(QWidget* newpage,MyWebView *view)
{
	//确定发送信号的页面的位置
	MyWebView* senders = (MyWebView*)sender();
	int index = weblist.indexOf(senders);
	//将新标签插入到发出信号的页面之后
	ui.tabWidget->insertTab(index+1, newpage, "tab");
	view->show();//显示页面
	newpage->resize(this->size());//设置tabWidget的子widget的尺寸
	view->resize(newpage->size());//设置页面尺寸
	weblist.insert(index+1,view);//根据页面标签的位置插入到列表
	ui.tabWidget->setCurrentIndex(index+1);//转到新加入的页面
	connect(view, SIGNAL(titleChanged(QString)), this, SLOT(settitle(QString)));//页面标签标题改变
	connect(view, SIGNAL(iconChanged(QIcon)), this, SLOT(seticon(QIcon)));//页面标签图标改变
	connect(view, SIGNAL(opennewpage(QWidget*, MyWebView*)),
		this, SLOT(addpage(QWidget*, MyWebView*)));//如果页面请求打开新的页面
}
void QWebDialog::closepage(int index)
{
	//移除关闭的页面,并释放内存
	QWidget* remove = ui.tabWidget->widget(index);
	ui.tabWidget->removeTab(index);
	delete remove;
	weblist.removeAt(index);
	ui.tabWidget->setCurrentIndex(index - 1);//页面切换到被关闭的页面的左边
	//如果标签全部被关闭,则关闭窗口
	if (ui.tabWidget->count() == 0)
	{
		close();
	}
}
void QWebDialog::settitle(QString title)
{
	//确定发送信号的页面
	MyWebView* senders = (MyWebView*)sender();
	//更改该页面标签的标题
	ui.tabWidget->setTabText(weblist.indexOf(senders), title);
}

void QWebDialog::seticon(QIcon icon)
{
	//确定发送信号的页面
	MyWebView* senders = (MyWebView*)sender();
	//更改该页面标签的图标
	ui.tabWidget->setTabIcon(weblist.indexOf(senders), icon);
}

可以重写resizeEvent,在拉伸窗口时,让页面尺寸随之改变。

更多推荐