Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: ilyagoo от Июнь 06, 2009, 12:08



Название: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 06, 2009, 12:08
Задача: создать компонент, который бы представлял собой нечто, выполняющее функции QSpinBox и QComboBox. Т.е. окошко ввода, содержащее в себе кнопки обоих этих компонентов. Нужны следующие возможности: осуществлять ввод чисел вручную, изменять числа с некоторым шагом как в QSpinBox при нажатии соответствующей кнопки или выбирать значение из выпадающего списка как в QComboBox. Как бы это осуществить?
Первое, что приходит в голову - это наследовать от них обоих, чтобы сохранить все слоты и сигналы. Вот только QSpinBox - потомок абстрактного класса, а QComboBox - QWidget'а. Второе то, как он должен отрисовываться. Вроде это происходит через QStyleOption, но этих классов получается два QStyleOptionComboBox и QStyleOptionSpinBox. Нужно и можно ли наследовать от этих двух классов или нужен QStyleOptionComplex? Кто-нибудь что-нибудь сложнее вертикальных кнопок делал, используя стили? Любое участие приветствуется. Спасибо :)


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: spirit от Июнь 06, 2009, 12:54
ну одновременное наследование от QSpinBox & QComboBox у тебя в любом случае не получиться,
т.к. нельзя использовать множественное наследование от QObject.

можно попробовать наследоваться чисто от QSpinBox, затем добавить QToolButton
на спинбокс и по клику по QToolButton показывать вью.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 06, 2009, 13:03
Цитировать
т.к. нельзя использовать множественное наследование от QObject
в этом месте поподробнее, где это в документации сказано? или это c++ не позволяет?
из этого следует, что и от двух стилей наследовать не получится?


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: spirit от Июнь 06, 2009, 13:12
читай тут (http://doc.trolltech.com/qq/qq15-academic.html#multipleinheritance).
не понимаю причем тут стили  ???


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 06, 2009, 13:38
Цитировать
читай тут.
угу.
компоненты отрисовываются при помощи соответствующих им стилей, которые рисуют кнопки, рамки и т.д.
например,
Код:
void QStylePainter::drawPrimitive (QStyle::PE_IndicatorSpinDown, styleOption)
рисует стрелку "вниз" для QSpinBox. А так как мне нужно, чтобы компонент имел и те и другие кнопки, придется иметь дело со стилями. Но я пока только начал на них смотреть, и любая помощь более опытных товарищей была бы кстати ;)


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: spirit от Июнь 06, 2009, 13:42
компоненты отрисовываются при помощи соответствующих им стилей, которые рисуют кнопки, рамки и т.д.
например,
Код:
void QStylePainter::drawPrimitive (QStyle::PE_IndicatorSpinDown, styleOption)
рисует стрелку "вниз" для QSpinBox. А так как мне нужно, чтобы компонент имел и те и другие кнопки, придется иметь дело со стилями. Но я пока только начал на них смотреть, и любая помощь более опытных товарищей была бы кстати ;)
я знаю через что отрисовываются контролы, если тебе хочется все сделать ручками то вперед,
но я ж тебе предложил быстрый вариант.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: lit-uriy от Июнь 06, 2009, 13:44
Про наследование есть и в документации: qthelp://com.trolltech.qt.442/qdoc/moc.html раздел "Multiple Inheritance Requires QObject to Be First"


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 06, 2009, 13:48
ручками хочется сделать не из-за того, что я упертый и мне лень к QLineEdit приклеить несколько кнопок, а из-за желания не отступать от концепции Qt. и знать-то я знаю, но вот опыта использования хватило только на вертикальную кнопку, да и то, используя чужой код ;D


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 06, 2009, 13:51
Про наследование есть и в документации: qthelp://com.trolltech.qt.442/qdoc/moc.html раздел "Multiple Inheritance Requires QObject to Be First"

Also, be sure that only the first inherited class is a QObject. так все-таки можно?


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: lit-uriy от Июнь 06, 2009, 14:11
QObject и его наследники, разумеется. После примера идёт ещё одно предложение, о том, что виртуальное наследование для QObject не поддерживается.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 06, 2009, 14:40
короче говоря, наследовать от двух потомков QObject можно только при виртуальном наследовании, которое не поддерживается, то есть нельзя :)
со стилями получается та же история...
выходит, что нужно наследовать QStyleOptionComplex? а как при этом управлять новыми контролами? это абстрактный вопрос, т.к. я пока только рассуждаю. было бы неплохо посмотреть на код чего-нибудь похожего. кстати, а для чего нужны классы, оканчивающиеся ...Private? мне придется делать такой же?


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: spirit от Июнь 06, 2009, 15:10
кстати, а для чего нужны классы, оканчивающиеся ...Private? мне придется делать такой же?
почитай про pimpl.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: lit-uriy от Июнь 06, 2009, 15:19
ilyagoo, посмотри статейку свежую:
http://labs.trolltech.com/blogs/2009/06/05/cross-platform-code-and-styles/

Там и исходник готовый есть.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 06, 2009, 16:23
Цитировать
почитай про pimpl
посмотрю, спасибо.

Цитировать
http://labs.trolltech.com/blogs/2009/06/05/cross-platform-code-and-styles/
интересно, но совсем не о том. это про QStyle, а мне нужен QStyleOption.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 08, 2009, 10:57
начало приблизительно такое:

spincombobox.h

Код:
#ifndef SPINCOMBOBOX_H
#define SPINCOMBOBOX_H

#include <QSpinBox>
#include <QStyleOption>

class TStyleOptionSpinComboBox : public QStyleOptionSpinBox
{

public:

   enum { SO_SpinComboBox = SO_ComplexCustomBase + 1 };

   enum StyleOptionType { Type = SO_SpinComboBox };
   enum StyleOptionVersion { Version = 1 };

   QAbstractSpinBox::ButtonSymbols buttonSymbols;
   QAbstractSpinBox::StepEnabled stepEnabled;

   bool frame;
   bool editable;
   QRect popupRect;
   QString currentText;
   QIcon currentIcon;
   QSize iconSize;

   TStyleOptionSpinComboBox();
};

class TSpinComboBox : public QSpinBox
{
   Q_OBJECT

public:
   TSpinComboBox(QWidget *parent = 0);
   ~TSpinComboBox();


protected:

   void paintEvent(QPaintEvent *event);

private:

};

#endif // SPINCOMBOBOX_H

spincombobox.cpp

Код:
#include "spincombobox.h"
#include <QPainter>
#include <QStylePainter>
#include <QtDebug>

TStyleOptionSpinComboBox::TStyleOptionSpinComboBox()
:  /*QStyleOptionComplex(Version, SO_SpinComboBox),*/ buttonSymbols(QAbstractSpinBox::UpDownArrows),
   stepEnabled(QAbstractSpinBox::StepNone), frame(true), editable(false)
{
   activeSubControls = QStyle::SC_SpinBoxDown | QStyle::SC_ComboBoxArrow; // нужно ли?
}

TSpinComboBox::TSpinComboBox(QWidget *parent)
   : QSpinBox(parent)
{

}

TSpinComboBox::~TSpinComboBox()
{

}

void TSpinComboBox::paintEvent(QPaintEvent *event)
{
   TStyleOptionSpinComboBox option;
   option.initFrom(this);                                        // инициализация стиля SpinBox

   QStylePainter spainter(this);
   spainter.drawComplexControl(QStyle::CC_SpinBox, option);
   spainter.drawComplexControl(QStyle::CC_ComboBox, option);
}

чего здесь не хватает? возможно это инициализация части ComboBox? начало-то хоть адекватное?


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 09, 2009, 10:21
да, что-то все страньше и страньше...

Код:
   QStyleOptionComboBox optCB;
   optCB.initFrom(this);
   optCB.frame = 1;
   optCB.direction = Qt::RightToLeft;
   optCB.subControls = QStyle::SC_ComboBoxArrow;
   spainter.drawComplexControl(QStyle::CC_ComboBox, optCB);


   QStyleOptionSpinBox optSB;
   optSB.initFrom(this);
   optSB.frame = 1;

   optSB.subControls =  QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
   spainter.drawComplexControl(QStyle::CC_SpinBox, optSB);

этот код рисует нужные кнопки, если наследовать от QWidget. если наследовать от QSpinBox (так хоть какие-нибудь методы не придется переписывать), кнопка spinbox'а не видна. если paintEvent пустой, все равно рисуется QSpinBox без кнопок, но область, где они должны быть, остается кликабельна. мужчины, хелп нужен ???


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: panAlexey от Июнь 09, 2009, 10:44
Исходники.
class uoColorChooser;
Может поможет.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 09, 2009, 11:42
Исходники.
class uoColorChooser;
Может поможет.
спасибо, может и поможет. только этот компонент наследует от QFrame, и функции QComboBox и QSpinBox нужно писать самому :(
но это очень похоже на единственный реальный вариант. другой - это свой стиль со своими функциями рисования и пересчета координат, это гораздо сложнее, и придется устанавливать этот стиль для приложения...


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: panAlexey от Июнь 09, 2009, 14:43
другой - это свой стиль со своими функциями рисования и пересчета координат, это гораздо сложнее, и придется устанавливать этот стиль для приложения...
посмотри класс uoFrameChooser там-же.
используются пересчеты координат и прочая хрень.
он простой ка мыло.
ниче там сложного нет.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 09, 2009, 16:19
видел я его. там-то пересчеты простые, я говорил про свой стиль.
вроде я уже что-то нарисовал, даже кнопочки нажимаются :)
очередная загвоздка с выводом текста и курсора. посмотрел на QLineEdit, сижу, чешу репу... что ж у них там все так наворочено >:(

в uoWidget все более или менее ясно, там просто в поле ввода рисуется цвет...

закрадывается подлая мыслишка, а не попробовать ли сделать наследника QSpinBox, вот только как влепить туда еще одну кнопку? допустим, что отлавливать нажатия на нее я смогу в eventFilter, но как заставить его отрисовывать текст с учетом этой лишней кнопки - неясно ???

есть ли у вас идеи, господа?


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: EhTemka от Июнь 09, 2009, 22:00
Я может не понимаю сути проблемы. Чем не устраивает комбинирование уже существующих виджетов? К примеру QSpinBox + QToolButton + таблица popup.

Или тут желание возиться(разбираться) в стилях?


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: panAlexey от Июнь 09, 2009, 22:50
очень похоже на выклянчивание готового решения.
если бы мне было нужно оно, я бы давно сделал. нифига там сложного нету...


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 10, 2009, 08:24
очень похоже на выклянчивание готового решения.
если бы мне было нужно оно, я бы давно сделал. нифига там сложного нету...

готового решения я тут не ищу, тем более, что чаще вижу малограмотный стёб, нежели адекватные ответы ;)

Я может не понимаю сути проблемы. Чем не устраивает комбинирование уже существующих виджетов? К примеру QSpinBox + QToolButton + таблица popup.

Или тут желание возиться(разбираться) в стилях?

изначально так и было, но выглядит это убого, хотелось бы все кнопки вбить в фрейм поля ввода. со стилями почти все ясно, осталось разобраться в том, как отображает себя самый примитивный QLineEdit.


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: spectre71 от Июнь 10, 2009, 09:15
Я может не понимаю сути проблемы. Чем не устраивает комбинирование уже существующих виджетов? К примеру QSpinBox + QToolButton + таблица popup.

Или тут желание возиться(разбираться) в стилях?

изначально так и было, но выглядит это убого, хотелось бы все кнопки вбить в фрейм поля ввода. со стилями почти все ясно, осталось разобраться в том, как отображает себя самый примитивный QLineEdit.

Ну и в чем убогость? Это сделано чисто в дизайнере.
Если сделать свой Layout, все это правильно связать, то и не надо замарачиваться


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 10, 2009, 21:40
Ну и в чем убогость? Это сделано чисто в дизайнере.
Если сделать свой Layout, все это правильно связать, то и не надо замарачиваться

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


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: spectre71 от Июнь 12, 2009, 08:36
Смотри вложение.
Но учти, что:
 1) нормально работает только под Windows и WindowsXP стилями под другими троли перемудрили не убирают Frame у QComboBox (может есть способ это исправить).
 2) В примере все вбито жестко (например, "QFrame { background: white }"  и некоторые размеры).
     А Надо делать динамически на соответствующие события (смена стиля, палитры, ...)
 3) Возможно будет необходимость сделать свой Layout, и отрисовку рамки "Frame" под некоторыми стилями (скругление углов, фокус,...)

Но функциональность QComboBox и QLineEdit переделывать нет необходимости


Название: Re: QComboBox + QSpinBox = новый компонент
Отправлено: ilyagoo от Июнь 14, 2009, 16:50
спасибо :)