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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Проблемы новичка с QTableWidget [РЕШЕНО]  (Прочитано 28593 раз)
_Vitaliy_
Гость
« : Сентябрь 03, 2008, 21:38 »

Только начал изучать Qt, стоит версия 4.3.1. Решил начать изучение с реального примера: необходимо считать файл данных следующего формата (вложение 102_2662.stf):

t,Hb,Vp,Xv,Xe,Xn ...
     79.000      81.633    -600.000     -23.333       5.333       0.000             
     79.250      81.633    -600.000     -23.333       5.333      -2.609       
     79.500      81.633    -600.000     -23.333       5.333      -2.609       
     79.750      81.633    -600.000     -23.333       5.333      -2.609   
     80.000      81.633    -600.000     -23.333       5.333      -2.609
...

В зависимости от кол-ва параметров (t,Hb,Vp,Xv,Xe,Xn ...) определяется кол-во столбцов QTableWidget"а, кол-во строк данных определяет кол-во строк QTableWidget"а соответственно и записать данные в QTableWidget, с которого потом будет осуществлятся считывание и дальнейшая обработка.         

Вроде смотрел на примеры, вроде "лазил" по форуму но проблему пока не решил, выкладываю то что наваял я, извиняйте но только учусь.

В файле mainform.cpp использую split(' '), как в книге Бланшет, но не могу сделать так что-бы данные записывались во все ячейки строки, а не в первую ячейку, это первая проблема.

Вторая заключается в том что не могу пока понять как при запуске программы (то что я написал) появляется новое окно
с QTableWidget"ом, вроде в "Десигнере" вставил на форму QTableWidget а как к нему программно обратиться не пойму...

Код:
mainform.cpp:

#include "mainform.h"
//
MainForm::MainForm( QWidget * parent, Qt::WFlags f)
: QMainWindow(parent, f)
{
setupUi(this);
connect(pushButton, SIGNAL(clicked()), this, SLOT(OpenFile()));
}
//


void MainForm::OpenFile()
{
QString fileName = QFileDialog::getOpenFileName(this);

QFile file (fileName);
if (file.open(QIODevice::ReadOnly))
{
QTextStream stream(&file);
QString str;
stream.setCodec("UTF-8");

QTableWidget* tbl = new QTableWidget;
tbl->setColumnCount(3);
    tbl->setRowCount(10);
   
   //   lst << "First" << "Second" << "Third";
    // tbl->setHorizontalHeaderLabels(lst);

    tbl->setColumnCount(20);
    tbl->setRowCount(2);
    int row=0,col=0;
while (!stream.atEnd())
{
str = stream.readLine();
QStringList fields = str.split(' ');

int f = fields.takeLast().toInt();
for (int i=0; i<=f; ++i)
{
QTableWidgetItem *item = new QTableWidgetItem;
item->setData(fields);
tbl->setItem(row, i, item);
}


}
if (stream.status() != QTextStream::Ok)
{
qDebug() << "Ошибка чтения файла";
}

file.close();
tbl->show();
}

}

mainform.h:
#ifndef MAINFORM_H
#define MAINFORM_H
//
#include <QMainWindow>
#include "ui_mainwindow.h"
#include <QtGui>
#include <QTextStream>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QStringList>
//
class MainForm : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
public:
MainForm( QWidget * parent = 0, Qt::WFlags f = 0 );
//QTableWidget *tbl;  // ???
//QTableWidgetItem ptwi = 0;
    QStringList       lst;

private slots:

void OpenFile();

};
#endif


Заранее признателен если кто укажет на мои "пробелы"...

Пользуйтесь тэгом КОД для форматирования исходного кода!

 
« Последнее редактирование: Январь 31, 2009, 18:04 от Константин » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Сентябрь 03, 2008, 22:28 »

Цитировать
не могу пока понять как при запуске программы (то что я написал) появляется новое окно
с QTableWidget"ом
ты его сам создаешь в void MainForm::OpenFile() :
QTableWidget* tbl = new QTableWidget;

Цитировать
вставил на форму QTableWidget а как к нему программно обратиться не пойму
т.к. у тебя множественное наследование класса MainForm, то обращайся в этом классе непосредственно, т.е. как он у тебя в дизайнере обозван
« Последнее редактирование: Сентябрь 03, 2008, 22:30 от lit-uriy » Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #2 : Сентябрь 03, 2008, 22:53 »

вместо:
Код:
int f = fields.takeLast().toInt();
for (int i=0; i<=f; ++i)
{
QTableWidgetItem *item = new QTableWidgetItem;
item->setData(fields);  // <---------- Вставил весь список залпом !!!
tbl->setItem(row, i, item);
}
я бы использовал:
Код:
int i=0;
// для каждой строки из списка строк
foreach (QString str, fields)
{
QTableWidgetItem *item = new QTableWidgetItem;
item->setData(str);  // <---------- Вставил один элемент списка
tbl->setItem(row, i++, item);
}
Записан

Юра.
_Vitaliy_
Гость
« Ответ #3 : Сентябрь 05, 2008, 17:49 »

lit-uriy, попробовал код который Вы предложили:
Код:
...
item->setData(str); 
...


В этом месте выбивает error: no matching function for call to 'QTableWidgetItem::setData(QStringList&)'

Непонимающий
Записан
ритт
Гость
« Ответ #4 : Сентябрь 05, 2008, 18:14 »

бред. ветку под снос
иди читай документацию
Записан
ритт
Гость
« Ответ #5 : Сентябрь 05, 2008, 22:52 »

ну, какими тут ссылками поможешь, если наличествует банальное нежелание читать?
ни бланшет, ни шлее, ни папа римский не помогут, если не читать ассистант и/или http://doc.trolltech.com/

> QTableWidgetItem::setData(QStringList&)
а строкой ниже кандидатов не показали?

Цитировать
void QTableWidgetItem::setData ( int role, const QVariant & value )   [virtual]
Sets the item's data for the given role to the specified value.

> своими высказываниями я отбиваю желание учиться
мне кажется, своими высказываниями я прививаю необходимое качество любого кодера и даже, наверное, кастомера - привычку/умение читать документацию взамен привычки гуглить и занудствовать на форумах по каждому вопросу!

счастливого изучения документации...

с уважением, константин

з.ы. не только в языках программирования существует синтаксис и орфограция - в русском языке тоже
Записан
_Vitaliy_
Гость
« Ответ #6 : Сентябрь 18, 2008, 16:03 »

Немного разобрался по этому вопросу, наверное отвечу сам себе, может еще кому пригодится, тем более что модератор: "...ветку под снос" (за что спасибо) этого не сделал  Улыбающийся

Код:
void MainForm::OpenFile()
{
QString fileName = QFileDialog::getOpenFileName(this);

QFile file (fileName);
if (file.open(QIODevice::ReadOnly))
{
QTextStream stream(&file);

stream.setCodec("CP-866");

QTableWidget* tbl = new QTableWidget;
   
      lst << "First" << "Second" << "Third";
    tbl->setHorizontalHeaderLabels(lst);
   
    tbl->setColumnCount(5);
    tbl->setRowCount(5);
   
    int f=0, row=0,col=0, tt=0, vv=0;
   
    QString str;
    QString fff, ggg;
    QList<QString> gg;
    QStringList fields;
   
    while (!stream.atEnd())
{
str = stream.readLine(); //chtenie stroki
str = str.simplified();  //ubiraet pustie probeli v stroke
if (tt<=3) fields = str.split(",");
if (tt>3) fields = str.split(' ');

tbl->setColumnCount(f);
tbl->setRowCount(tt+1);
gg = fields;

f = fields.size();

for (int i=0; i<=(f-1); ++i)
{
fff = gg.at(i);
QTableWidgetItem *item = new QTableWidgetItem;
item->setText(QString(fff));
tbl->setItem(tt, i, item);
}

  ++tt;
     
}
if (stream.status() != QTextStream::Ok)
{
qDebug() << "Р_С_РёР+РєР° С╪С'РчР_РёС_ С"айР>Р°";
}

file.close();
tbl->show();
}

Единственное сопутствующий вопрос: это хорошо работает для открытия файлов небольшого объема, а если файл более 2 мегабайт "весит" то все очень сильно "тормозит". Вроде надо пользоваться вместо QTableWidget QTableView"ом если у кого-то есть наработки поделитесь плиз 
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #7 : Сентябрь 18, 2008, 16:14 »

Чтобы интрефейс не "умирал" на время считывания данных из большого файла, добавьте в цикл следующее:


Код:
while (!stream.atEnd())
{
...
    qApp->processEvents();
...
}

Почитайте по этому поводу Бланшетте, глава "7.3. Сокращение времени отклика при длительной обработке данных."
« Последнее редактирование: Сентябрь 18, 2008, 16:16 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #8 : Сентябрь 18, 2008, 16:58 »

Причем чтобы время не сильно увеличилось, можно сделать так:
int i=0;
while(..........
{
    i++;
    if ((i/100)*100==i)
        qApp->processEvents();
.........
}
То бишь срабатывать будет на каждой сотой итерации. Улыбающийся
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
_Vitaliy_
Гость
« Ответ #9 : Сентябрь 18, 2008, 17:19 »

Да, помогло, спасибо, но время открытия файла размером в 2 "метра" составляет более полутора минут, хотя таже самая программа, написанная в Билдере 6.0 это делает на порядок быстрее... может все-таки нужно использовать QTableView, по-моему или у Бланшет или у Шлее об этом сказано.   
Записан
Alex03
Гость
« Ответ #10 : Сентябрь 18, 2008, 17:26 »

Код:
str = stream.readLine();
Угадайте как оно работает. Улыбающийся
Если читать блоками в память, вручную находить концы строк, и уже их потом обрабатывать то получится на порядок (порядки) быстрее.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #11 : Сентябрь 18, 2008, 17:28 »

Можно отключить обновление, т.е. вначале setUpdatesEnabled(false) и в конце setUpdatesEnabled(true). Но через модель быстрее будет.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
ритт
Гость
« Ответ #12 : Сентябрь 18, 2008, 17:37 »

в моделях есть такая фича - fetchMore. я сомневаюсь, что у кого-то найдётся монитор такой диагонали чтобы вся таблица разом влезла в один экран.
QTableWidget - это а) для ленивых; б) для сверхпростых задач. если требуется приличная производительность для больших объёмов данных, пользуемся QTableView/QAbstractItemModel
Записан
Tonal
Гость
« Ответ #13 : Сентябрь 18, 2008, 17:54 »

Не нужно читать блоками - там тормозов и без этого хватает.
Отключить обновление кардинально поможет, особенно, если стоит автоматический ресайз колонок.
В Eric4 так на порядок ускорили загрузку данных профилера.
Ну и переход на свою модель тоже даст существенный выигрыш и не только в скорости. Улыбающийся
Записан
ритт
Гость
« Ответ #14 : Сентябрь 18, 2008, 18:02 »

Не нужно читать блоками
это про fetchMore ?
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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