2012-05-09 19 views
0

メニューボタンが押されたときにQPlainTextEditのテキストをインデントしたいとします。ボタンが押されたとき、私は現在選択されている行がインデントされていない場合、現在の行をインデントします。現在、コードは1行で動作しますが、インデントを行うと行の最後の部分が消えるようになります。例えば、私が行:"Artificial Intelligence stands no chance against Natural Stupidity."を持っている場合、字下げの後にそれはちょうど:" Artificial Intelligence stands no chance against Natural Stupidiであり、その後、私はその行に書き始めます。また、文章の一部が消えてから、その行にカーソルを置いたり、カーソルを置いたりすると、プログラムがクラッシュします。QtプログラムがクラッシュするQTextCursorでQTextEditが変更される

コード:

void MainWindow::on_action_Indent_triggered() 
{ 
    Document* doc = dynamic_cast<Document*>(ui->tabsManager->currentWidget()); 
    QTextCursor cursor = doc->textArea->textCursor(); 
    cursor.beginEditBlock(); 

    // If ther is no text selected... 
    if (cursor.selection().isEmpty()) { 
     cursor.movePosition(QTextCursor::StartOfLine); 
     cursor.insertText(this->tabLength); 
    } else { // If the selection is not empty... 
     cursor.beginEditBlock(); 

     // Save selection start and end 
     int start = cursor.selectionStart(); 
     int end = cursor.selectionEnd(); 
     cursor.clearSelection(); 

     // Set end to the end of line of the selected line 
     cursor.setPosition(end); 
     cursor.movePosition(QTextCursor::EndOfLine); 
     end = cursor.position(); 

     // Set cursor to the start of the first selected line 
     cursor.setPosition(start); 
     cursor.movePosition(QTextCursor::StartOfLine); 
     start = cursor.position(); 

     // While still in the selection, add " " to the start of each line 
     do { 
      cursor.movePosition(QTextCursor::StartOfLine); 
      cursor.insertText(this->tabLength); 
      end += this->tabLength.count(); 
      cursor.movePosition(QTextCursor::EndOfLine); 
     } while (cursor.position() < end && cursor.movePosition(QTextCursor::Down)); 

     // Select the changed areatabLenght 
     cursor.clearSelection(); 
     cursor.setPosition(start); 
     while (cursor.position() < end) 
      cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); 
    } 
    // Set the cursor in the GUI 
    doc->textArea->setTextCursor(cursor); 
    cursor.endEditBlock(); 
} 

ドキュメントは、クラスであるおよびTextAreaはQTextPlainEditです。 this-> tabLengthは ""の値を持つQStringです

答えて

4

問題は非常に簡単です:endEditBlock()より多くの時間をbeginEditBlock()と呼んでいます。 } else {の直後にbeginEditBlock()コールを削除します。私はこの問題を再現することができ、[begin|end]EditBlock()と一致すると実際に修正されます。

以下は、自己完結型の例です。

# indenttest.pro 
CONFIG += qt gui 
SOURCES += indenttest.cpp 
// indenttest.cpp 
#include <cmath> 
#include <QWidget> 
#include <QVBoxLayout> 
#include <QPlainTextEdit> 
#include <QPushButton> 
#include <QTextCursor> 
#include <QTextDocumentFragment> 
#include <QApplication> 

// 

class QPlainTextEdit; 
class MainWindow : public QWidget 
{ 
    Q_OBJECT 
public: 
    explicit MainWindow(QWidget *parent = 0); 

public slots: 
    void on_indent(); 

private: 
    const QString tabLength; 
    QPlainTextEdit * textArea; 
}; 

// 

MainWindow::MainWindow(QWidget *parent) : 
    QWidget(parent), 
    tabLength(" ") 
{ 
    QVBoxLayout * layout = new QVBoxLayout(this); 
    QPushButton * btn = new QPushButton("Indent", this); 
    layout->addWidget(btn); 
    textArea = new QPlainTextEdit(this); 
    textArea->setPlainText("foo\nbar\nbaz\nbat"); 
    layout->addWidget(textArea); 
    connect(btn, SIGNAL(clicked()), SLOT(on_indent())); 

} 

void MainWindow::on_indent() 
{ 
    QTextCursor cursor = textArea->textCursor(); 
    cursor.beginEditBlock(); 

    // If ther is no text selected... 
    if (cursor.selection().isEmpty()) { 
     cursor.movePosition(QTextCursor::StartOfLine); 
     cursor.insertText(this->tabLength); 
    } else { // If the selection is not empty... 
     //cursor.beginEditBlock(); 

     // Save selection start and end 
     int start = cursor.selectionStart(); 
     int end = cursor.selectionEnd(); 
     //cursor.clearSelection(); 

     // Set end to the end of line of the selected line 
     cursor.setPosition(end); 
     cursor.movePosition(QTextCursor::EndOfLine); 
     end = cursor.position(); 

     // Set cursor to the start of the first selected line 
     cursor.setPosition(start); 
     cursor.movePosition(QTextCursor::StartOfLine); 
     start = cursor.position(); 

     // While still in the selection, add " " to the start of each line 
     do { 
      cursor.movePosition(QTextCursor::StartOfLine); 
      cursor.insertText(this->tabLength); 
      end += this->tabLength.count(); 
      cursor.movePosition(QTextCursor::EndOfLine); 
     } while (cursor.position() < end && cursor.movePosition(QTextCursor::Down)); 

     // Select the changed areatabLenght 
     cursor.clearSelection(); 
     cursor.setPosition(start); 
     while (cursor.position() < end) 
      cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); 
    } 
    // Set the cursor in the GUI 
    textArea->setTextCursor(cursor); 
    cursor.endEditBlock(); 
} 

int main(int argc, char** argv) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    return a.exec(); 
} 

#include "indenttest.moc" 
関連する問題