crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Создание умного QTextEdit, соориентируйте меня
dzyk
  опции профиля:
сообщение 13.4.2008, 18:39
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 13.4.2008
Пользователь №: 148

Спасибо сказали: 0 раз(а)




Репутация:   0  


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

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

Вопросы:
  1. Подскажите какой путь решения будет оптимальным? Приложение должно работать быстро, без дискомфорта для пользователя.
  2. Желательно, чтобы пользователь смог редактировать алгоритм анализа введенного текста.
  3. Какой класс взять за базовый? QTextEdit? QTextBrowser? QPaint?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 13.4.2008, 20:17
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


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


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

3. По тому ТЗ, что ты описал, я бы выбрал QTextEdit.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
dzyk
  опции профиля:
сообщение 14.4.2008, 16:31
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 13.4.2008
Пользователь №: 148

Спасибо сказали: 0 раз(а)




Репутация:   0  


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
  опции профиля:
сообщение 14.4.2008, 17:21
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 13.4.2008
Пользователь №: 148

Спасибо сказали: 0 раз(а)




Репутация:   0  


Ну понял я что сделал не так :)

вообщем объект то не создал
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
  опции профиля:
сообщение 14.4.2008, 17:35
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 13.4.2008
Пользователь №: 148

Спасибо сказали: 0 раз(а)




Репутация:   0  


А вообще извращение создавать новые объекты QTextEdit во втором потоке?
Может лучше QString'ом оперировать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 14.4.2008, 17:53
Сообщение #6


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


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

Но единственное запомни, сигналы будут обрабатываться в том потоке, в котором создан принимающий их объект, если тебя это устраивает, то все в порядке.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 14.4.2008, 18:02
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


В Qt, только в главном потоке можно создавать и оперировать виджетми.
В остальных - низя.
Так что передавай QString.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
dzyk
  опции профиля:
сообщение 16.4.2008, 15:23
Сообщение #8


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 13.4.2008
Пользователь №: 148

Спасибо сказали: 0 раз(а)




Репутация:   0  


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

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

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

Может посоветуете что?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 1:40