Russian Qt Forum
Сентябрь 22, 2024, 02:11 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Настройка QListWidget под легенду для графика  (Прочитано 12527 раз)
daimon
Гость
« Ответ #15 : Май 16, 2011, 16:21 »

есть виджет, который рисует график

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

отличия только, когда меняется размер виджета, тогда я перерисовую пиксмеп (renderPixmap(...) с новыми парметрами - размер пиксмепа

Код
C++ (Qt)
void CPlotter2d::paintEvent(QPaintEvent * /* event */)
{
   QStylePainter painter(this);
 
painter.drawPixmap(0, 0,pixmap);// mg);*/
//refreshPixmap(opt_graph);
 
}
 
void CPlotter2d::resizeEvent(QResizeEvent * /* event */)
{
 
opt_graph.width_widget = this->size().width();
opt_graph.height_widget = this->size().height();
 
pixmap= refreshPixmap(opt_graph);
 
//   refreshPixmap(opt_graph);
}

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

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


Цитировать
Или грабить виджет списка как пиксмеп и рисовать на пиксмепе - тогда получится, что сам виджет будет висеть на своём графическом виде (картинке) - как-то тупо получается.
Ничего не понял.

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

я вижу решение одно - рисовать на пиксмепе граб из виджета списка легенды, но тут как-то тупо получится мол виджет лежит сверху на нарисованной с помощью пеинтера картинки списка
как-то можна проще сделать?
« Последнее редактирование: Май 16, 2011, 16:26 от daimon » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #16 : Май 16, 2011, 16:29 »

Цитировать
всё этот делал, чтобы уменьшить нагрузку на процессор - пиксмеп меняется только при ресайзе виджета
Да уж "соптимиздил" Улыбающийся
А если юзер захочет подогнать размер окна, то просядем? В Qt уже встроен double-buffering, так ты ещё и свой забацал?
А чем не устроил  QGraphicsView? Твой CListLegend в него встроился бы легко.
Записан

Qt 5.11/4.8.7 (X11/Win)
daimon
Гость
« Ответ #17 : Май 16, 2011, 16:35 »

Цитировать
всё этот делал, чтобы уменьшить нагрузку на процессор - пиксмеп меняется только при ресайзе виджета
Да уж "соптимиздил" Улыбающийся
А если юзер захочет подогнать размер окна, то просядем? В Qt уже встроен double-buffering, так ты ещё и свой забацал?
А чем не устроил  QGraphicsView? Твой CListLegend в него встроился бы легко.
ну а так бы каждый раз пеинт эвентом рисовался бы график - весь рендер каждый раз или я не прав?
мда тут бы ещё как-то бы проверить, чтобы второй раз не перерисовывать тоже самое - хитрую проверку бы сделать
QGraphicsView пока не юзал - не знаю, пояни на простом примере

Основа проста - действующий виджет и при этом в итоге граб на картинке (при ресайзе график меняется - оси растягиваются и график тоже без помощи скейла - всё перерисовывается с учётом размера виджета, получается и виджет списка тоже надо двигать)
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #18 : Май 16, 2011, 16:39 »

Мде, в общем изобрёл очередной велосипед.
Почитай книжки насчёт QGraphicsView/QGraphicsScene.
Всё уже давно сделано.
Записан

Qt 5.11/4.8.7 (X11/Win)
daimon
Гость
« Ответ #19 : Май 16, 2011, 16:41 »

Код
C++ (Qt)
void CPlotter2d::resizeEvent(QResizeEvent * /* event */)
{
if(opt_graph.width_widget !=  this->size().width() || opt_graph.height_widget != this->size().height() )
{
opt_graph.width_widget = this->size().width();
opt_graph.height_widget = this->size().height();
 
pixmap= refreshPixmap(opt_graph);
}
 
//   refreshPixmap(opt_graph);
}

в общем лишний раз рисовать вроде не должно - только, когда размер меняется
Записан
daimon
Гость
« Ответ #20 : Май 16, 2011, 16:48 »

походу нужно типа создать сцену на неё повесить итемом график и легенду и потом уже там колдовать
ну а график всё равно нужно перерисовывать при ресайзе - скейлить не катит - надписи просто тогда будуть растягиваться или сжиматься
« Последнее редактирование: Май 16, 2011, 16:50 от daimon » Записан
daimon
Гость
« Ответ #21 : Май 16, 2011, 17:41 »

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

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



« Последнее редактирование: Май 16, 2011, 17:49 от daimon » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #22 : Май 16, 2011, 18:12 »

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

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

В LightPlot2D, например, легенда  - это отдельный виджет (не QListWidget) и связывается она непосредственно с самим Plotter'ом так: Plotter имеет указатель на легенду и в курсе что и когда с ней делать.

   
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
daimon
Гость
« Ответ #23 : Май 16, 2011, 18:35 »

можете кинуть ссылку на проект QLightPlot2D
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #24 : Май 16, 2011, 18:48 »

Цитировать
можете кинуть ссылку на проект QLightPlot2D
А Вы не в курсе?

Сама либа здесь: http://code.google.com/p/lightplot2d/downloads/list
Полный виджет со всеми диалогами и настройками здесь: http://www.prog.org.ru/topic_10208_90.html

Вначале нужно собрать библиотеку, потом собрать сам виджет Plotter
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
daimon
Гость
« Ответ #25 : Май 16, 2011, 18:58 »

Цитировать
можете кинуть ссылку на проект QLightPlot2D
А Вы не в курсе?

Сама либа здесь: http://code.google.com/p/lightplot2d/downloads/list
Полный виджет со всеми диалогами и настройками здесь: http://www.prog.org.ru/topic_10208_90.html

Вначале нужно собрать библиотеку, потом собрать сам виджет Plotter
я летом смотрел было норм
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #26 : Май 16, 2011, 19:09 »

На мой взгляд, если и писать подобные вещи, то лучше сразу использовать QGraphycsScene/View
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
daimon
Гость
« Ответ #27 : Май 16, 2011, 19:12 »

На мой взгляд, если и писать подобные вещи, то лучше сразу использовать QGraphycsScene/View

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

и почему-то картинка не сохраняется

Код
C++ (Qt)
#include "clistwidgetlegendgraph2d.h"
#include <QtGui/QApplication>
 
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene(QRect(0,0,640,480));
 
CListLegend list(0);
list.addItems(QStringList()<<"sfdsdfshhhhhhhhhhhhhhhhdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf"<<"sfdsdfsdf"<<"sdf");
 
scene.addWidget(&list);
scene.addWidget(new QPushButton("button",0));
 
 
QPixmap pixmap;
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
 
pixmap.save("scene.png");
 
QGraphicsView view(&scene);
view.show();
return a.exec();
}
 
Записан
daimon
Гость
« Ответ #28 : Май 16, 2011, 22:52 »

Код
C
#include <QtGui>
 
class CListLegend: public QListWidget
{
Q_OBJECT
public:
CListLegend(QWidget *parent):QListWidget(parent)
{
 
setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
setSelectionRectVisible(false);
 
setFocusPolicy( Qt::NoFocus );
setFrameShape(QFrame::Box);
 
QPixmap image(10,10);
resize(100,80);
image.fill(2);
 
addItem(image,"fffjjjjjjjjjjjjddddddddjjjjjjjjjjjjjjjj",Qt::CheckState::Unchecked);
addItem(image,"fffjjjjjjjjjjjjjjjjjjjjjjjjjjjj",Qt::CheckState::Unchecked);
addItem(image,"fffjjjjjjjjjjjjjjjjjjjjjjjjjjjj",Qt::CheckState::Unchecked);
addItem(image,"fffjjjjjjjjjjjjj",Qt::CheckState::Unchecked);
addItem(image,"fffjjjjjjjjjjjjjjj",Qt::CheckState::Unchecked);
addItem(image,"fffjjjjjjjjjjjjjjjj",Qt::CheckState::Unchecked);
addItem(image,"fffjjjjjjjjjjjjjjjjjjjjjjjjjjjj",Qt::CheckState::Unchecked);
 
}
void addItem(const QIcon& icon,  const QString& str, Qt::CheckState state = Qt::CheckState::Unchecked)
{
QListWidget::addItem(new QListWidgetItem(str));
// item(count()-1)->setCheckState(state);
}
bool event(QEvent * ev)
{
 
switch( ev->type() )
{
case QEvent::Enter:
setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded);
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
QListWidget::update();
break;
case QEvent::Leave:
 
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
QListWidget::update();
 
 
break;
default:
break;
}
return QListWidget::event( ev );
}
QPixmap image()
{
return QPixmap().grabWidget(this);
}
 
 
};
при таком варианте почему-то бок при появлении горизонального скрола - не соответствует максимальному итему
пробовал и апдейты подаблять - не помагает.
Что не так делаю?
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.161 секунд. Запросов: 23.