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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Перетаскивание столбцов в QTable  (Прочитано 3311 раз)
vvvmag
Гость
« : Май 05, 2009, 08:04 »

Вопрос состоит в следующем. Сделал столбцы перетаскиваемыми, но работает некрасиво.

Во-первых не видно куда встанет перетаскиваемый столбец. Т.е. хочется видеть некоторый курсор который покажет куда встанет столбец.
Во-вторых, если место куда необходимо перетащить столбец находится за границами видимости, то прокрутка должна происходить автоматически. А то сейчас приходится подтащить к краю, руками прокрутить горизонтальный скролл и потом снова перетащить столбец.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #1 : Май 09, 2009, 17:09 »

Мне тоже интересна эта задача - как реализовывал если не секрет? QTableView  или QTableWidget

Я бы сделал отдельное окошко вызываемое из контекстного меню в котором табличка для настройки параметров столбцов

НОМЕР / НАЗВАНИЕ / ВИДИМОСТЬ / может что-то еще

а порядок определялся бы полем "НОМЕР".
Тогда задача с автоскроллингом отпадает, хотя конечно не так интуитивно.
Записан
spectre71
Гость
« Ответ #2 : Май 11, 2009, 14:41 »

Вообще, QHeaderView при широких секциях работает криво:
  1) Перетаскивание - широкие секции не всегда перетаскиваются
  2) Горизонтальный скроллер у QTableView глючит при малой ширине QTableView

По хорошему его надо полностью переписывать.

Вот пример кода с автоскроллингом.

MyTableView->setHorizontalHeader(new THorHeader (MyTableView));


.h
Код
C++ (Qt)
class THorHeader : public QHeaderView
{
 Q_OBJECT
 
protected:
 static int OffsetIdent;
 static int OffsetCount;
 static int MinInterval;
protected:
 QTableView* TableView;
 QTimer Timer;
 int OffsetSpeed;
 int SpeedCounter;
public:
 explicit THorHeader(QTableView* TableView);
 virtual ~THorHeader();
protected:
 explicit THorHeader(Qt::Orientation orientation, QWidget *parent = 0);
 virtual void mouseMoveEvent(QMouseEvent* e);
 virtual void mouseReleaseEvent(QMouseEvent* e);
 
 void updateOffset(int offset);
 bool canMove(int value);
protected slots:
   void onTimeout(void);
};
 

.cpp
Код
C++ (Qt)
int THorHeader::OffsetIdent = 16;
int THorHeader::OffsetCount = 10;
int THorHeader::MinInterval = 100;
 
THorHeader::THorHeader(Qt::Orientation orientation, QWidget *parent) : QHeaderView(orientation, parent) {
 TableView = NULL;
}
 
THorHeader::THorHeader(QTableView* TableView) : QHeaderView(Qt::Horizontal, TableView) {
 this->TableView   = TableView;
 OffsetSpeed = 0;
 
 setMovable(true);
 setMouseTracking(true);
 
 QObject::connect(&Timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
 
THorHeader::~THorHeader() {}
 
void THorHeader::mouseMoveEvent(QMouseEvent* e) {
 QHeaderView::mouseMoveEvent(e);
 if(!TableView)                     {return;}
 if(e->buttons() != Qt::LeftButton) {return;}
 
 if     (e->pos().x() <= -OffsetIdent)        {updateOffset(e->pos().x()/OffsetIdent);}
 else if(e->pos().x() >= width()+OffsetIdent) {updateOffset((e->pos().x()-width())/OffsetIdent);}
 else                                         {updateOffset(0);}
}                                    
 
void THorHeader::mouseReleaseEvent(QMouseEvent* e) {
 if(Timer.isActive()) {Timer.stop();}
 QHeaderView::mouseReleaseEvent(e);
}
 
void THorHeader::updateOffset(int offset) {
 int NewOffsetSpeed;
 if(offset < -OffsetCount) {offset = -OffsetCount;}
 if(offset >  OffsetCount) {offset =  OffsetCount;}
 
 if   (!offset)      {NewOffsetSpeed = 0;}
 else if(offset > 0) {NewOffsetSpeed =  OffsetCount + 1 - offset;}
 else                {NewOffsetSpeed = -OffsetCount - 1 - offset;}
 
 if(OffsetSpeed == NewOffsetSpeed) {return;}
 
 if(!NewOffsetSpeed) {
   if(Timer.isActive()) {Timer.stop();}
   OffsetSpeed = 0;
   return;
 }
 
 if(!Timer.isActive()) {
   OffsetSpeed  = NewOffsetSpeed;
   SpeedCounter = (OffsetSpeed > 0)?OffsetSpeed:-OffsetSpeed;
   if(canMove(TableView->horizontalScrollBar()->value())) {
     onTimeout();
     Timer.start(MinInterval);
   }
 } else {
   int NewSpeedCounter = (NewOffsetSpeed > 0)?NewOffsetSpeed:-NewOffsetSpeed;
   int OldSpeedCounter = (OffsetSpeed    > 0)?OffsetSpeed:-OffsetSpeed;
   OffsetSpeed  = NewOffsetSpeed;
   SpeedCounter += NewSpeedCounter - OldSpeedCounter;
   if(SpeedCounter <= 0) {onTimeout();}
 }
}
 
bool THorHeader::canMove(int value) {
 if(OffsetSpeed > 0) {
   if(value >= TableView->horizontalScrollBar()->maximum()) {return false;}
 } else {
   if(value <= TableView->horizontalScrollBar()->minimum()) {return false;}
 }
 return true;
}
 
void THorHeader::onTimeout(void) {
 QApplication::processEvents();
 SpeedCounter--;
 if(SpeedCounter > 0) {return;}
 SpeedCounter = (OffsetSpeed > 0)?OffsetSpeed:-OffsetSpeed;
 
 int value = TableView->horizontalScrollBar()->value();
 if(!canMove(value)) {
   Timer.stop();
   return;
 }
 if(OffsetSpeed > 0) {++value;}
 else                {--value;}
 TableView->horizontalScrollBar()->setValue(value);
}
 
Записан
vvvmag
Гость
« Ответ #3 : Май 12, 2009, 07:35 »

Спасибо, попробую.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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