Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QComboBox, Как задать размер выпадающего списка
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt GUI
Страницы: 1, 2
trdm
Задать размер выпадающего списка у QComboBox.
Туплю слегонца.....
Проблема на скрине:
panter_dsd
QAbstractItemView * QComboBox::view () const ?
Litkevich Yuriy
trdm, а как он у тебя вообще такой получился, может ты с виджетом, вложеным, что-то не так сделал (sizeHint, например)?
trdm
Цитата(panter_dsd @ 3.1.2009, 19:56) *
QAbstractItemView * QComboBox::view () const ?

На сколько помню const в этом случае типа сторож, что-бы функция view не меняла внутренностей QComboBox.
Или я не понял намека?


+
там же на скрине все операции с комбобоксом.
ПС. Говорю же туплю :)
panter_dsd
const означает, что ссылка константная, но сам объект можно изменять. Делаешь:
QAbstractItemView * view=comboBox->view () и работаешь уже с самим объектом.
ПыСы: проверить не могу и не работал с этим, но по идее должно.

А вообще, закинь немного кода по созданию и заполнению QComboBox.
SABROG
Цитата(panter_dsd @ 3.1.2009, 20:26) *
const означает, что ссылка константная, но сам объект можно изменять. Делаешь:
QAbstractItemView * view=comboBox->view () и работаешь уже с самим объектом.
ПыСы: проверить не могу и не работал с этим, но по идее должно.

А вообще, закинь немного кода по созданию и заполнению QComboBox.


Нет, const в данном случае означает всего-лишь то, что метод не меняет внутреннего состояния класса (грубо говоря не меняет данные-члены класса, read-only)

И я думаю, что надо использовать setView, а то перетягивание каната получается. Комбик ресайзит как ему надо, ты ресайзиш как тебе надо.
trdm
Цитата(SABROG @ 3.1.2009, 20:53) *
И я думаю, что надо использовать setView, а то перетягивание каната получается. Комбик ресайзит как ему надо, ты ресайзиш как тебе надо.

Я уже думал над этим. Изучаю по void QComboBox::showPopup()
setView не попрет :(
Придется идти другим путем...

Мне не очень понравилось юзабелити колор-комбобокса. Так что прийдется как-то извратиться...
SABROG
Если особо напрягаться не хочется, то можно идти путем "Color Editor Factory Example"
trdm
Цитата(SABROG @ 3.1.2009, 21:39) *
Если особо напрягаться не хочется, то можно идти путем "Color Editor Factory Example"

не. смысл поделия в том что-бы экономить время девелопера помаксимому.
В "Color Editor Factory Example" выпадающий список, а у меня палитра из специально подобранных цветов.
Пользователь видит сразу варианты и может прикинуть что да как как будет выглядеть.
Если не устроит, уж тогда велком ту системе колор пикер...
Вот хороший вариант:
SABROG
А чем он радикально отличается от QColorDialog'a ?
trdm
Цитата(SABROG @ 3.1.2009, 21:59) *
А чем он радикально отличается от QColorDialog'a ?

Радикально: предзаданныйми цветовыми схемами.
Очень время экономит.
SABROG
Цитата(trdm @ 3.1.2009, 22:01) *
Цитата(SABROG @ 3.1.2009, 21:59) *
А чем он радикально отличается от QColorDialog'a ?

Радикально: предзаданныйми цветовыми схемами.
Очень время экономит.


Ну так и предзадай

Цитата
void QColorDialog::setCustomColor ( int number, QRgb color ) [static]
trdm
не кошерно. :)
плюс ко всему еще пара задач намечается со сходной реализацией, но разными данными.
надо схему отработать.
SABROG
Цитата(trdm @ 3.1.2009, 22:08) *
не кошерно. :)
плюс ко всему еще пара задач намечается со сходной реализацией, но разными данными.
надо схему отработать.

Ну исходников заполнения combobox мы до сих пор не увидели, т.ч. врятли так удастся чем-то помочь. Нужен компилируемый материал.
trdm
Цитата(SABROG @ 4.1.2009, 12:17) *
Ну исходников заполнения combobox мы до сих пор не увидели, т.ч. врятли так удастся чем-то помочь. Нужен компилируемый материал.

Там смотреть не на что.
Комбобоску просто устанавливается модель
tabFont->m_cBoxColor->setModel(m_colorModel);
Модель заполняется цветами:
Раскрывающийся текст

void uoReportPropEditor::addColor(int& row, QColor col, bool def)
{
    m_colorModel->insertRows(row, 1, QModelIndex());
    m_colorModel->setData(m_colorModel->index(row, 0, QModelIndex()),col);
    m_colorModel->setData(m_colorModel->index(row, 0, QModelIndex()),col, Qt::DecorationRole);
}

void uoReportPropEditor::fillColorModel()
{
    m_colorModel->removeRows(0, m_colorModel->rowCount(QModelIndex()), QModelIndex());
    int row = -1;
    addColor(++row, QColor("#000000"), true);
    addColor(++row, QColor("#ffffff"), true);
    addColor(++row, QColor("#ff0000"), true);
    addColor(++row, QColor("#00ff00"), true);
    addColor(++row, QColor("#0000ff"), true);//blue
    addColor(++row, QColor("#ffff00"), true);// желтый
    addColor(++row, QColor("#ff00ff"), true);    //
    addColor(++row, QColor("#00ffff"), true);    //

    addColor(++row, QColor("#800000"), true);    //
    addColor(++row, QColor("#008000"), true);    //
    addColor(++row, QColor("#808000"), true);    //
    addColor(++row, QColor("#000080"), true);    //
    addColor(++row, QColor("#800080"), true);    //
    addColor(++row, QColor("#008080"), true);    //
    addColor(++row, QColor("#808080"), true);    //
    addColor(++row, QColor("#c0c0c0"), true);    //

    //3
    addColor(++row, QColor("#8080ff"), true);    //
    addColor(++row, QColor("#802060"), true);    //
    addColor(++row, QColor("#ffffc0"), true);    //
    addColor(++row, QColor("#a0e0e0"), true);    //
    addColor(++row, QColor("#600080"), true);    //
    addColor(++row, QColor("#ff8080"), true);    //
    addColor(++row, QColor("#0080c0"), true);    //
    addColor(++row, QColor("#c0c0ff"), true);    //

    //4
    addColor(++row, QColor("#00cfff"), true);    //
    addColor(++row, QColor("#69ffff"), true);    //
    addColor(++row, QColor("#e0ffe0"), true);    //
    addColor(++row, QColor("#dd9cb3"), true);    //
    addColor(++row, QColor("#b38fee"), true);    //
    addColor(++row, QColor("#2a6ff9"), true);    //
    addColor(++row, QColor("#3fb8cd"), true);    //
    addColor(++row, QColor("#488436"), true);    //

    // 5
    addColor(++row, QColor("#958c41"), true);    //
    addColor(++row, QColor("#905e42"), true);    //
    addColor(++row, QColor("#a0627a"), true);    //
    addColor(++row, QColor("#624fac"), true);    //
    addColor(++row, QColor("#1d2fbe"), true);    //
    addColor(++row, QColor("#286676"), true);    //
    addColor(++row, QColor("#004500"), true);    //
    addColor(++row, QColor("#453e01"), true);    //

    // 6
    addColor(++row, QColor("#6a2813"), true);    //
    addColor(++row, QColor("#85396a"), true);    //
    addColor(++row, QColor("#4a3285"), true);    //
    addColor(++row, QColor("#c0dcc0"), true);    //
    addColor(++row, QColor("#a6caf0"), true);    //
    addColor(++row, QColor("#7fffd4"), true);    //
    addColor(++row, QColor("#f0ffff"), true);    //
    addColor(++row, QColor("#f5f5dc"), true);    ///// Повтор?!
    // Повторы?!
    // 7
    addColor(++row, QColor("#808000"), true);    //
    addColor(++row, QColor("#800080"), true);    //
    addColor(++row, QColor("#008080"), true);    //
    addColor(++row, QColor("#808080"), true);    //
    addColor(++row, QColor("#fffbf0"), true);    //
    addColor(++row, QColor("#a0a0a4"), true);    //
    addColor(++row, QColor("#313900"), true);    //
    addColor(++row, QColor("#d9853e"), true);    //

}

SABROG
Жесть какая. Может цикл сделать и массив цветов ?
trdm
Цитата(SABROG @ 5.1.2009, 1:22) *
Жесть какая. Может цикл сделать и массив цветов ?

Сделаю.
SABROG
view->updateGeometry();


Вызывал ?
trdm
Цитата(SABROG @ 5.1.2009, 14:31) *
view->updateGeometry();


Вызывал ?

нет, я пошел другим путем.
trdm
Вот таким путем пошел:
Как думаете, нормально?
Litkevich Yuriy
Цитата(trdm @ 6.1.2009, 6:27) *
Как думаете, нормально?
неа, декорацию окна убери
molchanoviv
А по моему вполне себе ничего
SABROG
Titlebar с фреймом имхо не нужны, а так вполне.
trdm
Цитата(Litkevich Yuriy @ 6.1.2009, 6:11) *
Цитата(trdm @ 6.1.2009, 6:27) *
Как думаете, нормально?
неа, декорацию окна убери

Какую декорацию?
molchanoviv
В окне выбора цвета убери шапку. Хотя по мне в ООо сделано с шапкой и ничего.
trdm
Цитата(molchanoviv @ 6.1.2009, 12:35) *
В окне выбора цвета убери шапку. Хотя по мне в ООо сделано с шапкой и ничего.

убрал. чуток доточить надо, а так в принцыпе готово..
Litkevich Yuriy
Цитата(trdm @ 6.1.2009, 15:32) *
Какую декорацию?
так называют рамку и, возможно, заголовок, которые рисует менеджер окон, чтобы пользователь мог управлять размером и положением окна. По буржуйски (frame & title = decoration)

Цитата(trdm @ 6.1.2009, 17:33) *
чуток доточить надо
ага, положи свой виджет на QFrame и поэксперементируй со стилем его границ.
trdm
Что-то никак не соображу по какой методе комбобокс прячет свой попуп,
если пользователь щелкает вне виджета, который отрабатывает это событие.
SABROG
Вообще за сокрытие попапов отвечает сам класс QWidget.

void QWidget::mousePressEvent(QMouseEvent *event)
{
    event->ignore();
    if ((windowType() == Qt::Popup)) {
        event->accept();
        QWidget* w;
        while ((w = qApp->activePopupWidget()) && w != this){
            w->close();
            if (qApp->activePopupWidget() == w) // widget does not want to dissappear
                w->hide(); // hide at least
        }
        if (!rect().contains(event->pos())){
            close();
        }
    }
}


Помимо кликов он отслеживает фокус всплывающих окон. Если фокус пропадает, то и окно закрывается (см. QWidgetPrivate::show_helper()).

void QComboBoxPrivateContainer::mousePressEvent(QMouseEvent *e)
{

    QStyleOptionComboBox opt = comboStyleOption();
    opt.subControls = QStyle::SC_All;
    opt.activeSubControls = QStyle::SC_ComboBoxArrow;
    QStyle::SubControl sc = combo->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt,
                                                           combo->mapFromGlobal(e->globalPos()),
                                                           combo);
    if ((combo->isEditable() && sc == QStyle::SC_ComboBoxArrow)
        || (!combo->isEditable() && sc != QStyle::SC_None))
        setAttribute(Qt::WA_NoMouseReplay);
    combo->hidePopup();
}


А ComboBox'у похоже все-равно когда закрываться куда ни кликни. По координатам мышки он определяет на какой элемент контрола (стрелка или еще что) был сделан клик и в зависимости от этого выставляет аттрибут Qt::WA_NoMouseReplay. В описании говорится:

Цитата
Используется для всплывающих виджетов. Указывает, что самое последнее событие нажатия кнопки мыши не должно быть воспроизведено, когда всплывающий виджет закрывается. Флаг устанавливается автором виджета и сбрасывается ядром Qt каждый раз когда виджет принимает новое событие мыши.

Но вот что означает это "воспроизведено" (reply) не ясно.
trdm
Вот проектик:
Через попуп у меня не получился виджет, чего-то я не догоняю в этом деле.
Если выпадающему виджету установить Qt::Popup, то вопервых получается какое-то прозрачное оконце, которое не ловит paintEvent() и соответственно нефига не рисует.
Если брать текущую реализацию, то есть 2 момента.
Если виджет-родитель при открытом попупе перетащить или поместить вниз зет-ордера то окно попупа останется на экране.
Как правильно отработать момент не въеду пока.
Может кто чего сообразит?
Litkevich Yuriy
Цитата(SABROG @ 10.1.2009, 2:03) *
"воспроизведено" (reply) не ясно
ну типа повторение
SABROG
Цитата(Litkevich Yuriy @ 10.1.2009, 0:26) *
ну типа повторение


А в каком контексте ? Что повторяется и зачем :) ?
---
А кажись понял

Цитата
When the application opens a popup widget, all events are sent to the popup.


Т.е. если кликнуть где-нить при активном попапе, то эвент пойдет дальше по всем виджетам, а аттрибут это блокирует.
SABROG
Проверил рисование на popup'e, все отлично

В подтверждение тому демка (7Mb)
Litkevich Yuriy
SABROG, а чето за метёлка? Она к теме какое отношение имеет?
SABROG
Это скрин из демки, там 24 телки рандомно выводятся в виде popup окна. Это я так проверял работу paintEvent'a попап окна. А телок выбрал, чтобы глаз радовали. Могу мужиков поставить. Предупредите заранее, когда в след. раз что-нибудь ваять надумаю. ;)

Надо будет на досуге с .mng пошаманить. Что-нить типа десктопного анимированного питомца или виртуалгёрл замутить.
trdm
Какой парент у попупа? QDialog? А у меня унаследованный от QFrame виджет.
Попробуй в конструкторе проекта, который я подцепил выше установить у uoColorCContainer флаг Qt::Popup и увидишь о чем я говорил.
SABROG
Цитата(trdm @ 10.1.2009, 19:58) *
Какой парент у попупа? QDialog? А у меня унаследованный от QFrame виджет.
Попробуй в конструкторе проекта, который я подцепил выше установить у uoColorCContainer флаг Qt::Popup и увидишь о чем я говорил.

У меня от чистого QWidget'a. Изменил на QFrame, ничего не изменилось.

Я тебя не правильно понял. Прозрачного окошка нет, оно просто не перерисовывается и не хайдится. Но все-таки эвенты работают, т.к. в комбике цвет меняется. Что-то ты замудрил хитрое с эвентами, там черт ногу сломит.
trdm
да уж... наверное замутил....
я еще и не такое замутить способен :)
фиг кто разберется....
SABROG
Попробуй пропиши вот это в main.cpp

QObject::connect(btnOK, SIGNAL(clicked()),colCh, SLOT(popupShow()));


И раскомментируй Qt::Popup. Затем сравни результаты, выбери из комбобокса попап, а потом с помощью кнопки OK. В первом случае зависнет, во второй отработает на все 100.

---
Пардон забыл еще кое-что.
Надо закомментировать это:

setWindowFlags(Qt::ToolTip);


Иначе popup окно не будет попапом и следовательно закрываться при потере фокуса.

Если в uoColorCContainer::mousePressEvent закомментировать все и оставить только это:

QWidget::mousePressEvent(event);


То окно будет закрываться при потере фокуса, но не будет выбираться элемент, а если раскомментировать, то цвета будут выбираться, но попап не будет закрываться при потере фокуса.

Зато если совместить вот так:

void uoColorCContainer::mousePressEvent(QMouseEvent *event)
{

    QPoint pt = event->pos();
    QList<uoColRect>::const_iterator  cIt = m_colRects.begin();
    uoColRect colrRct;
    int cur = 0;

    while(cIt != m_colRects.end()){
        colrRct = *cIt;
        if (colrRct.m_rect.contains(pt))
        {
            m_curentItem = cur;
            cur = -1;
            break;
        }
        cIt++;
        ++cur;
    }
    if (cur == -1){
        setCurentItem(m_curentItem);
        hide();
    }
    QWidget::mousePressEvent(event);
}


То окно и закрывается и элемент выбирается.
---
Похоже я опять что-то забыл...
Блин, если сначала нажать на кнопку, а потом использовать комбо, то все нормально. А если просто на кнопку комбика жать, то отрисовка не идет.
---
Мистика какая-то. Если сначала нажать на комбик, потом выбрать предполагаемый цвет, то этот так и не отрисовавшийся попап пропадает. Затем если снова нажимать на комбик то все работает. В общем эвенты - зло.
trdm
Стало быть проблема в МЕСТЕ вызова метода popupShow().
Я это замечал когда пытался проанализировать Qt-шный пример windowsFlag.
вот правленный проект. я тут кое-что подкрутил. Вобщем меня вроде как устраивает, но если есть шанс сделать нормально, то лучше сделать нормально...
SABROG
Добавил setFocus стало все отрисовываться

void uoColorChooser::popupShow()
{
    if (m_colorList.isEmpty())
        return;
    getContainer();
    QSize sz = m_Container->recalcSize();
    m_Container->doChangeCurColor(m_colorCurPos);

    QPoint below = mapToGlobal(frameRect().bottomLeft());
    QRect contRect = QRect(below, QPoint(below.x()+sz.width(), below.y()+sz.height()));
    m_Container->setGeometry(contRect);
    m_Container->move(below);
    m_Container->raise();
    m_Container->show();
    m_Container->update();
    m_Container->setFocus();
}


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

В общем пока все свелось к следующим изменениям:

- раскомментировать Qt::Popup
- закомментировать Qt::Tooltio
- добавить в конец метода uoColorCContainer::mousePressEvent - QWidget::mousePressEvent(event);
- в методе uoColorChooser::mousePressEvent заменить popupHide() на popupShow()
- добавить setFocus
trdm
Цитата(SABROG @ 10.1.2009, 23:32) *
Добавил setFocus стало все отрисовываться

фокус на сонтайнере как бы и не нужен в принципе по задумке.
SABROG
Цитата(trdm @ 11.1.2009, 0:19) *
Цитата(SABROG @ 10.1.2009, 23:32) *
Добавил setFocus стало все отрисовываться

фокус на сонтайнере как бы и не нужен в принципе по задумке.


Ну QComboBox фокус же на вьюху ставит. Правда до сих пор не могу понять как этот фокус влияет на отрисовку попапа. Или почему фокус сам не переходит на открытое окно. В общем проблема скрылась где-то в зарослях логики работы Qt с виджетами и эвентами.
trdm
Цитата(SABROG @ 10.1.2009, 23:32) *
Добавил setFocus стало все отрисовываться....

Вобщем сделал как ты написал и добавил от себя.
После установки фокуса все стало перерисовываться.
ПС. Вобщем дорожка проторена, можно идти :)
Сенк!
SABROG
Цитата(trdm @ 11.1.2009, 21:27) *
Цитата(SABROG @ 10.1.2009, 23:32) *
Добавил setFocus стало все отрисовываться....

Вобщем сделал как ты написал и добавил от себя.
После установки фокуса все стало перерисовываться.
ПС. Вобщем дорожка проторена, можно идти :)
Сенк!


Имхо там заросли те еще :) Хотелось бы докапаться до сути, почему:
  1. фокус не переходит на окно, если окно показывается в эвенте (если по сигнату то все ок)
  2. окно не отрисовывается без фокуса


И понять каждую строчку кода, чтобы можно было написать какой-нибудь гайд по созданию своих виджетов. Я думаю там еще будут проблемы с keyPressEvent'ом. А так код сейчас выглядит так как будто его выдрали частями из исходников QComboBox :)
trdm
Цитата(SABROG @ 11.1.2009, 21:40) *
Я думаю там еще будут проблемы с keyPressEvent'ом.

это я доточил.
Цитата(SABROG @ 11.1.2009, 21:40) *
А так код сейчас выглядит так как будто его выдрали частями из исходников QComboBox :)

не, сам писал. подглядывал конечно...
у комбобокса там прокладка для возможности установки вьювов, а у меня без...
SABROG
А ты победил залипание кнопок при первом клике ? Т.е. когда у QComboBox жмешь на стрелку, то она залипает до момента пока контейнер не скроется. А у меня получается что при первом вызове не залипает, а потом нормально.
trdm
Цитата(SABROG @ 11.1.2009, 23:04) *
А ты победил залипание кнопок при первом клике ? Т.е. когда у QComboBox жмешь на стрелку, то она залипает до момента пока контейнер не скроется. А у меня получается что при первом вызове не залипает, а потом нормально.

неа. Оставил пока для как несущественную фичу. Думю доточить несложно. Сейчас другие приоритеты.
Собственно я просто хотел "познакомиться" с имплементациями такого рода: выпадающий список и свои кнопки "на контроле".
SABROG
Создал тестовое приложение и в mousePressEvent динамически создаю QWidget и там же его отображаю. Проблем с отрисовкой вроде нет никаких, даже оригинальный обработчик вызывать не приходится. Где же косяк зарылся ?

Кстати забавно. Если на форме находится кнопка и на нее нажимаешь, то эвент не вызывается, а если на неё нажать правой кнопкой мышки, то вызывается :)

Кстати выбор клавиатурой при закрытом контейнере работает криво. Если зажать клавишу вверх/вниз, то через некоторое время цвет зацикливается.
trdm
Цитата(SABROG @ 12.1.2009, 15:22) *
Кстати выбор клавиатурой при закрытом контейнере работает криво. Если зажать клавишу вверх/вниз, то через некоторое время цвет зацикливается.

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