Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Создание умного QTextEdit
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt GUI
dzyk
Задача:
Создание приложения на Qt - основным элементом является текстовое поле. Пользователь вводит текстовую информацию и она обрабатывается фоновым процессом, в котором с помощью регулярных выражений анализируется введенный текст. В конечном итоге пользователь видит как раскрашивается/маркируется им введенный текст, а приложение помещает куски текста в базу данных.

Проблема в том, что в отличии от текстовых редакторов с подсветской синтаксиса языков, анализ введенного текста слишком сложный.

Вопросы:
  1. Подскажите какой путь решения будет оптимальным? Приложение должно работать быстро, без дискомфорта для пользователя.
  2. Желательно, чтобы пользователь смог редактировать алгоритм анализа введенного текста.
  3. Какой класс взять за базовый? QTextEdit? QTextBrowser? QPaint?
ViGOur
Цитата(dzyk @ 13.4.2008, 19:39) *
Вопросы:
  1. Подскажите какой путь решения будет оптимальным? Приложение должно работать быстро, без дискомфорта для пользователя.
  2. Желательно, чтобы пользователь смог редактировать алгоритм анализа введенного текста.
  3. Какой класс взять за базовый? QTextEdit? QTextBrowser? QPaint?
1. Чтобы приложение работало быстро, тебе нужно:
  1. Делать обрабутку текста и прочее в другом потоке.
  2. Создать поле статуса, в котором пользователь будет видеть статус выполения
  3. Если это долгоиграящий процесс, то предусмотреть кнопку отмены обработки.


2. А в чем в данном пункте собственно проблема?

3. По тому ТЗ, что ты описал, я бы выбрал QTextEdit.
dzyk
ViGOur, спасибо за совет.

Проблема такая: немогу получить доступ к объекту TextEdit главного потока приложения из дочернего потока.

В то время когда обращаешься к объекту, программа просто "убивается операционкой".
Выкладываю код. Он основан на примере из книги Бланшета, там в разделе 18 как раз разбирают, как использовать объект главного потока.

main.cpp
#include <QApplication>

#include "textwindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    TextWindow textWin;
    textWin.resize(300, 200);
    textWin.show();
    return app.exec();
}


textwindow.h

#ifndef TEXTWINDOW_H
#define TEXTWINDOW_H

#include <QMainWindow>
#include <QtGui>
#include "transactionthread.h"

class TextWindow : public QMainWindow
{
    Q_OBJECT

public:
    TextWindow();
    
protected:

private slots:
    void setTextExample();
    void allTransactionsDone();

private:
    TransactionThread thread;
    QTextEdit *textEdit;
    QPushButton *pushButton;
    
};

#endif


textwindow.cpp
#include <QtGui>

#include "textwindow.h"


TextWindow::TextWindow()
{  
    textEdit = new QTextEdit;
    pushButton = new QPushButton;
    setCentralWidget(textEdit);
    setMenuWidget(pushButton);
    pushButton->setText("Start setText from child thread");
    
    thread.setTextEdit(textEdit);
    
    statusBar()->showMessage(tr("Ready"), 2000);

    connect(&thread, SIGNAL(transactionStarted(const QString &)),
            statusBar(), SLOT(showMessage(const QString &)));
    connect(&thread, SIGNAL(finished()),
            this, SLOT(allTransactionsDone()));    
    connect(pushButton,SIGNAL(clicked()),
            this,SLOT(setTextExample()));            

}

void TextWindow::setTextExample()
{
    thread.addTransaction(new SetTextTransaction());
}


void TextWindow::allTransactionsDone()
{
    textEdit->setPlainText(thread.textedit_f()->toPlainText());
    statusBar()->showMessage(tr("Ready"), 2000);
}


transactionthread.h
#ifndef TRANSACTIONTHREAD_H
#define TRANSACTIONTHREAD_H

#include <QtGui>
#include <QMutex>
#include <QThread>
#include <QQueue>

class Transaction
{
public:
    virtual ~Transaction() { }

    virtual QTextEdit* applik(QTextEdit *textEdit_th)=0;
    virtual QString message() = 0;
};

class SetTextTransaction : public Transaction
{
public:
    SetTextTransaction();
    QTextEdit* applik(QTextEdit *textEdit_th);
    QString message();

};


class TransactionThread : public QThread
{
    Q_OBJECT

public:
    void addTransaction(Transaction *transact);
    void setTextEdit(QTextEdit *textEdit_th_2);
    QTextEdit* textedit_f();


signals:
    void transactionStarted(const QString &message);

protected:
    void run();

private:
    QMutex mutex;
    QTextEdit *currentTextEdit;
    QQueue<Transaction *> transactions;
};

#endif


transactionthread.cpp
#include <QtGui>

#include "transactionthread.h"

using namespace std;

SetTextTransaction::SetTextTransaction()
{
    
}

QTextEdit* SetTextTransaction::applik(QTextEdit *textEdit_th)
{
    textEdit_th->setPlainText("eto ThreadChild napisal");
    return textEdit_th;
}

QString SetTextTransaction::message()
{  
        return QObject::tr("TredChild pishet v textedit...");
}

void TransactionThread::addTransaction(Transaction *transact)
{
    QMutexLocker locker(&mutex);
    transactions.enqueue(transact);
    if (!isRunning())
        start();
}

void TransactionThread::run()
{
    Transaction *transact;

    forever {
        mutex.lock();
        if (transactions.isEmpty()) {
            mutex.unlock();
            break;
        }
        QTextEdit *oldTextEdit = currentTextEdit;
        transact = transactions.dequeue();
        mutex.unlock();

        emit transactionStarted(transact->message());
        QTextEdit *newTextEdit = transact->applik(oldTextEdit);
        delete transact;

        mutex.lock();
        currentTextEdit = newTextEdit;
        mutex.unlock();
    }
}


void TransactionThread::setTextEdit(QTextEdit *textEdit_th_2)
{
    QMutexLocker locker(&mutex);
    currentTextEdit = textEdit_th_2;
}



QTextEdit* TransactionThread::textedit_f(){
  QMutexLocker locker(&mutex);
    return currentTextEdit;
}
dzyk
Ну понял я что сделал не так :)

вообщем объект то не создал
textEdit_th= new QTextEdit;
в строках кода transactionthred.cpp нужно было создать объект то, вот так:
QTextEdit* SetTextTransaction::applik(QTextEdit *textEdit_th)
{
    textEdit_th= new QTextEdit;
    textEdit_th->setPlainText("eto ThreadChild napisal");
    return textEdit_th;
}


p.s. Как же помогает переписка самого с собой
dzyk
А вообще извращение создавать новые объекты QTextEdit во втором потоке?
Может лучше QString'ом оперировать?
ViGOur
Цитата(dzyk @ 14.4.2008, 18:35) *
А вообще извращение создавать новые объекты QTextEdit во втором потоке?
Может лучше QString'ом оперировать?
НЕ понял что ты имеешь ввиду.

Но единственное запомни, сигналы будут обрабатываться в том потоке, в котором создан принимающий их объект, если тебя это устраивает, то все в порядке.
Tonal
В Qt, только в главном потоке можно создавать и оперировать виджетми.
В остальных - низя.
Так что передавай QString.
dzyk
Ситуация такая. Написал немного кода. Создается второй поток и через определенные интервалы времени берет текстовое содержимое из TextEdit'а главного потока. И пока пользователь набирает документ - анализирует текст, сортирует его по базам данных, а свою работу показывает изменением цвета, шрифта, (стиля). И делает это просто, вставляя кусок измененного текста в тот же TextEdit главного потока взамен существующего нераскрашеного куска....

Проблема в том, что когда документ достигает среднего размера. Копирование и вставка текста происходит с мерцанием и подрагиванием скроллера... А это ваЩЕ недопустимо.

Как же быть? Неужели создавать свой класс, производный от QPaint?.... чего очень не хочется.

Может посоветуете что?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.