
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.52] |
![]() |
|
Сообщ.
#1
,
|
|
|
Опять какие-то непонятки с виджетом
![]() Писал FTP клиент. На форме имеется QTreeWidget с и именем fileList, QLineEdit с именем serverName и QPushButton с именем connectButton. Я написал несколько слотов для работы с QFtp и соединил их с сотвествующими сигналами: ![]() ![]() 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 на строчку ![]() ![]() inline QString text(int column) const { return data(column, Qt::DisplayRole).toString(); } ну я сразу предположил, что проблема где-то в слоте processItem(QTreeWidgetItem *, int), так как именно этому слоту посылается сигнал от дабл-клике по итему. Но я прошелся отладчиком по всем инструкциям этого самого слота и программа вылетела после завершения processItem ... Вот я и не понял где у меня ошибка. Думал может в слоте обработки события нажтия кнопки Connect, но там тоже ничего ... ![]() ![]() 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)) ); /* Тут разные проверки имени сервера и предпринятие соотвествующих мер */ } |
Сообщ.
#2
,
|
|
|
Скорее всего у тебя невалидный item в processItem
З.Ы. Кстате, connect нада делать один раз. Может из-за этого еще барахлит, хотя на 100% не уверен |
Сообщ.
#3
,
|
|
|
cozzzy так почему тогда при проходе отладчиком по processItem никаких багов не замечается, а прога вылетает после выхода из функции?
Хм-м-м. Интересно. Если вынести все connect`ы связанные с ftp в конструктор, то приложение перестает функциоровать ... Потому что в connect хранится копия указателя ftp, указатель - то меняется периодически? Проблема решилась выносом connect(ui.fileList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(processItem(QTreeWidgetItem *, int))); в конструктор. Объяснить причину затрудняюсь - помогите. |
Сообщ.
#4
,
|
|
|
Цитата 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, но если значение его меняется, то действительно нужно переподписывться каждый раз |
Сообщ.
#5
,
|
|
|
cozzzy ftp это указатель на QFtp.
|
Сообщ.
#6
,
|
|
|
У тебя QUrlInfo передаётся по ссылке возможно он у них локальный, и urlInfo.name() тоже передаёшь по ссылке, в одних случаях это вызовет ошибку при копировании:
Цитата Xenon_Sk @ inline QString text(int column) const { return data(column, Qt::DisplayRole).toString(); } в д.р. при освобождении: processItem ![]() |