Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: juvf от Июль 05, 2010, 20:43



Название: Как показать текст на ComboBox?
Отправлено: juvf от Июль 05, 2010, 20:43
Есть ComboBox с некоторыми строками, например "Пушкин", "Есенин". Пока не выбрали ни нужно ни каких поэтов показывать, а нужно показать <Выберите поэта>, бледным цветом шрифта. Как это сделать?

Можно сделать ComboBox с одной строкой "<Выберете поэта>" и показать её бледным шрифтом. А на клик прикрутить слот который удалит строку "<Выберете поэта>" и добавит строки "Пушкин" и "Есенин". Но как то это коряво.

Если не показывать ни одной строки из списка айтемов комбобокса (setCurrentIndex(-1)), то отображается пустая строка. Как в эту пустую строку текст поместить?


Название: Re: Как показать текст на ComboBox?
Отправлено: Marat(Qt) от Июль 05, 2010, 21:41
В paintEvent по условию if(currentIndex()==-1) рисуй поверх виджета, собственно сам виджет рисуй с помощью стиля - сложно, но вроде можно


Название: Re: Как показать текст на ComboBox?
Отправлено: SABROG от Июль 06, 2010, 00:35
Могу предложить следующий вариант, не идеальный, но рабочий.

(http://img811.imageshack.us/img811/9531/comboboxselect.gif)

Код
C++ (Qt)
class ComboBoxProxyStyle : public QProxyStyle
{
   Q_OBJECT
   Q_PROPERTY(QString placeHolder READ placeHolder WRITE setPlaceHolder)
public:
   ComboBoxProxyStyle(const QString& placeHolder)
   {
       setPlaceHolder(placeHolder);
   }
 
   virtual void drawControl(ControlElement element,
                            const QStyleOption* option,
                            QPainter* painter, const QWidget* widget) const
   {
       QStyleOption* opt = const_cast<QStyleOption*>(option);
 
       if (element == QStyle::CE_ComboBoxLabel) {
           QWidget* w = const_cast<QWidget*>(widget);
           QComboBox* cbx = qobject_cast<QComboBox*>(w);
           QStyleOptionComboBox* cb =
                           qstyleoption_cast<QStyleOptionComboBox*>(opt);
           if (cb && cbx) {
 
               if (-1 == cbx->currentIndex()) {
                   QPalette pal = cb->palette;
                   pal.setBrush(QPalette::Text, pal.mid());
                   cb->currentText = placeHolder();
                   cb->palette = pal;
               }
           }
       }
 
       QProxyStyle::drawControl(element, opt, painter, widget);
   }
 
   virtual void drawItemText(QPainter *painter,
                             const QRect &rect,
                             int flags,
                             const QPalette &pal,
                             bool enabled,
                             const QString &text,
                             QPalette::ColorRole textRole) const
   {
       if (placeHolder() == text) {
           textRole = QPalette::Text;
       }
       QProxyStyle::drawItemText(painter, rect, flags, pal, enabled, text, textRole);
   }
   QString placeHolder() const {return m_placeHolder;}
   void setPlaceHolder(const QString& text) {m_placeHolder = text;}
 
private:
   QString m_placeHolder;
};
 

Код
C++ (Qt)
ui->comboBox->setStyle(new ComboBoxProxyStyle("Select something..."));
 


Название: Re: Как показать текст на ComboBox?
Отправлено: juvf от Июль 06, 2010, 04:55
Могу предложить следующий вариант, не идеальный, но рабочий.


Ну, тоже коряво как-то, но работает. Спасибо. Только вот текст "Select something..." серенький только когда фокус на ComboBox-e. Ну могу понять почему. Как его заставить серым писать при любом фокусе?


ps Странно что такой функции нет в qt. Приходится извращаться. А подобное поведении интерфейса встречается часто. Ну текст-то писать, хотя бы простым шрифтом, при currentItem == -1 ,,,,,, это-то уж были обязаны были сделать еще тролли.


Название: Re: Как показать текст на ComboBox?
Отправлено: SABROG от Июль 06, 2010, 08:19
Как его заставить серым писать при любом фокусе?
Я код на форуме менял 3 раза, а так нужно прописать цвет для остальных ролей.

А подобное поведении интерфейса встречается часто.
Я видел такое только на веб-сайтах, в обычных программах пустой QComboBox сам по себе свидетельствует о том, что надо что-то выбрать.


Название: Re: Как показать текст на ComboBox?
Отправлено: GreatSnake от Июль 06, 2010, 10:07
Да, казалось бы, такой простой и иногда нужной фишки и нет.
Мне кажется можно сделать по-проще.
После создания и заполнения QComboBox-a делаем следующее:

Код
C++ (Qt)
cb->setEditable( true );
cb->lineEdit()->setText( "Select something..." );
cb->lineEdit()->setReadOnly( true );
cb->lineEdit()->setEnabled( false );

А в QComboBox::currentIndexChanged() слоте енаблим lineEdit().
Единственный минус - комбобох будет выглядеть как editable.


Название: Re: Как показать текст на ComboBox?
Отправлено: SABROG от Июль 06, 2010, 12:06
(http://img195.imageshack.us/img195/9830/combobox.png)

Может пригодится. Делаем элемент списка не выбираемым и не активным.

Код
C++ (Qt)
   QStandardItemModel* model =
           static_cast<QStandardItemModel*>(ui->comboBox->model());
   QStandardItem* item = model->item(0, 0);
   Qt::ItemFlags flags = item->flags();
 
   flags &= ~Qt::ItemIsSelectable & ~Qt::ItemIsEnabled;
 
   item->setFlags(flags);
 

Скрываем элемент списка, при этом в QComboBox его можно выставить активным.

Код
C++ (Qt)
   QListView* listView = qobject_cast<QListView*>(ui->comboBox->view());
   Q_CHECK_PTR(listView);
   listView->setRowHidden(0, true);
 


Название: Re: Как показать текст на ComboBox?
Отправлено: juvf от Июль 06, 2010, 18:52
Все варианты попробовал. Больше всех подошел с ComboBoxProxyStyle.
Всем спасибо. Проблема решена.