На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела *nix / gcc / Eclipse / Qt / wxWidgets / GTK+
  • При создании темы ОБЯЗАТЕЛЬНО указывайте версию тулкита / библиотеки / компилятора.
  • Перед тем как задать вопрос, сформулируйте его правильно, чтобы вас могли понять.
  • Нарушение Правил может повлечь наказание со стороны модераторов.


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: Majestio
  
> Непонятки с QTreeWidget
    Опять какие-то непонятки с виджетом :) А именно странный глюк.
    Писал FTP клиент.
    На форме имеется QTreeWidget с и именем fileList, QLineEdit с именем serverName и QPushButton с именем connectButton.
    Я написал несколько слотов для работы с QFtp и соединил их с сотвествующими сигналами:
    ExpandedWrap disabled
      connect(ftp, SIGNAL(listInfo(const QUrlInfo &)),this, SLOT(addToList(const QUrlInfo &)));
      connect(ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(ftpCommandFinished(int, bool)));
      connect(ui.fileList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(processItem(QTreeWidgetItem *, int)));

    addToList добавляет папку/файл в QTreeWidget. processItem реагирует на дабл-клике по QTreeWidgetItem в fileList и предпринимает соотвествующие действия (либо идет в папку либо качает файл).
    Проблема достаточно странная - я ввожу название сервера, жму на кнопку Connect - мы подключаемся, все хорошо, кнопка Connect меняет свое название на Disconnect, ходим по папочкам, качаем, одним словом все работает. Затем мы кликаем по кнопке Connect, ставшей Disconnect, отключаемся от сервера, чистим QTreeWidget, сам объект QFtp. Затем жмем Connect опять, нормально подключаемся, получаем список директорий и файлов в корне, но при попытке зайти в какую-нибудь папочку меня матерят на тему Access Violation и в VS меня кидает в файл qtreewidget.h на строчку
    ExpandedWrap disabled
          inline QString text(int column) const
              { return data(column, Qt::DisplayRole).toString(); }

    ну я сразу предположил, что проблема где-то в слоте processItem(QTreeWidgetItem *, int), так как именно этому слоту посылается сигнал от дабл-клике по итему. Но я прошелся отладчиком по всем инструкциям этого самого слота и программа вылетела после завершения processItem ... Вот я и не понял где у меня ошибка. Думал может в слоте обработки события нажтия кнопки Connect, но там тоже ничего ...
    ExpandedWrap disabled
      void FtpClient::addToList(const QUrlInfo &urlInfo)
      {
          QTreeWidgetItem* item = new QTreeWidgetItem;
          item->setText(0, urlInfo.name());
          item->setText(1, QString::number(urlInfo.size()));
          item->setText(2, urlInfo.owner());
          item->setText(3, urlInfo.group());
          item->setText(4, urlInfo.lastModified().toString("MMM dd yyyy"));
       
          QPixmap pixmap(urlInfo.isDir() ? "d:\\folder.gif" : "d:\\file.gif");
          item->setIcon(0, pixmap);
       
          isDirectory[urlInfo.name()] = urlInfo.isDir();
          ui.fileList->addTopLevelItem(item);
          if (!ui.fileList->currentItem())
          {
              ui.fileList->setCurrentItem(ui.fileList->topLevelItem(0));
              ui.fileList->setEnabled(true);
          }
      }
       
      void FtpClient::processItem(QTreeWidgetItem *item, int)
      {
          QString name = item->text(0);
          if (isDirectory.value(name))
          {
              ui.fileList->clear();
              isDirectory.clear();
              currentPath += "/" + name;
              ftp->cd(name);
              ftp->list();
              ui.currentpathLabel->setText(currentPath);
              ui.goToParent->setEnabled(true);
              setCursor(Qt::WaitCursor);
              return;
          }
          else
          {
              if ( QMessageBox::question(this, "Save", "Do you want to download " + item->text(0) + " ?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
              {
                  on_downloadButton_clicked();
                  return;
              }
              else return;
          }
       
      }
       
      void FtpClient::on_connectButton_clicked()
      {
          if (ftp)
          //Если у нас уже было соединение, то мы его разрываем и чистим QTreeWidget
          {
              setCursor(Qt::WaitCursor);
              ftp->abort();
              ftp->deleteLater();
              isDirectory.clear();
              currentPath.clear();
              ftp = 0;
              ui.fileList->clear();
              ui.fileList->setEnabled(false);
              ui.connectButton->setEnabled(true);
              ui.connectButton->setText("Connect");
              ui.goToParent->setEnabled(false);
              setCursor(Qt::ArrowCursor);
              return;
          }
          setCursor(Qt::WaitCursor);
          ftp = new QFtp(this);
          ui.fileList->clear();
          currentPath.clear();
          QUrl url( ui.serverName->text() );
          connect(ftp, SIGNAL(listInfo(const QUrlInfo &)),this, SLOT(addToList(const QUrlInfo &)));
          connect(ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(ftpCommandFinished(int, bool)));
          connect(ui.fileList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(processItem(QTreeWidgetItem *, int)));
          connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(updateProgressDialog(qint64, qint64)) );
              /* Тут разные проверки имени сервера и предпринятие соотвествующих мер */
      }
      Скорее всего у тебя невалидный item в processItem

      З.Ы. Кстате, connect нада делать один раз. Может из-за этого еще барахлит, хотя на 100% не уверен
        cozzzy так почему тогда при проходе отладчиком по processItem никаких багов не замечается, а прога вылетает после выхода из функции?
        Хм-м-м. Интересно.
        Если вынести все connect`ы связанные с ftp в конструктор, то приложение перестает функциоровать ... Потому что в connect хранится копия указателя ftp, указатель - то меняется периодически?
        Проблема решилась выносом
        connect(ui.fileList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(processItem(QTreeWidgetItem *, int)));
        в конструктор. Объяснить причину затрудняюсь - помогите.
          Цитата Xenon_Sk @
          connect(ui.fileList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(processItem(QTreeWidgetItem *, int)));
          в конструктор. Объяснить причину затрудняюсь - помогите.

          Возможно тебе дважды приходил сигнал. А так как ты делал ui.fileList->clear(); то вполне возможно, что во второй раз item и оказывался невалидным

          Цитата Xenon_Sk @
          Если вынести все connect`ы связанные с ftp в конструктор, то приложение перестает функциоровать ... Потому что в connect хранится копия указателя ftp, указатель - то меняется периодически?

          Не знаю, на что указівает ftp, но если значение его меняется, то действительно нужно переподписывться каждый раз
            cozzzy ftp это указатель на QFtp.
              У тебя QUrlInfo передаётся по ссылке возможно он у них локальный, и urlInfo.name() тоже передаёшь по ссылке, в одних случаях это вызовет ошибку при копировании:
              Цитата Xenon_Sk @
              inline QString text(int column) const { return data(column, Qt::DisplayRole).toString(); }

              в д.р. при освобождении: processItem ;)
              1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
              0 пользователей:


              Рейтинг@Mail.ru
              [ Script execution time: 0,0475 ]   [ 15 queries used ]   [ Generated: 6.07.25, 16:04 GMT ]