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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не отображается виджет в QScrollArea  (Прочитано 8879 раз)
klim
Гость
« : Июль 18, 2008, 10:33 »

Здравствуйте!
Имеется самодельный widget, созданный на основе QWidget, рисующий с помощью paintEvent битмап. При обычном вызове:
Код:
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    paintWidget widget;
    widget.show();

    return app.exec();
}
всё работает как надо.

Однако после попытки запихнуть его в QScrollArea, получаю только серый фон области прокрутки, а сам widget не отрисовывается.
Код:
mainWidget::mainWidget(QWidget *parent) : QWidget(parent)
{
    paintWidget *map = new paintWidget();
    scrollArea = new QScrollArea(this);
    scrollArea->setWidget(map);
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    mainWidget widget;
    widget.show();

    return app.exec();
}
В чем косяк?
Записан
spirit
Гость
« Ответ #1 : Июль 18, 2008, 11:04 »

имхо, что-то не то с вашим виджетом, т.к. если сделать следующую земену, то все ок
Код:
mainWidget::mainWidget(QWidget *parent) : QWidget(parent)
{
    QTextEdit *map = new QTextEdit();
    scrollArea = new QScrollArea(this);
    scrollArea->setWidget(map);
}
а ваш paintWidget содержит лейауты?
Записан
klim
Гость
« Ответ #2 : Июль 18, 2008, 11:13 »

Ну, да. Я тоже подсовывал QLabel с тем же битмапом - всё на ура работает.

Если нужно вот мой страшный код paintWidget:
Код:
class paintWidget : public QWidget
{
public:
    paintWidget(QWidget *parent = 0);
   
protected:
    void paintEvent(QPaintEvent *e);
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    bool isInside(int ix, int iy, int a, int n);
   
private:
    QPixmap mapImage;
    QPoint curLine[2];
    QPoint point[MAX_VERTEX_NUMBER];
    int vert_num;
   
    QPoint area[MAX_AREA_NUMBER][MAX_VERTEX_NUMBER];
    int area_num;
    int a_vert_num[MAX_AREA_NUMBER];
   
    int activeArea;
   
    bool bDrawing;
   
    double x1lon, x2lon;  // ??????? - x
    double y1lat, y2lat;  // ?????? - y
    int width, height;
    double stepx, stepy;
    double curlon, curlat;
};

paintWidget::paintWidget(QWidget *parent) : QWidget(parent)
{
    setMouseTracking(true);
   
    vert_num = 0;
    area_num = 0;
    activeArea = -1;
   
    mapImage = QPixmap("e:\\map.bmp");
    width = mapImage.width();
    height = mapImage.height();
   
    x1lon = 30.146484;
    x2lon = 30.585938;
    y1lat = 59.800634;
    y2lat = 60.108670;
   
    stepx = (x2lon - x1lon) / width;
    stepy = (y2lat - y1lat) / height;
   
    bDrawing = false;
}

void paintWidget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    QPen pen;
    QBrush brush;
   
    painter.drawPixmap(0,0,mapImage);
   
    pen.setColor(QColor(0,200,0));
    pen.setWidth(2);
    painter.setPen(pen);
    brush.setStyle(Qt::SolidPattern);
    brush.setColor(QColor(0,255,0,10));
    painter.setBrush(brush);
    for(int a=0; a<area_num; a++)
    {
        for(int i=1; i<a_vert_num[a]; i++)
        {
            painter.drawPolygon(area[a],a_vert_num[a]-1);
        }
    }
   
   
    pen.setColor(QColor(Qt::black));
    painter.setPen(pen);
    painter.setFont(QFont("Lucida Console",14));
    painter.drawText(QRect(15,10,200,200),QString("%1\n%2").arg(curlat).arg(curlon));
   
    pen.setColor(QColor(255,128,0));
    pen.setWidth(2);
    painter.setPen(pen);
    if(bDrawing)
    {
        for(int i=1; i<vert_num; i++)
            painter.drawLine(point[i-1],point[i]);
        painter.drawLine(curLine[0],curLine[1]);
    }
    if(activeArea >= 0)
    {
        painter.drawPolygon(area[activeArea],a_vert_num[activeArea]-1);
    }
   
}

void paintWidget::mousePressEvent(QMouseEvent *e)
{
     if(e->button() == Qt::LeftButton)
     {
         if(bDrawing)
         {
             point[vert_num++] = curLine[1];
             curLine[0] = curLine[1];
         }else{
             point[0] = e->pos();
             vert_num = 1;
             curLine[0] = curLine[1] = e->pos();
             bDrawing = true;
         }
     }
     
     if(e->button() == Qt::RightButton)
     {
         if(bDrawing)
         {
             point[vert_num++] = point[0];
             bDrawing = false;
             
             // ??????????? ?????????? ??????? ? ????????
             int l = sizeof(point) / sizeof(point[0]);
             for(int i=0; i<l; i++)
             {
                 area[area_num][i] = point[i];
             }
             a_vert_num[area_num++] = vert_num;
         }
     }
     
     update();
}

void paintWidget::mouseMoveEvent(QMouseEvent *e)
{
    if(bDrawing)
    {
        // ???????? ? ???????????
        QPoint mouse;
        QPoint point;
        QPoint temp;
        int m = 999;
        int tempm;
        mouse = e->pos();
        for(int a=0; a<area_num; a++)
        {
            for(int i=1; i<a_vert_num[a]; i++)
            {
                temp = mouse-area[a][i];
                tempm = temp.manhattanLength();
                if(tempm < m)
                {
                    point = area[a][i];
                    m = tempm;                   
                }
            }
        }
        if(m<20)
        {
            curLine[1] = point;
        }else{
            curLine[1] = e->pos();
        }
        update();
    }else{
        activeArea = -1;
        for(int i=0; i<area_num; i++)
            if(isInside(e->x(),e->y(),i,a_vert_num[i]))
                activeArea = i;
        update();
    }
   
    curlon = x1lon + e->x()*stepx;
    curlat = y2lat - e->y()*stepy;
}

bool paintWidget::isInside(int ix, int iy, int a, int n)
{
    // mine
    double sx = (double)ix;
    double sy = (double)iy;
   
    int poly[n*2];
    for(int i=0; i<n; i++)
    {
        poly[i*2] = area[a][i].x();
        poly[i*2+1] = area[a][i].y();
    }
    // end of mine
   
  int x[50], y[50];
  n--;
  for(int i=0; i<n; i++)
  {
    x[i] = poly[i*2];
    y[i] = poly[i*2+1];
  }
int pj, pk=0;
double wrkx, yu, yl;
for (pj=0; pj<n; pj++)
{
yu = y[pj]>y[(pj+1)%n]?y[pj]:y[(pj+1)%n];
yl = y[pj]<y[(pj+1)%n]?y[pj]:y[(pj+1)%n];
if (y[(pj+1)%n] - y[pj])
wrkx = x[pj] + (x[(pj+1)%n] - x[pj])*(sy - y[pj])/(y[(pj+1)%n] - y[pj]);
else
wrkx = x[pj];
if (yu >= sy)
if (yl < sy)
{
if (sx > wrkx)
pk++;
if (fabs(sx - wrkx) < 0.00001) return true;
}
if ((fabs(sy - yl) < 0.00001) && (fabs(yu - yl) < 0.00001) && (fabs(fabs(wrkx - x[pj]) + fabs(wrkx - x[(pj+1)%n]) - fabs(x[pj] - x[(pj+1)%n])) < 0.0001))
return true;
}
if (pk%2)
return true;
else
return false;
}
Записан
spirit
Гость
« Ответ #3 : Июль 18, 2008, 11:15 »

желательно еще бы указывать версию кути
Записан
Alex03
Гость
« Ответ #4 : Июль 18, 2008, 11:17 »

Определите sizeHint() для своего paintWidget, ну или на крайняк установите для него минимальный размер - setMinimumSize().
Записан
klim
Гость
« Ответ #5 : Июль 18, 2008, 11:20 »

желательно еще бы указывать версию кути
4.4.0

Определите sizeHint() для своего paintWidget, ну или на крайняк установите для него минимальный размер - setMinimumSize().
Спасибо, сейчас почитаю.
Записан
klim
Гость
« Ответ #6 : Июль 18, 2008, 11:26 »

А setMinimumSize() где нужно прописывать? Я в конструкторе piantWidget написал, так у меня scrollArea вообще в точку превратилась  Злой
Записан
spirit
Гость
« Ответ #7 : Июль 18, 2008, 11:30 »

в общем все работает.
Код:
paintWidget::paintWidget(QWidget *parent) : QWidget(parent)
{
    setMouseTracking(true);
   
    vert_num = 0;
    area_num = 0;
    activeArea = -1;
   
mapImage = QPixmap("e:/map.bmp");
    width = mapImage.width();
    height = mapImage.height();

    resize(width, height);
....
Записан
klim
Гость
« Ответ #8 : Июль 18, 2008, 11:33 »

в общем все работает.
Да, точно... хм..
Спасибо.

А почему он в первом случае выводит с какими-то размерами по-умолчанию виджет, а во втором (там где qscrollarea появляется) - нет?
Записан
Alex03
Гость
« Ответ #9 : Июль 18, 2008, 12:24 »

А setMinimumSize() где нужно прописывать? Я в конструкторе piantWidget написал, так у меня scrollArea вообще в точку превратилась  Злой
Совсем простенький пример проекта не помешал бы.

Цитировать
When using a scroll area to display the contents of a custom widget, it is important to ensure that the size hint of the child widget is set to a suitable value. If a standard QWidget is used for the child widget, it may be necessary to call QWidget::setMinimumSize() to ensure that the contents of the widget are shown correctly within the scroll area.
И
Цитировать
Size Hints and Size Policies

When implementing a new widget, it is almost always useful to reimplement sizeHint() to provide a reasonable default size for the widget and to set the correct size policy with setSizePolicy().

By default, composite widgets which do not provide a size hint will be sized according to the space requirements of their child widgets.

The size policy lets you supply good default behavior for the layout management system, so that other widgets can contain and manage yours easily. The default size policy indicates that the size hint represents the preferred size of the widget, and this is often good enough for many widgets.

Записан
klim
Гость
« Ответ #10 : Июль 20, 2008, 18:13 »

Совсем простенький пример проекта не помешал бы.
Пример программки, где QScrollArea в точку превращается?
Записан
Alex03
Гость
« Ответ #11 : Июль 21, 2008, 08:33 »

Совсем простенький пример проекта не помешал бы.
Пример программки, где QScrollArea в точку превращается?
Да, я имел ввиду минимально возможный вариант кода, который целиком компилируется, и в котором проявляется Ваша "проблема".

Потому как иначе многое не понятно.
например приводя код
Код:
mainWidget::mainWidget(QWidget *parent) : QWidget(parent)
{
    paintWidget *map = new paintWidget();
    scrollArea = new QScrollArea(this);
    scrollArea->setWidget(map);
}
Ничего не ясно об этом mainWidget, и сдаётся мне что тут проблема не только в том что paintWidget не ресайзится в QScrollArea, но и в том что QScrollArea не ресайзится в mainWidget, по крайней мере Вы про это ничего не сказали, и не привели остального кода mainWidget с лэйаутами или чёнить типа:
Код:
void mainWidget::resizeEvent(QResizeEvent * event)
{
    m_pScrollArea->resize(event->size());
}


Приведите примерчик типа такого:
Код:
#include <QApplication>
#include <QPushButton>
#include <QPainter>
#include <QImage>
#include <QRgb>
#include <QMainWindow>
#include <QScrollArea>

//#define USE_SET_MIN_SIZE 1
//#define USE_MIN_HINT     1

class paintWidget : public QWidget
{
public:
    paintWidget(QWidget *parent = 0);
   
#ifdef USE_MIN_HINT
    virtual QSize sizeHint() const;
#endif
protected:
    void paintEvent(QPaintEvent *e);
   
private:

    QSize m_size;
    QImage m_img;
};

paintWidget::paintWidget(QWidget *parent) : QWidget(parent)
{
    m_size = QSize(256, 256);
    m_img = QImage(m_size, QImage::Format_RGB32);
#ifdef USE_SET_MIN_SIZE
    setMinimumSize(m_size);
#endif
}
#ifdef USE_MIN_HINT
QSize paintWidget::sizeHint() const
{
    return m_size;
}
#endif
void paintWidget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    QPen pen;
    QBrush brush;

    for(int y=0; y<m_size.height(); y++)
    {
        QRgb* prgb = (QRgb*)m_img.scanLine(y);
        for(int x=0; x<m_size.width(); x++)
        {
            *prgb++ = qRgb(x, y, x+y);
        }
   
    }

    painter.drawImage(QRect(0, 0, width(), height()), m_img, QRect(0, 0, 256, 256));
}

int main( int argc, char **argv )
{
    QApplication a( argc, argv );

    paintWidget pw1;
    pw1.show();

    QMainWindow mw;
    mw.show();

    QScrollArea* psa = new QScrollArea(&mw);
    mw.setCentralWidget(psa);
    paintWidget* ppw2 = new paintWidget(psa);
    psa->setWidget(ppw2);

    return a.exec();
}
Попробуйте в нём последовательно разкомментировать строки
Код:
//#define USE_SET_MIN_SIZE 1
//#define USE_MIN_HINT     1
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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