英文:
How do I get the current left and indentations in this code, display them and after that implement the custom ones the user entered in the text edit
问题
所以我基本上需要获取当前的左缩进和右缩进,将它们显示在文本部件上,然后获取用户输入的自定义缩进,然后实现它们。当我运行这个程序时,它显示了不正确的缩进值。缩进的最小值和最大值分别为0和14。还有,当我在对话框框中输入自定义值时,有时它只增加了一个值,而其他时候什么也没发生。有人能帮助我找到我的错误吗?
/*!
* \fn MainWindow::on_actionIncrease_Indent_triggered
* \brief 添加缩进,最多到14.65(即触及右边距)(以厘米为单位)
*/
void MainWindow::on_actionIncrease_Indent_triggered(int left, int right)
{
if (!curr_browser || curr_browser->isReadOnly())
return;
QMargins margin = curr_browser->contentsMargins();
QTextCursor cursor = curr_browser->textCursor();
QTextBlock block = cursor.block();
QTextBlockFormat blockFormat = block.blockFormat();
int presentIndent = blockFormat.indent();
int indent = 1 + presentIndent;
if (left != 0)
indent = left;
if (indent > 14)
return;
if (right == 0)
blockFormat.setRightMargin(margin.right());
else
blockFormat.setRightMargin(right);
blockFormat.setIndent(indent);
// qDebug() << "Increase Indent ->" << blockFormat.indent();
cursor.mergeBlockFormat(blockFormat);
}
/*!
* \fn MainWindow::on_actionDecrease_Indent_triggered
* \brief 移除缩进,最多到0(即触及左边距)(以厘米为单位)
*/
void MainWindow::on_actionDecrease_Indent_triggered()
{
if (!curr_browser || curr_browser->isReadOnly())
return;
QMargins margin = curr_browser->contentsMargins();
QTextCursor cursor = curr_browser->textCursor();
QTextBlock block = cursor.block();
QTextBlockFormat blockFormat = block.blockFormat();
int presentIndent = blockFormat.indent();
int indent = presentIndent - 1;
if (indent < 0)
return;
blockFormat.setLeftMargin(margin.left());
blockFormat.setIndent(presentIndent - 1);
// qDebug() << "Decrease Indent ->" << blockFormat.indent();
cursor.mergeBlockFormat(blockFormat);
}
void MainWindow::on_actionIndentation_Options_triggered()
{
if (!curr_browser || curr_browser->isReadOnly())
return;
QMargins margin = curr_browser->contentsMargins();
QTextCursor cursor = curr_browser->textCursor();
QTextBlock block = cursor.block();
QTextBlockFormat blockFormat = block.blockFormat();
int left = blockFormat.indent(), right = margin.right() - blockFormat.rightMargin();
indentOptions *i = new indentOptions(this, &left, &right);
i->show();
connect(i, &indentOptions::dialogAccepted, this, [=]() {
if (left + right <= 14) {
on_actionIncrease_Indent_triggered(left, right);
}
i->deleteLater();
});
}
indentOptions::indentOptions(QWidget *parent, int *left, int *right) :
QDialog(parent),
ui(new Ui::indentOptions)
{
ui->setupUi(this);
this->left = left;
this->right = right;
setWindowTitle("Set Indentation");
ui->textEdit_left->setText(QString::number(*left));
ui->textEdit_right->setText(QString::number(*right));
}
英文:
So I have to basically get the current left and right indentations, display them on the text widget and then get the user input for the custom indentations and basically implement them. When I run this program it displays the incorrect indentation values. the minimum and max values of indentations are 0 and 14 respectively. Also when I enter custom values in the dialog box it just increments the values by one sometimes and other times it does nothing. Can someone help me find my mistake?
/*!
* \fn MainWindow::on_actionIncrease_Indent_triggered
* \brief Adding Indentation upto 14.65 {i.e. touched right margin} {in cm}
*/
void MainWindow::on_actionIncrease_Indent_triggered(int left, int right)
{
if(!curr_browser || curr_browser->isReadOnly())
return;
QMargins margin = curr_browser->contentsMargins();
QTextCursor cursor = curr_browser->textCursor();
QTextBlock block = cursor.block();
QTextBlockFormat blockFormat = block.blockFormat();
int presentIndent = blockFormat.indent();
int indent = 1+presentIndent;
if(left != 0) indent = left;
if(indent > 14) return;
if(right == 0)blockFormat.setRightMargin(margin.right());
else blockFormat.setRightMargin(right);
blockFormat.setIndent(indent);
// qDebug()<<"Increase Indent ->"<<blockFormat.indent();
cursor.mergeBlockFormat(blockFormat);
}
/*!
* \fn MainWindow::on_actionDecrease_Indent_triggered
* \brief Removing Indentation upto 0 {i.e. touches Left margin} {in cm}
*/
void MainWindow::on_actionDecrease_Indent_triggered()
{
if(!curr_browser || curr_browser->isReadOnly())
return;
QMargins margin = curr_browser->contentsMargins();
QTextCursor cursor = curr_browser->textCursor();
QTextBlock block = cursor.block();
QTextBlockFormat blockFormat = block.blockFormat();
int presentIndent = blockFormat.indent();
int indent = presentIndent-1;
if(indent < 0) return;
blockFormat.setLeftMargin(margin.left());
blockFormat.setIndent(presentIndent - 1);
// qDebug()<<"Decrease Indent ->"<<blockFormat.indent();
cursor.mergeBlockFormat(blockFormat);
}
void MainWindow::on_actionIndentation_Options_triggered()
{
if(!curr_browser || curr_browser->isReadOnly())
return;
QMargins margin = curr_browser->contentsMargins();
QTextCursor cursor = curr_browser->textCursor();
QTextBlock block = cursor.block();
QTextBlockFormat blockFormat = block.blockFormat();
int left = blockFormat.indent(), right = margin.right() - blockFormat.rightMargin();
indentOptions *i = new indentOptions(this, &left, &right);
i->show();
connect(i, &indentOptions::dialogAccepted, this, [=](){
if(left + right <= 14){
on_actionIncrease_Indent_triggered(left, right);
}
i->deleteLater();
});
}
indentOptions::indentOptions(QWidget *parent, int* left, int* right) :
QDialog(parent),
ui(new Ui::indentOptions)
{
ui->setupUi(this);
this->left = left;
this->right = right;
setWindowTitle("Set Indentation");
ui->textEdit_left->setText(QString::number(*left));
ui->textEdit_right->setText(QString::number(*right));
}
答案1
得分: 1
注意,您初始化了ui->textEdit_left
的文本,该文本的值是通过指针left
获取的,这不会在值和文本之间创建任何绑定,当用户编辑文本时,left
的值不会自动更改。
即使它们被绑定了,也不会起作用,因为lambda函数通过值而不是引用捕获了left
,所以对于lambda函数来说,left
始终等于blockFormat.indent()
(lambda保存值的副本而不是引用)。
即使它们被绑定了,而且left
是通过引用捕获的,也不会起作用,因为局部变量left
在用户接受对话框时会被销毁,因为对话框不是模态的,指向left
的指针和引用将在那时无效,访问无效指针上的值会导致未定义行为(SEGFAULT或随机值)。
要获取用户输入的内容,您需要访问编辑的文本并将其转换回整数。为此,您需要按照我之前建议的方式实现getter函数。
class indentOptions {
...
public:
int left() const;
int right() const;
}
int indentOptions::left() const {
return ui->textEdit_left->text().toInt();
}
int indentOptions::right() const {
return ui->textEdit_right->text().toInt();
}
connect(i, &indentOptions::dialogAccepted, this, [=](){
int left = i->left();
int right = i->right();
if(left + right <= 14){
on_actionIncrease_Indent_triggered(left, right);
}
i->deleteLater();
});
您可以通过在indentOptions
内部保留初始值的副本(而不是指针)并返回它们来处理用户输入无效(非数字)文本的情况。
class indentOptions {
...
indentOptions(QWidget *parent, int left, int right);
protected:
int m_left;
int m_right;
}
indentOptions::indentOptions(QWidget *parent, int left, int right) : QDialog(parent),
ui(new Ui::indentOptions), m_left(left), m_right(right) {
...
}
int indentOptions::left() const {
bool ok;
int value = ui->textEdit_left->text().toInt(&ok);
if (ok) {
return value;
}
return m_left;
}
英文:
Notice that you initialized ui->textEdit_left
s text with value obtained through the pointer left
, this doesn't create any binding between value and text, when user edits text, value of left
does not change automagicaly.
Even if they were bounded, it wont work, since lambda function captured left
by value not by reference, so left
is always equals to blockFormat.indent()
for lambda function (lambda holds copy of value not reference to it).
Even if they were bounded and left
was captured by reference, it wont work, since local variable left
is destroyed by the time user accepts dialog, since dialog is not modal, pointers and references to left
will be invalid by then, accessing values over invalid pointers leads to undefined behaviour (SEGFAULT or random value).
To get what user inputs you need to access edit's text and convert it back to int. To do that you need to implement getter functions as I suggested before.
class indentOptions {
...
public:
int left() const;
int right() const;
}
int indentOptions::left() const {
return ui->textEdit_left->text().toInt();
}
int indentOptions::right() const {
return ui->textEdit_right->text().toInt();
}
connect(i, &indentOptions::dialogAccepted, this, [=](){
int left = i->left();
int right = i->right();
if(left + right <= 14){
on_actionIncrease_Indent_triggered(left, right);
}
i->deleteLater();
});
You can cover cases when used inputs invalid (nonnumber) text by holding copies of initial values (not pointers) inside indentOptions
and returning them instead.
class indentOptions {
...
indentOptions(QWidget *parent, int left, int right);
protected:
int m_left;
int m_right;
}
indentOptions::indentOptions(QWidget *parent, int left, int right) : QDialog(parent),
ui(new Ui::indentOptions), m_left(left), m_right(right) {
...
}
int indentOptions::left() const {
bool ok;
int value = ui->textEdit_left->text().toInt(&ok);
if (ok) {
return value;
}
return m_left;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论