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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: grabWidget() для моего виджета  (Прочитано 6412 раз)
finka
Гость
« : Октябрь 24, 2007, 14:32 »

Есть класс Ellipse, наследуемый от QWidget, в его конструкторе я делаю прозрачным фон виджета:
Код:
	QPalette newPalette = palette();
newPalette.setBrush(QPalette::Window, QBrush(Qt::NoBrush));
setPalette(newPalette);
Вот его функция paintEvent(...):
Код:
	QPainter painter(this);
painter.setPen(privatePen);
painter.setBrush(palette().brush(QPalette::Button));
painter.drawEllipse(privateRect);

И еще функция
Код:
setRect(QRect newRect)
{
    privateRect = newRect;
    resize(privateRect.width(), privateRect.height());
    update(privateRect.width(), privateRect.height());
}


privatePen, privateRect - поля виджета, которые я задаю. Если privateRect имеет длину/ширину больше 50, то когда я делаю QPixmap::grabWidget(ellipse) (или grabWidget(ellipse, ellipse->rect())), то получившаяся картинка имеет размеры 50*50, изображает верхний левый квадрат виджета. Кроме того прозрачные "уголки" виджета в картинке, полученной из этой функции превращаются в какой-то полупрозрачный мусор. Помогите сделать правильную картинку, изображающую виджет таким, какой он есть, может я че-то неправильно делаю...
Записан
Литий
Гость
« Ответ #1 : Октябрь 24, 2007, 15:16 »

Можно использовать функцию grabWindow, она берет пиксели прямо с экрана, а не отрисовывает виджет в pixmap.
Записан
finka
Гость
« Ответ #2 : Октябрь 24, 2007, 16:44 »

В таком случае потеряют прозрачность прозрачные части виджета.
Записан
Литий
Гость
« Ответ #3 : Октябрь 24, 2007, 16:59 »

Можно посмотреть исходники grabWidget, но там используются какие-то приватные функции и флаги... А можно (раз это твой виджет) вынести код рисования в отдельную функцию:
Код:
void paintTo( QPainter &p )
{
  ...
}
и использовать ее в двух местах.
Как сделать в общем случае, непонятно...
Записан
Dodge
Гость
« Ответ #4 : Октябрь 25, 2007, 01:33 »

Вам необходимо брать картинку именно с канвы виджета?
Может стоит упростить и рисовать этот эллипс сразу в пиксмап?  Смеющийся

Типа того:
Код:
QPixmap myimage;
QPainter painter( &myimage );
painter.setPen(privatePen);
painter.setBrush(palette().brush(QPalette::Button));
painter.drawEllipse(privateRect);

Записан
finka
Гость
« Ответ #5 : Октябрь 25, 2007, 14:53 »

Если учесть, что у меня не только эллипс, но и еще много чего разного бывает, то упростить таким образом не получится.
Записан
Dodge
Гость
« Ответ #6 : Октябрь 25, 2007, 17:56 »

Если учесть, что у меня не только эллипс, но и еще много чего разного бывает, то упростить таким образом не получится.
Это почемуэто не получится?...
Нада мыслить с размахом!
Код:
class MyWidget : public QWidget {
protected:
    QPaintDevice * paintdevice;
    void paintEvent( QPaintEvent * );

public:
    MyWidget( QWidget * parent=NULL );
    const QPaintDevice * currentPaintDevice();
    void setCurrentPaintDevice( QPaintDevice * pd );

};

MyWidget::MyWidget( QWidget * parent ) : QWidget( parent ) {
    paintdevice = this;
}
void MyWidget::paintEvent( QPaintEvent * ) {

    Q_ASSERT( paintdevice != NULL );

    QPainter painter( paintdevice );
    painter.setPen( privatePen );
    painter.setBrush( palette().brush( QPalette::Button ) );
    painter.drawEllipse( privateRect );

}
const QPaintDevice * MyWidget::currentPaintDevice() {
    return paintdevice;
}
void MyWidget::setCurrentPaintDevice( QPaintDevice * pd ) {
    if ( pd == NULL )
        return;
    paintdevice = pd;
}


При таком раскладе, получается оч универсальный виджет, рисуй его, куда хочешь. Если это необходимо, можно сделать еще кое что:
Код:
class MyWidget : public QWidget {
protected:
    QPaintDevice * paintdevice;
    void paintEvent( QPaintEvent * );

public:
    MyWidget( QWidget * parent=NULL );
    const QPaintDevice * currentPaintDevice();
    void setCurrentPaintDevice( QPaintDevice * pd );
    void drawTo( QPaintDevice * pd );

};

MyWidget::MyWidget( QWidget * parent ) : QWidget( parent ) {
    paintdevice = this;
}
void MyWidget::paintEvent( QPaintEvent * ) {

    drawTo( paintdevice );

}
const QPaintDevice * MyWidget::currentPaintDevice() {
    return paintdevice;
}
void MyWidget::setCurrentPaintDevice( QPaintDevice * pd ) {
    if ( pd == NULL )
        return;
    paintdevice = pd;
}
void MyWidget::drawTo( QPaintDevice * pd ) {
    Q_ASSERT( pd != NULL );

    QPainter painter( pd );
    painter.setPen( privatePen );
    painter.setBrush( palette().brush( QPalette::Button ) );
    painter.drawEllipse( privateRect );

}

drawTo можно объявить статиком и использовать так:
Код:
QPixmap image;
MyWidget::drawTo( &image );
Записан
finka
Гость
« Ответ #7 : Октябрь 26, 2007, 15:49 »

А теперь представьте, что у меня есть ну допустим ellipseWidget, rectWidget, lineWidget, QPushButton, QLabel и тд, все они содержатся в списке QList <QWidget *>, и я в данный момент времени не знаю, кто там есть кто, и мне надо нарисовать изображение некоторого элемента оттуда. Грубо говоря, это лишь попытка сделать drag/drop с перетаскивающимся изображением виджета. Перебирать все типы в поисках нужного, чтобы именно к его функции обратиться, жутко неудобно.
Записан
Dodge
Гость
« Ответ #8 : Октябрь 29, 2007, 14:17 »

А теперь представьте, что у меня есть ну допустим ellipseWidget, rectWidget, lineWidget, QPushButton, QLabel и тд, все они содержатся в списке QList <QWidget *>, и я в данный момент времени не знаю, кто там есть кто, и мне надо нарисовать изображение некоторого элемента оттуда. Грубо говоря, это лишь попытка сделать drag/drop с перетаскивающимся изображением виджета. Перебирать все типы в поисках нужного, чтобы именно к его функции обратиться, жутко неудобно.
Хы.
А как же наследование?
1. Создаем абстрактный базовый класс с этой функцией:
Код:
class MyBaseWidget : public QWidget {
    ...
    virtual void drawTo( QPaintDevice * pd ) = 0;
    ...
};
2. Наследуемся от базового класса, и определяем нашу функцию:
Код:
class MyEllipseWidget : public MyBaseWidget {
    ...
    void drawTo( QPaintDevice * pd ) {
        Q_ASSERT( pd != NULL );

        QPainter painter( pd );
        painter.setPen( privatePen );
        painter.setBrush( palette().brush( QPalette::Button ) );
        painter.drawEllipse( privateRect );
    }
    ...
};
class MyQuadWidget : public MyBaseWidget {
    ...
    void drawTo( QPaintDevice * pd ) {
        Q_ASSERT( pd != NULL );

        QPainter painter( pd );
        painter.setPen( privatePen );
        painter.setBrush( palette().brush( QPalette::Button ) );
        painter.drawEllipse( privateRect );
    }
    ...
};
3. Работа со списком виджетов:
Код:
    QList<MyBaseWidget*> mywidgets;
    foreach ( MyBaseWidget * widget, mywidgets ) {
    QPixmap image;
        widget->drawTo( &image );
    }

Еще вопросы?

З.Ы. Если чтото не понятно, могу прислать рабочий пример.

З.Ы.Ы. А вообще, технология драг энд дроп в куте реализованна немного по другому.
Записан
finka
Гость
« Ответ #9 : Октябрь 30, 2007, 13:18 »

Как я уже написала, наряду с моими виджетами планируется использовать qt-шные:
Цитировать
ellipseWidget, rectWidget, lineWidget, QPushButton, QLabel и тд
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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