Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Как реализовать аналог бегущей строки?


Автор: KL7 27.7.2009, 12:28
Для определенных задумок необходим аналог QLineEdit, но с полным контролем горизонтального расположения текста... 
Будем считать что надо реализовать нециклическую бегущую строку (прям как в новостях  smile )... 

Анимационная составляющая мне кажется не проблемой (освоюсь с таймерами и справлюсь наверно), но проблема в том, что мне нужно плавное движение текста, т.е. возможность при необходимости передвинуть текст скажем на 1px... Так же необходима грамотная обработка виджета справа и слева, т.е. как же будут появляться и исчезать символы, после того, как они появились в видимой области или покинули ее...

Как ето можно реализовать? Идеи у меня есть, но пока они слишком абстрактны... 
Если у кого-то есть варианты, буду благодарен за любые предложения  smile 

Автор: andrew_121 27.7.2009, 13:29
Что-то вроде:
Код

class MyLineEdit: public QLineEdit, public QThread {
};

По моему, нужно копать в сторону QPaintDevice. Не уверен.

Автор: Любитель 27.7.2009, 13:40
Тебе нужно только отображение данных или и редактирование тоже?

Автор: pan2004 27.7.2009, 15:38
Делаешь свой виджет, и пишешь в нем свою paintEvent(), в котором выводишь строку в зависимости от QTimeLine. Можно и с субпиксельной точностью, благо QPainter поддерживает дробные координаты
Если нужно редактирование, при щелчке заменяешь его на обычный QLineEdit. Я думаю, бегающую строку неудобно редактировать в анимированном виде)

Автор: SABROG 27.7.2009, 16:04
http://qt.shamangrad.net/doku.php?id=%D0%B1%D0%B5%D0%B3%D1%83%D1%89%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B0, может почерпнешь какую-нибудь идею.

Автор: KL7 27.7.2009, 21:17
Цитата(pan2004 @  27.7.2009,  15:38 Найти цитируемый пост)
Делаешь свой виджет, и пишешь в нем свою paintEvent(), в котором выводишь строку в зависимости от QTimeLine. Можно и с субпиксельной точностью, благо QPainter поддерживает дробные координаты
Если нужно редактирование, при щелчке заменяешь его на обычный QLineEdit. Я думаю, бегающую строку неудобно редактировать в анимированном виде)

спс... но в таком абстрактном виде я тоже знаю, как сделать  smile  мне надо более конкретная помощь, как же именно добавлять и удалять символы, как их хранить и все остальное... я посмотрел на QFontMetrics - етот класс похоже позволяет получить исчерпывающую информацию о геометрических характеристиках текста, а ето уже хорошо... 


Цитата(SABROG @  27.7.2009,  16:04 Найти цитируемый пост)
Вот, может почерпнешь какую-нибудь идею.

спс, сейчас будем вникать  smile 

Автор: KL7 28.7.2009, 21:34
SABROG, как выяснилось, в исходниках представлен "простой" вариант бегущей строки, в которой текст сдвигается посимвольно... мне же хотелось бы иметь попиксельный вариант...

в общем я начал писать свой виджет =)

вопрос первый:
текст я буду рисовать в нужной позиции, используя QPainter, т.е. в конечном счете текст превратится в изображение... но мне необходимо, чтобы в окне был виден только та часть текста, которая находится внутри моего виджета...
для етого надо использовать ClipArea?

в свою очередь мне хотелось бы, чтобы виджет был ограничен рамкой, схожей с рамкой QLineEdit, которая с радостью подвергается изменениям через таблицы стилей: изменяется ее цвет, толщина, радиус и отступ(padding)...
как ето реализовать? чем я должен ограничить свой виджет для таких целей и как ето сделать? 
судя по документации QLineEdit рисует рамку через QFrame (весьма логично), искользуя свойства из QStyleOptionFrame... ето можно сделать через drawPrimitive, используя все те же свойства... но как инициализировать QStyleOptionFrame используя правила из stylesheet-файла? и как потом получить размер и положение области, которая находится полностью внутри QFrame (желательно с учетом padding)? если ее получить, то она может выступать в качестве ClipArea...

дальше пока все выглядит весьма прозрачно... 
рисую текст в нужной позиции (все что вне виджета будет просто оставаться невидимым), а по таймеру пересчитываю позиции и если нужно редактирую отображаемый текст (если символ уже гарантированно вылез из поля виджета, то он просто удаляется из строки, а при необходимости справа добавляются новые символы)...

Автор: KL7 4.8.2009, 11:45
пишу потиху свой виджет... возникло пару вопросов...

1.  Мой виджет путем drawPrimitive обретает вокруг себя рамочку... ета рамочка рисуется с учетом всех stylesheet-свойств, в том числе padding... потом, используя SE_FrameContent, я получаю прямоугольник, расположенный внутри рамочки и внутри padding-a, в котором я рисую свой текст...
а теперь мне надо получить точно такой же прямоугольник, но уже содержащий padding-область... ето прямоугольник я хочу залить 50/50 двумя фоновыми цветами... но я так и не смог получить ни сам треугольник прямоугольник, ни размеры padding-a (можно наверно самому проанализировать stylesheet и из него вытянуть, например, "padding: 5px", но может есть более приемлемые методы?)

2. Мой виджет подразумевает ввод текста... или скорее не ввод, а обработку текста... вобщем он должен особым образом реагировать на нажатия клавиш, отвечающих за печатные символы... как ето грамотно сделать? что надо работать с keyPressEvent - ето мне понятно... про модификаторы (shift) также что-то читал, но общая схема пока не понятна...

буду благодарен за помощь...

Автор: SABROG 4.8.2009, 12:41
Цитата(KL7 @  4.8.2009,  11:45 Найти цитируемый пост)
прямоугольник


Цитата(KL7 @  4.8.2009,  11:45 Найти цитируемый пост)
треугольник

Вероятно опечатка?

Ты выбрал для себя не простую задачу. Мало у кого есть опыт рисования собственного виджета, а те у кого он есть ввязываться в это не будут, т.к. прекрасно понимают сколько там еще геморроя впереди. Я как-то заморачивался с собственным titlebar'ом и чужим combobox'ом, больше мне не хочется в это втягиваться. Могу лишь посоветовать изучать исходники Qt и исходники чужих виджетов.

Автор: KL7 4.8.2009, 15:06
Цитата(SABROG @  4.8.2009,  12:41 Найти цитируемый пост)
Вероятно опечатка?

так и есть =)

Цитата(SABROG @  4.8.2009,  12:41 Найти цитируемый пост)
Ты выбрал для себя не простую задачу. Мало у кого есть опыт рисования собственного виджета, а те у кого он есть ввязываться в это не будут, т.к. прекрасно понимают сколько там еще геморроя впереди. Я как-то заморачивался с собственным titlebar'ом и чужим combobox'ом, больше мне не хочется в это втягиваться. Могу лишь посоветовать изучать исходники Qt и исходники чужих виджетов. 

спасибо, обнадежили =)
ну я не имею наполеоновских планов... просто пока у меня нет ни одной конкретной задачи, вот решил что-нибудь пописать, но чтобы интересно было... не получится - значит не получится, но опыт какой-то точно получу..

если рисовать совсем свой виджет без поддержки stylesheet-ов, то все не так уж и сложно... сам как-нибудь обработал отступы, рамочки и можно даже для всего сделать настройки... 
но я хотел попытаться адаптировать самодельный виджет под Qt-стили... но все оказалось труднее, чем я предполагал, поскольку прямого доступа к элементам стиля не имеешь, а предлагаемые примитивы (элементы виджетов, различные области) похоже охватывают не все аспекты...

а исходники... все конечно хорошо, но сложно... я пытался изучать QLineEdit... какую-то информацию оттуда почерпнул, но в реализации класса широко применяются свои внутренние технологии, которые в "общественном" Qt никак не представлены (или просто не описаны)... так, например, там используется какой-то удивительный заголовочный private-файл, различные макросы и те же элементы стиля (отступы, толщина и ширина) берутся из какого-то удивительного объекта, сущность которого я пока не осознал... возможно в етом и нет необходимости...

буду ковыряться - до сентября еще месяц каникул =) 
и все же если будут предложения - буду признателен...
тут пожалуй основная проблема - внутри чего рисовать етот текст... был бы QFrame более навороченным (возможно я его плохо знаю  smile ), было бы наверно проще... но по умолчанию ето просто рамочка без каких-либо перспектив...

Автор: SABROG 4.8.2009, 15:21
Посмотри может исходники виджетов http://www.wysota.eu.org/wwwidgets/ и тут http://www.qt-apps.org/index.php?xcontentmode=4298

Автор: KL7 4.8.2009, 18:05
Цитата(SABROG @  4.8.2009,  15:21 Найти цитируемый пост)
Посмотри может исходники виджетов http://www.wysota.eu.org/wwwidgets/ и тут http://www.qt-apps.org/index.php?xcontentmode=4298 

спасибо... буду изучать... хотя wwwidget-ы написаны в том же стиле, что и стандартные, а там мне далеко не все понятно... но буду разбираться =)

а подскажите, как получить прямоугольник, описывающий внутреннюю область рамки, которая рисуется таким вот образом:
Код

QStyleOptionFrameV3 opt;
opt.initFrom(this);
style()->drawPrimitive(QStyle::PE_Frame, &opt, &painter, this);

рамочка имеет толщину и закругления, заданные через stylesheet...
пока ето основная проблема...

Автор: SABROG 4.8.2009, 19:16
Цитата(KL7 @  4.8.2009,  18:05 Найти цитируемый пост)
описывающий внутреннюю область рамки

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

Цитата(KL7 @  4.8.2009,  18:05 Найти цитируемый пост)
рамочка имеет толщину и закругления, заданные через stylesheet...
пока ето основная проблема... 


А эти параметры нельзя получить, если в документации кликнуть на ссылку "List of all members, including inherited members"?

Автор: KL7 5.8.2009, 07:26
Цитата(SABROG @  4.8.2009,  19:16 Найти цитируемый пост)
К сожалению у меня были плохие оценки в школе, я совершенно не понимаю, что от меня требуется, когда читаю задачу.

попытаюсь объяснить доходчивее... 
http://ipicture.ru/Gallery/Viewfull/21794321.html
мне нужно любым путем получить характеристики желтого прямоугольника... буду признателен, если прямо и без иронии скажете, как ето сделать...


Цитата(SABROG @  4.8.2009,  19:16 Найти цитируемый пост)
А эти параметры нельзя получить, если в документации кликнуть на ссылку "List of all members, including inherited members"?

применительно к какому классу? QFrame-а у меня в коде нет... возможно стоит наследовать мой виджет от QFrame, но ето другой вопрос...

int QStyleOptionFrame::lineWidth пока мне ничего кроме нуля не согласился вернуть, хотя рамочка рисуется толщиной в 6 пикселей...

радиус закругления мне в принципе не нужен, но ради интереса поискал - не нашел я его нигде в Qt Assistant-e... так что этот параметр похоже нельзя получить даже "если в документации кликнуть на ссылку "List of all members, including inherited members"...

Автор: Любитель 5.8.2009, 07:50
Привязываться к стайлшитам не есть гуд. Вообще говоря - эта рамка зависит от стиля (QStyle) для текущего виджета/апилкейшена. При установке стайлшита используется прокси-стиль QStyleSheetStyle. Который.. вообще говоря вроде не экспортируется из Qt (всмысле экспортируется то - само собой, но в официальных инклюдах его нет). Далее - у него есть метод renderRule, позволяющий получить правила отображения для конкретного виджета, у коготорого метод borderRect... Одним словом - документированного способа получить толщину бордера нельзя. К сожалению, но это минус проектирования QStyle (хотя скорее - стайлшитов, ибо можно было в QStyleOption::initFrom считывать стиль виджета, а у стиля иметь методы инициализирующие ту же толщину бордера.. Как-то так.

Автор: KL7 5.8.2009, 08:35
Цитата(Любитель @  5.8.2009,  07:50 Найти цитируемый пост)
Привязываться к стайлшитам не есть гуд. 

понятно... 
и если нужна полноценная поддержка чего-то наподобие скинов, то надо читать в сторону стилей?
подумаем...

не хотелось бы разводить много тем, так что еще спрошу:
покажите, где почитать про private-классы (например, QLabel активно взаимодействует с QLabelPrivate), которые нередко в Qt используются... хоть какую-то информацию о том, каково предназначение и как использовать ету технологию... она ведь наверняка как-то обоснована...

Автор: Любитель 5.8.2009, 08:48
Цитата(KL7 @  5.8.2009,  08:35 Найти цитируемый пост)
и если нужна полноценная поддержка чего-то наподобие скинов, то надо читать в сторону стилей?

Стайлшиты реализуются через QStyleSheetStyle. Только его почему-то решили сделать недокументированным.. Но тем не менее - это один из стилей.

Цитата(KL7 @  5.8.2009,  08:35 Найти цитируемый пост)
покажите, где почитать про private-классы (например, QLabel активно взаимодействует с QLabelPrivate), которые нередко в Qt используются... хоть какую-то информацию о том, каково предназначение и как использовать ету технологию... она ведь наверняка как-то обоснована...

Ну, по сути классический с++-ный паттерн PImpl. Преимущество в отсутствии необходимости вынесения деталей в хидер. Ведь даже при изменении прайват данных класса мы должны перекомпилировать всё, что использует этот класс (всмысле использует класс, а не используется классом). Выделение же отдельного внутреннего класса + указатель на объект этого класса в хидере позволяет этого избежать.

Другими словами - это общепринятый костыль smile Впрочем, при привычке - достаточно удобный.

Автор: KL7 8.8.2009, 18:30
Цитата(Любитель @  5.8.2009,  08:48 Найти цитируемый пост)
Ну, по сути классический с++-ный паттерн PImpl.

во-первых, спасибо за информацию =) почитал, стало гораздо понятнее... пытался применить в данном проекте, но пока и без новых паттернов проблем хватает, но в будущем буду знакомится с такими вещами...

а теперь... мой виджет... функциональность реализована примерно на 80% =) Т.е. он уже почти умеет все, что должен...
но качество реализации не важное...  smile 

собственно код...

main.cpp
Код

#include <QApplication>
#include <QVBoxLayout>
#include "typingarea.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QWidget *window = new QWidget;
    window->setWindowTitle("Input Area");

    TypingArea *input = new TypingArea;
    input->setText(QString::fromLocal8Bit("Standing in the middle of the road is dangerous, you will get knocked down by the traffic from both directions."));

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addStretch(50);
    layout->addWidget(input);
    layout->addStretch(50);
    window->setLayout(layout);

    window->show();

    return app.exec();
}



typingarea.h
Код

#ifndef INPUTAREA_H
#define INPUTAREA_H

#include <QFrame>

class QBasicTimer;

class TypingArea : public QFrame{
    Q_OBJECT
public:
    TypingArea(QWidget* = 0);

    QSize sizeHint() const;
    QSize minimumSizeHint() const;

    QString getText() const;
    int getTypedTextPercent() const;
    int getFrameWidth() const;
    int getFrameRadius() const;
    int getTextMargin() const;
    QColor getFrameColor() const;
    QColor getBackColor() const;
    QColor getTypedMaskColor() const;
    QColor getTextColor() const;
    QColor getCurSymbolColor() const;
    QFont getTextFont() const;

public Q_SLOTS:
    void setText(QString, int = 0);
    void setTypedTextPercent(int);
    void setFrameWidth(int);
    void setFrameRadius(int);
    void setTextMargin(int);
    void setFrameColor(QColor);
    void setBackColor(QColor);
    void setTypedMaskColor(QColor);
    void setTextColor(QColor);
    void setCurSymbolColor(QColor);
    void setTextFont(QFont);

protected:
    void paintEvent(QPaintEvent *);
    void keyPressEvent(QKeyEvent *);
    void timerEvent(QTimerEvent *);

private:
    QBasicTimer *shiftTimer;
    
    enum {
        MIN_TEXT_LENGTH = 15,
        NORMAL_TEXT_LENGTH = 30,
        TYPED_TEXT_PERCENT = 25,
        SHIFT_STEPS = 10,
        SHIFT_INTERVAL = 10,
        CUR_SYMBOL_ZOOM = 120
    };

    QString text;
    QString errorText;
    int curSymbol;

    int typedTextPercent;
    int shift;
    int shiftStep;

    int frameWidth;
    int frameRadius;
    int textMargin;
    QColor frameColor;
    QColor backColor;
    QColor typedMaskColor;
    QColor textColor;
    QColor curSymbolColor;
    QFont textFont;

    QString frameStylesheet() const;

    QRect fullBackRect() const;
    QRect leftBackRect() const;
    QRect rightBackRect() const;
    QRect fullTextRect() const;
    QRect leftTextRect() const;
    QRect rightTextRect() const;

    int stringWidth(QString);
    void drawFrame(QPainter &);
    void drawText(QPainter &);
    void drawErrorText(QPainter &);
};

#endif



typingarea.cpp
Код

#include <QtGui>
#include "typingarea.h"

TypingArea::TypingArea(QWidget *parent) : QFrame(parent) {
    text = "";
    errorText = "";

    textFont = QFont("Comic Sans MS", 35, QFont::Bold, false);
    frameWidth = 6;
    frameRadius = 8;
    textMargin = 6;
    textColor.setRgb(129, 86, 60);
    curSymbolColor.setRgb(12, 208, 218);
    frameColor.setRgb(197, 174, 2);
    backColor.setRgb(255, 224, 97);
    typedMaskColor.setRgb(160, 160, 160, 170);

    shiftTimer = new QBasicTimer();

    typedTextPercent = TYPED_TEXT_PERCENT;
    shift = 0;

    setStyleSheet(styleSheet() + frameStylesheet());
    setFont(textFont);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    setFocusPolicy(Qt::StrongFocus);
    setFixedHeight(sizeHint().height());
}

//--------------------------------------------------------------------
//--------------------------------------------------------------------

void TypingArea::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    painter.fillRect(fullBackRect(), backColor);
    drawText(painter);
    painter.fillRect(leftBackRect(), typedMaskColor);
    if(!errorText.isEmpty()) {
        painter.fillRect(rightBackRect(), QColor(255, 0, 0, 210));
        drawErrorText(painter);
    }
    drawFrame(painter);
}

void TypingArea::keyPressEvent(QKeyEvent *event) {
    if(event->key() == Qt::Key_Backspace) {
        if(!errorText.isEmpty())
            errorText.remove(errorText.length() - 1, 1);
        update(fullBackRect());
        return;
    }

    if(event->text().isEmpty() || curSymbol >= text.length()) {
        QWidget::keyPressEvent(event);
        return;
    }

    if((errorText.isEmpty()) && (event->text()[0] == text[curSymbol])) {
        shiftTimer->stop();
        shift += fontMetrics().width(text[curSymbol]);
        shiftStep = shift / SHIFT_STEPS;
        shiftTimer->start(SHIFT_INTERVAL, this);
        curSymbol++;
    } else {
        errorText += event->text();
        update(fullBackRect());
    }
}

void TypingArea::timerEvent(QTimerEvent *event) {
    if(event->timerId() == shiftTimer->timerId()) {
        if(shift > shiftStep) {
            shift -= shiftStep;
        } else {
            shift = 0;
            shiftTimer->stop();
        }
        update(fullBackRect());
    }
}

QSize TypingArea::sizeHint() const {
    int w = NORMAL_TEXT_LENGTH * fontMetrics().width('x')
         + 2 * (textMargin + frameWidth);
    int h = fontMetrics().height() * CUR_SYMBOL_ZOOM / 100
            + 2 * (textMargin + frameWidth);

    return QSize(w, h);
}

QSize TypingArea::minimumSizeHint() const {
    int w = MIN_TEXT_LENGTH * fontMetrics().width('x')
            + 2 * (textMargin + frameWidth);
    int h = fontMetrics().height() * CUR_SYMBOL_ZOOM / 100
            + 2 * (textMargin + frameWidth);

    return QSize(w, h);
}

//--------------------------------------------------------------------
//--------------------------------------------------------------------

void TypingArea::drawFrame(QPainter &painter) {
    QStyleOptionFrameV3 opt;
    opt.initFrom(this);
    style()->drawPrimitive(QStyle::PE_Frame, &opt, &painter, this);
}

void TypingArea::drawText(QPainter &painter) {
    painter.save();
    painter.setClipRect(fullTextRect());

    QFont curSymbolFont = textFont;
    curSymbolFont.setPointSizeF(curSymbolFont.pointSizeF() * CUR_SYMBOL_ZOOM / 100);

    painter.setPen(textColor);
    painter.setFont(textFont);
    painter.drawText(leftTextRect().adjusted(0, 0, shift, 0),
            Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip,
            text.mid(0, curSymbol));

    painter.setPen(curSymbolColor);
    painter.setFont(curSymbolFont);
    painter.drawText(rightTextRect().adjusted(shift, 0, 0, 0),
            Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip,
            text.mid(curSymbol, 1));

    int curSymbolWidth = painter.fontMetrics().width(text[curSymbol]);

    painter.setPen(textColor);
    painter.setFont(textFont);
    painter.drawText(rightTextRect().adjusted(shift + curSymbolWidth, 0, 0, 0),
            Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip,
            text.mid(curSymbol + 1));

    painter.restore();
}

void TypingArea::drawErrorText(QPainter &painter) {
    painter.save();

    painter.setPen(Qt::white);
    QRect boundRect = painter.boundingRect(rightTextRect(),
            Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip, errorText);

    painter.setClipRect(rightTextRect());
    if(boundRect.width() <= rightTextRect().width())
        painter.drawText(rightTextRect(),
                Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip,
                errorText);
    else
        painter.drawText(rightTextRect(),
                Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip,
                errorText);

    painter.restore();
}


QString TypingArea::frameStylesheet() const {
    QString col = QString("rgb(%1, %2, %3)").arg(frameColor.red())
            .arg(frameColor.green()).arg(frameColor.blue());

    QString ss = QString("TypingArea { "
                "border-style: solid; "
                "border-width: %1px; "
                "border-radius: %2px;"
                "padding: %3px; "
                "border-color: %4; }").arg(frameWidth).arg(frameRadius)
                .arg(textMargin).arg(col);
    return ss;
}

int TypingArea::stringWidth(QString str) {
    QPainter painter(this);
    QRect oldRect = painter.boundingRect(rightTextRect(),
            Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip, str);
    QRect newRect = painter.boundingRect(leftTextRect(),
            Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine | Qt::NoClip, str);
    return oldRect.left() - newRect.left();
}

QRect TypingArea::leftBackRect() const {
    return fullBackRect().adjusted(0, 0, - fullBackRect().width()
            * (100 - typedTextPercent) / 100, 0);
}

QRect TypingArea::rightBackRect() const {
    return fullBackRect().adjusted(fullBackRect().width()
            * typedTextPercent / 100, 0, 0, 0);
}

QRect TypingArea::fullBackRect() const {
    return rect().adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth);
}

QRect TypingArea::leftTextRect() const {
    return leftBackRect().adjusted(textMargin, 0, 0, 0);
}

QRect TypingArea::rightTextRect() const {
    return rightBackRect().adjusted(0, 0, -textMargin, 0);
}

QRect TypingArea::fullTextRect() const {
    return fullBackRect().adjusted(textMargin, 0, -textMargin, 0);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------

QString TypingArea::getText() const { return text; }
int TypingArea::getTypedTextPercent() const { return typedTextPercent; }
int TypingArea::getFrameWidth() const { return frameWidth; }
int TypingArea::getFrameRadius() const { return frameRadius; }
int TypingArea::getTextMargin() const { return textMargin; }
QColor TypingArea::getFrameColor() const { return frameColor; }
QColor TypingArea::getBackColor() const { return backColor; }
QColor TypingArea::getTypedMaskColor() const { return typedMaskColor; }
QColor TypingArea::getTextColor() const { return textColor; }
QColor TypingArea::getCurSymbolColor() const { return curSymbolColor; }
QFont TypingArea::getTextFont() const { return textFont; }

void TypingArea::setText(QString text, int curSymbol) {
    this->text = text;
    this->curSymbol = curSymbol;
}

void TypingArea::setTypedTextPercent(int typedTextPercent) {
    this->typedTextPercent = typedTextPercent;
}

void TypingArea::setFrameWidth(int frameWidth) { this->frameWidth = frameWidth; }
void TypingArea::setFrameRadius(int frameRadius) { this->frameRadius = frameRadius; }
void TypingArea::setTextMargin(int textMargin) { this->textMargin = textMargin; }
void TypingArea::setFrameColor(QColor frameColor) { this->frameColor = frameColor; }
void TypingArea::setBackColor(QColor backColor) { this->backColor = backColor; }
void TypingArea::setTypedMaskColor(QColor typedMaskColor) {
    this->typedMaskColor = typedMaskColor;
}
void TypingArea::setTextColor(QColor textColor) { this->textColor = textColor; }
void TypingArea::setCurSymbolColor(QColor curSymbolColor) {
    this->curSymbolColor = curSymbolColor;
}
void TypingArea::setTextFont(QFont textFont) { this->textFont = textFont; }



1. Буду благодарен за любую критику (как в сторону реализации, так и в сторону грамотности кода). Только не в слишком грубой форме.

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

Анимацию я реализовал как сумел. Етот код у меня на староватом компе вроде как работает, но как только я меняю величину шрифта с 35 на 55, то все начинает жутко виснуть.
Размер шрифта должен лишь зумировать виджет, а скорость отклика должна сохранится.... Но виджет начинает реагировать гораздо хуже и буковки ползут раз в пять медленее...
Хотелось бы решить ету проблему, так что нужен совет и пояснение, что же тут не так...

Заранее приношу большие извинения за отсутствие каких-либо комментариев. 
И буду искренне благодарен, если Вы (абстрактный программист) не заленитесь почитать етот быть может не слишком достойный код...

PS
как заставить eclipse по Ctrl+Tab мирно ходить по всем вкладкам, а не только по двум последним?  smile 

Автор: SABROG 8.8.2009, 22:20
Цитата(KL7 @  8.8.2009,  18:30 Найти цитируемый пост)
1. Буду благодарен за любую критику (как в сторону реализации, так и в сторону грамотности кода). Только не в слишком грубой форме.

На самом деле хотелось бы больше скриншотов и аттач с исходниками. На форуме не удобно изучать код.

Цитата(KL7 @  8.8.2009,  18:30 Найти цитируемый пост)
    textFont = QFont("Comic Sans MS", 35, QFont::Bold, false);

Тут, я так понимаю, приносится в жертву кроссплатформенность библиотеки.

Цитата(KL7 @  8.8.2009,  18:30 Найти цитируемый пост)
class TypingArea : public QFrame{

В чем необходимость наследования от QFrame, если рамку можно нарисовать самому?

Цитата(KL7 @  8.8.2009,  18:30 Найти цитируемый пост)
class QBasicTimer;

Возможно это лишнее. Более базового таймера чем QObject::startTimer() и QObject::timerEvent() еще не придумали.

Цитата(KL7 @  8.8.2009,  18:30 Найти цитируемый пост)
QString TypingArea::getText() const { return text; }
int TypingArea::getTypedTextPercent() const { return typedTextPercent; }
int TypingArea::getFrameWidth() const { return frameWidth; }
int TypingArea::getFrameRadius() const { return frameRadius; }
int TypingArea::getTextMargin() const { return textMargin; }
QColor TypingArea::getFrameColor() const { return frameColor; }
QColor TypingArea::getBackColor() const { return backColor; }
QColor TypingArea::getTypedMaskColor() const { return typedMaskColor; }
QColor TypingArea::getTextColor() const { return textColor; }
QColor TypingArea::getCurSymbolColor() const { return curSymbolColor; }
QFont TypingArea::getTextFont() const { return textFont; }

Не знаю как остальные программисты, но я предпочитаю подобные методы оставлять в хедерах с ключевым словом inline.

Цитата(KL7 @  8.8.2009,  18:30 Найти цитируемый пост)
Но виджет начинает реагировать гораздо хуже и буковки ползут раз в пять медленее...

Надо проанализировать профайлером. Возможно косяк в коде. Может быть готовую картинку можно закэшировать и всего-лишь двигать по виджету.

Автор: KL7 9.8.2009, 00:18
Цитата(SABROG @  8.8.2009,  22:20 Найти цитируемый пост)
На самом деле хотелось бы больше скриншотов и аттач с исходниками. На форуме не удобно изучать код.

Цитата(SABROG @  8.8.2009,  22:20 Найти цитируемый пост)
Возможно это лишнее. Более базового таймера чем QObject::startTimer() и QObject::timerEvent() еще не придумали.

Цитата(SABROG @  8.8.2009,  22:20 Найти цитируемый пост)
Не знаю как остальные программисты, но я предпочитаю подобные методы оставлять в хедерах с ключевым словом inline.

завтра исправлюсь...

Цитата(SABROG @  8.8.2009,  22:20 Найти цитируемый пост)
Тут, я так понимаю, приносится в жертву кроссплатформенность библиотеки.

Что имеется ввиду? 
В принципе это значение по умолчанию временно и оно будет пересмотрено =)

Цитата(SABROG @  8.8.2009,  22:20 Найти цитируемый пост)
В чем необходимость наследования от QFrame, если рамку можно нарисовать самому?

Рамка и рисуется самостоятельно, т.е. через drawPrimitive, а наследование осталось из-за первоначальных задумок. 
Надо заменить на QWidget

Цитата(SABROG @  8.8.2009,  22:20 Найти цитируемый пост)
Надо проанализировать профайлером. Возможно косяк в коде. Может быть готовую картинку можно закэшировать и всего-лишь двигать по виджету. 

Примерно представляю, что такое профайлер, но если не трудно - задайте направление, где почитать.
Кэширование, думаю, возможно, но над етим надо поработать. Несколько вариантов более простой оптимизации уже придумал. А ошибка в коде очень вероятно... Пару дней назад я в paintEvent вызывал унаследованный от QFrame метод drawFrame - виджет перерисовывался без остановки и все сильно висло. Потратил не мало времени, пока разобрался.

Автор: SABROG 9.8.2009, 08:42
Цитата(KL7 @  9.8.2009,  00:18 Найти цитируемый пост)
Что имеется ввиду? 

Шрифт.

Цитата(KL7 @  9.8.2009,  00:18 Найти цитируемый пост)
Примерно представляю, что такое профайлер, но если не трудно - задайте направление, где почитать.

http://www.ibm.com/developerworks/ru/library/l-gnuprof/index.html

Автор: KL7 9.8.2009, 12:30
Цитата(SABROG @  9.8.2009,  08:42 Найти цитируемый пост)
Шрифт.

это я понял... Вы хотели сказать, что Comic Sans есть далеко не на всех платформах или что?

Цитата(SABROG @  9.8.2009,  08:42 Найти цитируемый пост)
gprof 

почитал... в принципе разобрался... Но судя по тому, что я нашел, для работы с qt и gprof необходимо все библиотеки пересобрать в статик с параметром -pg. Если сам не смогу решить проблему, то все же пересоберу.

Кое-какие корректировки в коде сделал. Лучше работать пока не стало.  smile 

------ edited -----
только что договорился с gprof, буду изучать...
а наибольшие временные затраты идут на drawText... чем больше (по размерам!) текст, тем труднее приходится процессору... я оптимизировал код, но все равно на большом размере шрифта подтормаживает... буду думать

Автор: DK2 26.4.2011, 22:26
Подскажите как получить значение текста из QTextEdit

Автор: borisbn 27.4.2011, 00:05
DK2, ты чего ? Задаёшь вопрос в чужой теме, в которой уже почти 2 года не было обновлений  smile  smile 

Автор: DK2 27.4.2011, 19:05
темой ошибся. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)