Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Larry от Июнь 06, 2011, 17:04



Название: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 06, 2011, 17:04
Добрый день, форумчане! Подскажите пожалуйста в чем может быть ошибка...Есть QTabWidget и при закрытии его вкладок закрываются все, которые находятся справа. Закрываю вкладку
Код:
QTabWidget::removeTab(index);
вставил вывод индекса в консоль и видно, что при закрытии любой вкладки слот вызывается столько раз сколько всего вкладок в QTabWidget.


Название: Re: закрытие таба в QTabWidget
Отправлено: LisandreL от Июнь 06, 2011, 19:32
Ну вы побольше кода-то выложите, а лучше программу.


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 06, 2011, 19:48
сегодня уже не получится, но завтра с утра сразу выложу...


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 07, 2011, 10:20
Код:
Вот кусок кода где происходит добавление вкладок в таб

[code]void CLevEd::slotTileCreate()
{

QString strImagename = QFileDialog::getOpenFileName(this,
tr("открыть изображение"), NULL,
tr("Изображение(*.jpg; *.png; *.bmp; *.gif)"));
if(strImagename.isEmpty())
return;

QString str;
str = strImagename.section('/', -1);

CDlgTileParameter *ptr_dlg = new CDlgTileParameter(str);

if(ptr_dlg->exec() == QDialog::Rejected)
return;

QSize tileSize = ptr_dlg->getSize();
// создание и настройка вида
m_teView = new CTileEdit(m_lwTilesList);
m_teView->setImage(strImagename);
m_teView->setTileSize(tileSize);

m_twView->addTab(m_teView, str);

connect(m_twView, SIGNAL(tabCloseRequested(int)), this, SLOT(slotCloseTab(int)));
}
а здесь происходит закрытие
Код:
void CLevEd::slotCloseTab(int index)
{
qDebug() << tr("вкладка №-") << index;
m_twView->removeTab(index);
}

где m_teView - это наследованный класс QGraphicsView
     m_twView - QTabWidget[/code]


Название: Re: закрытие таба в QTabWidget
Отправлено: GreatSnake от Июнь 07, 2011, 10:47
При каждом добавлении таб-а вешаешь слот
Код
C++ (Qt)
connect(m_twView, SIGNAL(tabCloseRequested(int)), this, SLOT(slotCloseTab(int)));
Этот слот нужно вешать единожды при создании QTabWidget-a.


Название: Re: закрытие таба в QTabWidget
Отправлено: LisandreL от Июнь 07, 2011, 10:55
Да, либо единожды, либо Qt::UniqueConnection.


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 07, 2011, 10:56
спасибо, ща попробую:)


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 07, 2011, 11:33
Спасибо большое еще раз, все работает! Появился еще один вопрос по QListWidget и решил задать его здесь. Во вложении на рисунке видно, что в QListWidget добавление пиктограмм происходит не по всей ширине(справа остается область достаточная для добавления еще одного изображения), почему может так происходить и что надо сделать, чтобы пиктограммы добавлялись по всей ширине списка?


Название: Re: закрытие таба в QTabWidget
Отправлено: GreatSnake от Июнь 07, 2011, 11:53
Какой flow() у QListWidget?
И с лейаутом всё в порядке? Непонятный правый отступ там какой-то.


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 07, 2011, 12:01
flow() пытался ставить как слева на право, так и сверху вниз(в этом случае внизу отступ был),все оставалось без изменений.
С лайоутом все нормально, то я выставлял фиксированный размер для списка...


Название: Re: закрытие таба в QTabWidget
Отправлено: GreatSnake от Июнь 07, 2011, 12:16
С лайоутом все нормально, то я выставлял фиксированный размер для списка...
И зачем  ???


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 07, 2011, 12:29
пробовал:), но ничего так и не помогло...непонятно как сделать чтобы отображалось нормально...


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 07, 2011, 13:04
больше никаких вариантов нет?


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 07, 2011, 16:57
перепробовал уже все варианты и не пойму как это исправить...помогите please!!!


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 08, 2011, 08:36
А какой еще можно использовать виджет для этих же целей?


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 08, 2011, 11:15
Подскажите пожалуйста, как можно отключить горизонтальную прокрутку в QListWidget?


Название: Re: закрытие таба в QTabWidget
Отправлено: GreatSnake от Июнь 08, 2011, 11:18
Подскажите пожалуйста, как можно отключить горизонтальную прокрутку в QListWidget?
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 08, 2011, 12:00
спасибо большое


Название: Re: закрытие таба в QTabWidget
Отправлено: GreatSnake от Июнь 08, 2011, 12:20
А какой еще можно использовать виджет для этих же целей?
Судя по-всему у троллей баг в QListView - они при расчёте лейаута элементов всегда учитывают размер скроллбара, если у него полиси ScrollBarAsNeeded :(
Чтобы решить эту проблему, нужно установить другой скроллбар полиси либо использовать что-нибудь другое, например FlowLayout:
Код
C++ (Qt)
#include <QApplication>
#include <QScrollArea>
#include <QStyle>
#include <QPushButton>
#include <QLayout>
 
//
class FlowLayout : public QLayout
{
//Q_OBJECT // uncomment in the header
public:
FlowLayout( QWidget* parent = 0, int margin = -1, int hSpacing = -1, int vSpacing = -1 );
virtual ~FlowLayout();
 
void addItem( QLayoutItem *item );
int horizontalSpacing() const;
int verticalSpacing() const;
Qt::Orientations expandingDirections() const;
bool hasHeightForWidth() const;
int heightForWidth( int ) const;
int count() const;
QLayoutItem *itemAt( int index ) const;
QSize minimumSize() const;
void setGeometry( const QRect& rect );
QSize sizeHint() const;
QLayoutItem *takeAt( int index );
void insertWidget( int index, QWidget* w );
 
protected:
int doLayout( const QRect& rect, bool testOnly ) const;
int smartSpacing( QStyle::PixelMetric pm ) const;
 
private:
QList< QLayoutItem* > itemList_;
int h_space_;
int v_space_;
QSize max_size_;
};
 
//
FlowLayout::FlowLayout( QWidget* parent, int margin, int hSpacing, int vSpacing )
: QLayout( parent )
, h_space_( hSpacing )
, v_space_( vSpacing )
{
parent->setLayout( this );
setContentsMargins( margin, margin, margin, margin );
}
 
FlowLayout::~FlowLayout()
{
QLayoutItem *item;
while( ( item = takeAt( 0 ) ) )
delete item;
}
 
void FlowLayout::addItem( QLayoutItem *item )
{
QSize sz( item->widget()->sizeHint() );
 
if( sz.width() > max_size_.width() ||
sz.height() > max_size_.height() )
{
max_size_ = item->widget()->sizeHint();
QLayoutItem *item;
foreach( item, itemList_ )
{
item->widget()->resize( max_size_ );
}
}
 
item->widget()->resize( max_size_ );
itemList_.append( item );
}
 
void FlowLayout::insertWidget( int index, QWidget* w )
{
bool is_shown = w->isVisible();
if( is_shown )
w->hide();
 
addWidget( w );
if( index >= 0 && index < itemList_.count() - 1 )
itemList_.move( itemList_.count() - 1, index );
 
if( is_shown )
w->show();
}
 
int FlowLayout::horizontalSpacing() const
{
if( h_space_ >= 0 )
return h_space_;
else
return smartSpacing( QStyle::PM_LayoutHorizontalSpacing );
}
 
int FlowLayout::verticalSpacing() const
{
if( v_space_ >= 0 )
return v_space_;
else
return smartSpacing( QStyle::PM_LayoutVerticalSpacing );
}
 
int FlowLayout::count() const
{
return itemList_.size();
}
 
QLayoutItem *FlowLayout::itemAt( int index ) const
{
return itemList_.value( index );
}
 
QLayoutItem *FlowLayout::takeAt( int index )
{
QLayoutItem* taked_item = 0;
if( index >= 0 && index < itemList_.size() )
{
taked_item = itemList_.takeAt( index );
 
max_size_ = QSize( 0, 0 );
QLayoutItem *item;
foreach( item, itemList_ )
{
QSize sz( item->widget()->sizeHint() );
if( sz.width() > max_size_.width() ||
sz.height() > max_size_.height() )
max_size_ = sz;
}
foreach( item, itemList_ )
{
item->widget()->resize( max_size_ );
}
}
return taked_item;
}
 
Qt::Orientations FlowLayout::expandingDirections() const
{
return 0;
}
 
bool FlowLayout::hasHeightForWidth() const
{
return true;
}
 
int FlowLayout::heightForWidth( int width ) const
{
return doLayout( QRect( 0, 0, width, 0 ), true );
}
 
void FlowLayout::setGeometry( const QRect& rect )
{
QLayout::setGeometry( rect );
doLayout( rect, false );
}
 
QSize FlowLayout::sizeHint() const
{
return minimumSize();
}
 
QSize FlowLayout::minimumSize() const
{
QSize size( QLayout::minimumSize() );
 
if( count() )
size = max_size_;
 
size += QSize( 2 * margin(), 2 * margin() );
return size;
}
 
int FlowLayout::doLayout( const QRect& rect, bool testOnly ) const
{
int left, top, right, bottom;
getContentsMargins( &left, &top, &right, &bottom );
QRect effectiveRect = rect.adjusted( +left, +top, -right, -bottom );
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;
 
QLayoutItem *item;
foreach( item, itemList_ )
{
QWidget *wid = item->widget();
if( wid->isHidden() )
continue;
 
int spaceX = horizontalSpacing();
if( spaceX == -1 )
spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
if( spaceY == -1 )
spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + max_size_.width() + spaceX;
if( nextX - spaceX > effectiveRect.right() && lineHeight > 0 )
{
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + max_size_.width() + spaceX;
lineHeight = 0;
}
 
if( !testOnly )
item->setGeometry( QRect( QPoint( x, y ), max_size_ ) );
 
x = nextX;
lineHeight = qMax( lineHeight, max_size_.height() );
}
return y + lineHeight - rect.y() + bottom;
}
 
int FlowLayout::smartSpacing( QStyle::PixelMetric pm ) const
{
QObject *parent = this->parent();
if( !parent )
{
return -1;
}
else if( parent->isWidgetType() )
{
QWidget *pw = qobject_cast< QWidget* >( parent );
return pw->style()->pixelMetric( pm, 0, pw );
}
else
{
return qobject_cast< QLayout* >( parent )->spacing();
}
}
 
class FlowView : public QScrollArea
{
//Q_OBJECT // uncomment in the header
public:
FlowView( QWidget* parent = 0 );
void addWidget( QWidget* w )
{
widget()->layout()->addWidget( w );
}
void insertWidget( int index, QWidget* w )
{
#if 0 // uncomment in the header
FlowLayout* l = qobject_cast< FlowLayout* >( widget()->layout() );
#else
FlowLayout* l = dynamic_cast< FlowLayout* >( widget()->layout() );
#endif
l->insertWidget( index, w );
}
};
 
//
FlowView::FlowView( QWidget* parent )
: QScrollArea( parent )
{
setWidgetResizable( true );
QWidget* w = new QWidget( this );
setWidget( w );
new FlowLayout( w, 4, 4, 2 );
setMinimumSize( 20, 20 );
}
 
int main( int argc, char** argv )
{
QApplication app( argc, argv );
FlowView fw;
 
for( int i = 1; i <= 50; i++ )
fw.addWidget(
new QPushButton( QString( "%1" ).arg( i, 2, 10, QChar( '0' ) ) ) );
 
fw.show();
 
return app.exec();
}
 
За основу взят Qt-шный FlowLayout (http://doc.qt.nokia.com/latest/layouts-flowlayout.html#flowlayout-class-definition) и добавлено приведение всех элементов к одному размеру.


Название: Re: закрытие таба в QTabWidget
Отправлено: Larry от Июнь 08, 2011, 12:32
GreatSnake, спасибо большое...буду пробовать:)