在 QTabWidget 的更改上显示星号
Show asterisk on changes of a QTabWidget
我正在创建一个多文件文本编辑器,它使用用于编辑不同文件的选项卡。
为此,我使用了一个 QTabWidget,它包含 QPlainTextEdit 小部件,用户可以在其中编辑文本。如果用户在 QPlainTextEdit 中编辑文本,我想通过添加星号 (*) 来更改选项卡标题,以向他显示此文件中有未保存的更改。
我目前的解决方案如下:
向 QTabWidget 添加新选项卡:
QPlainTextEdit* temp = new QPlainTextEdit("lots of text", this);
temp->setWindowTitle("the title of the tab");
connect(temp->document(), SIGNAL(contentsChanged()), this, SLOT(onTabContentChanged()));
mTabWidget->setCurrentIndex(mTabWidget->addTab(temp, temp->windowTitle()));
对内容更改的反应插槽:
void MainWindow::onTabContentChanged(void) {
// Content of a tabbed QPlainTextedit has changed; find it and set it to modified
QTextDocument* tempDocument = dynamic_cast<QTextDocument*>(sender());
if(tempDocument) {
for (int var = 0; var < mTabWidget->count(); ++var) {
QPlainTextEdit* tempTextedit = dynamic_cast<QPlainTextEdit*>(mTabWidget->widget(var));
if(tempTextedit) {
if(tempDocument == tempTextedit->document()) {
tempTextedit->setWindowModified(true);
mTabWidget->setTabText(mTabWidget->indexOf(tempTextedit), "add a * here");
}
}
}
}
}
在我看来,使用 sender() 并不好,而且 effort/code 这样做太多了,所以我觉得我做错了,或者有更好的方法来做到这一点。
有什么想法吗?
使用:
Win7 专业版
Qt 5.3.2
有多种方法可以简化此代码。例如,您可以使用 QPlainTextEdit::textChanged
信号代替 QTextDocument::contentsChanged
。如果你这样做,你将在动态转换后得到 QPlainTextEdit
并且你将能够立即使用 QTabWidget::indexOf
而无需迭代。
您还可以假设用户无法在非活动选项卡上编辑某些内容,因此您可以只使用 QTabWidget::currentIndex
.
然而,有时复杂胜于简化。我假设您的编辑器将具有某些功能,并且其行为将与简单 QPlainTextEdit
不同。创建一个代表选项卡内容的 class 可能会很好。您可以从 QPlainTextEdit
派生或创建另一个包含 QPlainTextEdit
的表单 class 并且将来可能包含更多小部件。然后,您可以将与单个编辑器相关的所有逻辑放在这个 class 中,因此它还应该决定应该为它显示哪个标题。 class 应该有一个指向主窗体或选项卡小部件的指针,并且可以轻松地在选项卡小部件中计算自己的索引,因此它可以在不使用 sender()
.
的情况下重命名其选项卡
我正在创建一个多文件文本编辑器,它使用用于编辑不同文件的选项卡。 为此,我使用了一个 QTabWidget,它包含 QPlainTextEdit 小部件,用户可以在其中编辑文本。如果用户在 QPlainTextEdit 中编辑文本,我想通过添加星号 (*) 来更改选项卡标题,以向他显示此文件中有未保存的更改。
我目前的解决方案如下:
向 QTabWidget 添加新选项卡:
QPlainTextEdit* temp = new QPlainTextEdit("lots of text", this);
temp->setWindowTitle("the title of the tab");
connect(temp->document(), SIGNAL(contentsChanged()), this, SLOT(onTabContentChanged()));
mTabWidget->setCurrentIndex(mTabWidget->addTab(temp, temp->windowTitle()));
对内容更改的反应插槽:
void MainWindow::onTabContentChanged(void) {
// Content of a tabbed QPlainTextedit has changed; find it and set it to modified
QTextDocument* tempDocument = dynamic_cast<QTextDocument*>(sender());
if(tempDocument) {
for (int var = 0; var < mTabWidget->count(); ++var) {
QPlainTextEdit* tempTextedit = dynamic_cast<QPlainTextEdit*>(mTabWidget->widget(var));
if(tempTextedit) {
if(tempDocument == tempTextedit->document()) {
tempTextedit->setWindowModified(true);
mTabWidget->setTabText(mTabWidget->indexOf(tempTextedit), "add a * here");
}
}
}
}
}
在我看来,使用 sender() 并不好,而且 effort/code 这样做太多了,所以我觉得我做错了,或者有更好的方法来做到这一点。
有什么想法吗?
使用:
Win7 专业版
Qt 5.3.2
有多种方法可以简化此代码。例如,您可以使用 QPlainTextEdit::textChanged
信号代替 QTextDocument::contentsChanged
。如果你这样做,你将在动态转换后得到 QPlainTextEdit
并且你将能够立即使用 QTabWidget::indexOf
而无需迭代。
您还可以假设用户无法在非活动选项卡上编辑某些内容,因此您可以只使用 QTabWidget::currentIndex
.
然而,有时复杂胜于简化。我假设您的编辑器将具有某些功能,并且其行为将与简单 QPlainTextEdit
不同。创建一个代表选项卡内容的 class 可能会很好。您可以从 QPlainTextEdit
派生或创建另一个包含 QPlainTextEdit
的表单 class 并且将来可能包含更多小部件。然后,您可以将与单个编辑器相关的所有逻辑放在这个 class 中,因此它还应该决定应该为它显示哪个标题。 class 应该有一个指向主窗体或选项卡小部件的指针,并且可以轻松地在选项卡小部件中计算自己的索引,因此它可以在不使用 sender()
.