#c #qt #qt5
#c #qt #qt5
Вопрос:
У меня есть Mdi application
.
Это приложение позволяло открывать текстовые файлы внутри subWindow
.
Проблема в том, что вы можете открывать один и тот же файл много раз.
Я использовал следующий неполный код:
QList<QMdiSubWindow*> subWindows = ui->mdiArea->subWindowList()
Но как я могу узнать, существует ли файл или нет.
Как я могу предотвратить такое поведение?
Модификация
Я делаю следующий код, и он работает нормально: ( Please review the code
)
QList <QMdiSubWindow*> subWindows = ui -> mdiArea -> subWindowList();
if (subWindows.count() > 0) {
for (int i = 0; i < subWindows.count(); i ) {
if (subWindows.at(i) -> property("filePath").toString() == fileDlg) {
return;
}
}
}
Полный код:
QString fileDlg = QFileDialog::getOpenFileName(this, "Open File", "F://", "Text Files(*.txt)");
if (fileDlg != "") {
// Start the important code
QList < QMdiSubWindow * > subWindows = ui -> mdiArea -> subWindowList();
if (subWindows.count() > 0) {
for (int i = 0; i < subWindows.count(); i ) {
if (subWindows.at(i) -> property("filePath").toString() == fileDlg) {
return;
}
}
}
// End the important code
QString cache;
QFile file(fileDlg);
if (file.open(QFile::ReadOnly)) {
QTextStream in ( amp; file);
while (!file.atEnd()) {
cache = in .readAll();
}
}
file.close();
QFileInfo finfo(file);
QWidget * widget = new QWidget(this);
QTextEdit * TextEdit = new QTextEdit(widget);
TextEdit -> setObjectName("myTextEdit");
QMdiSubWindow * mdiWindows = ui -> mdiArea - > addSubWindow(widget);
mdiWindows -> setProperty("filePath", fileDlg);
mdiWindows -> setGeometry(5, 5, 300, 250);
mdiWindows -> setWindowTitle(finfo.baseName());
mdiWindows -> layout() -> addWidget(TextEdit);
mdiWindows -> setWindowState(Qt::WindowMaximized);
mdiWindows -> layout() -> setSpacing(0);
TextEdit -> setText(cache);
mdiWindows -> show();
}
Комментарии:
1. используйте контейнер для ведения списка открытых файлов, при открытии нового файла проверьте, есть ли открываемый файл в списке открытых файлов.
2. Спасибо, но можно ли привести мне пример?
Ответ №1:
В зависимости от операционной системы один и тот же файл может иметь несколько разных имен. Даже на одно и то же имя можно ссылаться по-разному (подумайте о том, чтобы обойти структуру каталогов!). Любая схема, основанная исключительно на именах, обречена на провал.
Это часто бывает даже весьма полезно, я часто открываю один и тот же файл несколько раз, чтобы просмотреть одно место при редактировании другого. Пусть пользователь решает.
Ответ №2:
Пример кода по мере необходимости:
class MdiWindow
{
static std::vector<std::wstring> s_filePaths;
bool openNewFile(const std::wstringamp; filePath) {
std::vector<std::wstring>::iterator iter = std::find(s_filePaths.begin(), s_filePaths.end(), filePath);
//already opened
if (iter != s_filePaths.end()) {
return true;
}
if (openFileSucceeded(filePath)) {
s_filePaths.push_back(filePath);
return true;
}
return false;
}
void closeFile(const std::wstringamp; filePath) {
s_filePaths.erase(s_filePaths.begin(), std::remove(s_filePaths.begin(), s_filePaths.end(), filePath));
}
}
Ответ №3:
Простого способа сделать это нет. Он имеет зависящие от платформы решения, запрашивая структуры данных ядра и просматривая структуры для каждого процесса, что непросто.
Но вы можете открывать файлы своим приложением в контейнере и проверять его значения при открытии нового файла.
Контейнер может быть членом класса, например :
QList<QString> openedFileNames;
Открытие файла :
if(!openedFileNames.contains(filename))
{
openedFileNames.append(filename);
QFile file( filename );
if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
QMessageBox::warning(this, tr("Error opening!"), tr("Could not open the file"));
...
}
Закрытие файла :
openedFileNames.removeAt(openedFileNames.indexOf(filename));
file.close();
Комментарии:
1. Спасибо вам, мистер
@Nejat
, за помощь, я решил эту проблему. пожалуйста, просмотрите мой код, чтобы узнать, хороший он или плохой. посмотрите на мой вопрос еще раз, который я обновил.
Ответ №4:
После первого открытия используйте:
http://doc.qt.io/qt-5/qlockfile.html
В вашем коде добавьте:
QFile file(fileDlg);
if (file.open(QFile::ReadOnly)) {
QTextStream in ( amp; file);
while (!file.atEnd()) {
cache = in .readAll();
}
} else {
//Something...
return;
}
file.close();
Комментарии:
1. Спасибо, но как использовать
QLockFile
class. Я сделалQLockFile lockFile(fileDlg); lockFile.lock();
.2. @LionKing к сожалению, я не могу заблокировать чтение. Я попробую еще раз завтра.