crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QPainter для самопального виджета
anater
  опции профиля:
сообщение 11.10.2010, 20:11
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.12.2009
Пользователь №: 1335

Спасибо сказали: 0 раз(а)




Репутация:   0  


Итак доброшо времени суток.

Имею самопальный виджет унаследованный от QWidget.

В нем есть всякие поля тестовые кнопочки и прочая мишура.

И есть виджет в котором должна рисоваться картинка... Вопроса собственно два.
Как прикрутить QPainter конкретно к данному встроеному виджету?

QPainter painter (this)ж в paintEvent не особенно хорошо работает ибо рисуемые элементы запросо налезают на соседей.

Как конкретно рисоваться во встроеном виджете?

Спасибо за вменяемые ответы :)

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 11.10.2010, 21:13
Сообщение #2


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(anater @ 11.10.2010, 21:11) *
Как прикрутить QPainter конкретно к данному встроеному виджету?
Отнаследоваться от этого (встроенного :)) виджета, переопределить в нем paintEvent и отрисовать то что тебе нужно через QPainter. Либо же, второй вариант, установить фильтр событий в главном виджете (это в котором мишура всякая), ловить событие отрисовки для встроенного и отрисовать то что тебе нужно через QPainter. Третьего не дано.
Цитата(anater @ 11.10.2010, 21:11) *
QPainter painter (this)ж в paintEvent не особенно хорошо работает ибо рисуемые элементы запросо налезают на соседей.
Это откуда такие глупости
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
anater
  опции профиля:
сообщение 11.10.2010, 21:22
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.12.2009
Пользователь №: 1335

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(igor_bogomolov @ 11.10.2010, 22:13) *
Цитата(anater @ 11.10.2010, 21:11) *
Как прикрутить QPainter конкретно к данному встроеному виджету?
Отнаследоваться от этого (встроенного :)) виджета, переопределить в нем paintEvent и отрисовать то что тебе нужно через QPainter. Либо же, второй вариант, установить фильтр событий в главном виджете (это в котором мишура всякая), ловить событие отрисовки для встроенного и отрисовать то что тебе нужно через QPainter. Третьего не дано.
Цитата(anater @ 11.10.2010, 21:11) *
QPainter painter (this)ж в paintEvent не особенно хорошо работает ибо рисуемые элементы запросо налезают на соседей.
Это откуда такие глупости

Глупости непосредственно с экрана. Например рисую линию на этом "встроеном" виджете, а она начинается не с угла самого виджета а с угла окна и вылезает из под остальных элементов. Т.е. отрисовывается где попало.

Да и как "отнаследоваться"? :) Хотелось бы сохранить "цельность" конструкции. Может можно переопределить paintEvent без такой хирургии? Если можно то выложи плиз кратенький примерчик.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 11.10.2010, 21:26
Сообщение #4


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(anater @ 11.10.2010, 22:22) *
Если можно то выложи плиз кратенький примерчик.
Не, наоборот. Опиши нормально задачу и прикладывай свой код. А мы подправим где надо.
Примеров в документации достаточно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
anater
  опции профиля:
сообщение 11.10.2010, 21:35
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.12.2009
Пользователь №: 1335

Спасибо сказали: 0 раз(а)




Репутация:   0  


Не относящееся к длу порезал.

Раскрывающийся текст
#ifndef PB_H
#define PB_H

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

class Pb:public QFrame
{
public:
    Pb(QFrame *parent=0);

    int get_size;
    int scene_w;
    int scene_h;
    int dev_pb;
    int chan_pb;

    lf* pbla;
    QGridLayout* pb_l;
    QFrame* pb_name;
    QHBoxLayout* pb_name_l;

    QFrame* pb_param;
    QVBoxLayout* pb_param_l;

    QFrame* pb_graf;
    QVBoxLayout* pb_graf_l;

    QLineEdit* pb_qle;

    QLCDNumber* pb_lcd;

    QFrame* pb_ed_iz;
    QLineEdit* pb_qle_ed_izm;
    QVBoxLayout* pb_qle_ed_izm_l;

    QWidget* qwpb; ////!!!!!!!! в нем то и надо рисовать картинку!!! Очень желательно не вынося куда подальше из этого класса!!!!

    void init(lf * lsa,int dev, int chan);
protected:
    void paintEvent(QPaintEvent * event);

};

#endif // PB_H
Раскрывающийся текст
#include <QtGui>

#include "pb.h"
#include"lf.h"

Pb::pb(QFrame *parent)
    :QFrame(parent)

{

    get_size=0;
    scene_w=0;
    scene_h=0;
    dev_pb=0;
    chan_pb=0;

    this->setFrameStyle(QFrame::WinPanel | QFrame::Plain);
    pb_l = new QGridLayout;

    this->setLayout(pb_l);
    pb_l->setMargin(0);
    pb_l->setSpacing(0);

    pb_name = new QFrame;
    pb_name->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
    pb_name_l = new QHBoxLayout;
    pb_name_l->setMargin(0);
    pb_name_l->setSpacing(0);
    pb_name->setLayout(pb_name_l);

    pb_param = new QFrame;
    pb_param->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    pb_param_l = new QVBoxLayout;
    pb_param_l->setMargin(0);
    pb_param_l->setSpacing(0);
    pb_param->setLayout(pb_param_l);

    pb_ed_iz = new QFrame;
    pb_qle_ed_izm = new QLineEdit;
    pb_ed_iz ->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    pb_qle_ed_izm_l = new QVBoxLayout;

    pb_qle_ed_izm_l->setMargin(0);
    pb_qle_ed_izm_l->setSpacing(0);
    pb_qle_ed_izm->setMaximumSize(100,20);

    pb_ed_iz->setLayout(pb_qle_ed_izm_l);

    pb_graf = new QFrame;
    pb_graf_l = new QVBoxLayout;
    qwpb = new QWidget(this);
    //qppb= new QPainter;

    //pb_gfraf_scene = new QGraphicsScene;
    //pb_gfraf_view = new QGraphicsView;
    //pb_gfraf_view->setScene(pb_gfraf_scene);
    //pb_gfraf_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //pb_gfraf_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    pb_graf->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
    pb_graf->setLayout(pb_graf_l);
    pb_graf_l->setMargin(0);
    pb_graf_l->setSpacing(0);
    pb_graf_l->addWidget(qwpb);
    //qppb= new QPainter(qwpb);

    pb_qle = new QLineEdit;
    pb_qle->setDisabled(true);
    pb_qle->setAlignment(Qt::AlignCenter);
  
    pb_qle->setText("5CV");
    pb_qle->setMaximumSize(100,20);

    pb_lcd = new QLCDNumber;
    pb_lcd->setSegmentStyle(QLCDNumber::Flat);
    pb_lcd->display(4.4);
    pb_name_l->addWidget(pb_qle);

    pb_param_l->addWidget(pb_lcd);

    pb_qle_ed_izm_l->addWidget(pb_qle_ed_izm);
    
    pb_l->addWidget(pb_name,1,1);

    pb_l->addWidget(pb_param,2,1,1,1);
    pb_l->addWidget(pb_ed_iz,3,1,1,1);

    pb_l->addWidget(pb_graf,4,1,10,1);

};



void Pb::paintEvent(QPaintEvent * event)
{
    std::cout<<"painter X  " << qwpb->geometry().x()<< std::endl;
    std::cout<<"painter Y " <<qwpb->geometry().y()<< std::endl;
    std::cout<<"layout X  " << pb_graf_l->geometry().x()<< std::endl;
    std::cout<<"layout X  " << pb_graf_l->geometry().y()<< std::endl;
    std::cout<<"qwpbw  " << pb_lcd->pos().x() << std::endl;
    std::cout<<"qwpbh  " << this->pb_lcd->pos().y() << std::endl;
};
Причина редактирования: пользуйся тэтом code
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 11.10.2010, 21:57
Сообщение #6


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Ну второй вариант примерно так выглядеть будет
В класс Pb добавь bool eventFilter(QObject *obj, QEvent *event)
protected: // paintEvent в данном классе переопределять не надо
     bool eventFilter(QObject *obj, QEvent *event);


В конструкторе того же класса
Pb::pb(QFrame *parent):QFrame(parent)
{
    qwpb->installEventFilter(this);


реализация фильтра событий
 bool Pb::eventFilter(QObject *obj, QEvent *event)
{
     if (event->type() == QEvent::Paint && obj == qwpb) {
         QPaintEvent *e = static_cast<QPaintEvent *>(event);
         QPainter painter(this);
         painter.drawImage(...);
                 ... // здесь в общем то что нужно рисуешь
         return true;
     } else {
         return QObject::eventFilter(obj, event);
     }
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
anater
  опции профиля:
сообщение 13.10.2010, 19:26
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.12.2009
Пользователь №: 1335

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(igor_bogomolov @ 11.10.2010, 22:57) *
Ну второй вариант примерно так выглядеть будет
...

Спасибо по этому варианту получилось весьма симпатично!
Причина редактирования: не цитируй целыми сообщениями, тем более такими большими
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
bayah
  опции профиля:
сообщение 19.5.2011, 6:34
Сообщение #8


Студент
*

Группа: Участник
Сообщений: 31
Регистрация: 23.11.2009
Пользователь №: 1249

Спасибо сказали: 0 раз(а)




Репутация:   0  


А у меня не получается сделать перехватывая события.
Ничего не рисуется на graphicsView виджете.
Что не так в этом коде, подскажите:

widget.h
Раскрывающийся текст
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtGui>

namespace Ui {
    class Widget;
}

class Widget : public QWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = 0);
    ~Widget();

protected:
    void changeEvent(QEvent *e);
    bool eventFilter(QObject *obj, QEvent *event);

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H



widget.cpp
Раскрывающийся текст
#include "widget.h"
#include "ui_widget.h"

#include <iostream>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->graphicsView->installEventFilter(this); //собственно на этом виджете, созданном в Дизайнере я и хочу рисовать
}

Widget::~Widget()
{
    delete ui;
}

void Widget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

    bool Widget::eventFilter(QObject *obj, QEvent *event)
    {
        if(event->type() == QEvent::Paint && obj == ui->graphicsView){
            QPaintEvent *e = static_cast<QPaintEvent *>(event);
            QPainter painter(qobject_cast<QWidget* >(obj));
            painter.drawLine(10, 10, 100, 100);

            return true;

        }else{
            return QObject::eventFilter(obj, event);
        }
    }



ну и тут просто обычный main.cpp:

Раскрывающийся текст
#include <QtGui/QApplication>
#include <QWidget>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}


Сообщение отредактировал bayah - 19.5.2011, 8:47
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 13:59