Просмотр сообщений
|
Страниц: 1 2 [3] 4 5 ... 12
|
31
|
Qt / Общие вопросы / Re: Почему вы выбрали Qt
|
: Март 09, 2015, 20:23
|
Что за "чрезмерная простота в ущерб качесту"?
Ну, например... Свойство ReadOnly присутствует в одном виджете, а в другом его нет, хотя конструктивно виджеты похожи - в оба можно вводить текст, и можно блокировать его изменение. Со временем эта возможность добавляется, но не сразу и не везде. Естественность кода от этого снижается, и по аналогии представить уровень ограничений Qt невозможно. То, что объективно нужно, того часто нет, а лишнее, для стабилизации слабого кода, попадается. Qt похожа на грибницу - растет естественно, но хаотично, без четкой концепции.
|
|
|
32
|
Разное / Говорилка / Re: Плюсолюбителям
|
: Март 09, 2015, 18:51
|
Нет никакой архитектуры языка. Все зависит от реализации менеджера памяти в стандартной библиотеке. В языке нет стандартных средств определить размер выделенного блока, да это и не нужно.
Я об этом и говорю. Абстрактный delete[] не знает, сколько памяти освобождается. Стандартная библиотека - надстройка, ей можно не пользоваться, пользоваться чем-то еще, а выделять память при помощи new[] и освобождать при помощи delete[], которые являются частью языка, можно в любой программе на С++. Количество элементов для обработки потом придется указать явно, так как средствами С++, если не ошибаюсь, нет возможности выяснить ни размер выделенного блока в байтах, ни количество элементов в массиве. Пример с дескрипторами - демонстрация, когда указатель хранит не адрес ячейки памяти, а что-то еще. Строго говоря, на абстрактной платформе, под которую может быть написан компилятор С++, указатель может иметь абсолютно любой формат, и может не предоставлять никакой информации о размере массива, на который он (явно или опосредованно) указывает. И delete[] - команда или последовательность команд ASSM - также не будет знать ничего о размере блока, которую выделяли на старте. И, действительно, delete[] это знать не обязательно.
|
|
|
33
|
Разное / Говорилка / Re: Плюсолюбителям
|
: Март 09, 2015, 18:03
|
2PinkPanther Мы хоть и в защищенном режиме, но в flat mode, поэтому указатель это именно адрес в виртуальном адресном пространстве, и дискрипторы здесь не причем.
В каком режиме идет работа - это уровень конкретной архитектуры машины. Здесь же идет речь об архитектуре языка, о причинах, почему функции требуют дополнительные данные. Ответ - архитектура может быть разной, в некоторых размер блока может стать физически неизвестным после его выделения. Хотя надстройки (siztof() и так далее), конкретные реализации библиотек С++ и предоставляют возможность это выяснить - в рамках любезности разработчиков.
|
|
|
34
|
Разное / Говорилка / Re: Плюсолюбителям
|
: Март 09, 2015, 17:36
|
Операторы new[] и delete[] получают размер необходимого буфера в байтах, а не количество элементов. Даже сохранив этот размер он не поможет определить число элементов. Мне кажется, что delete тоже не знает размер, а точнее, delete просто не нужно знать размер. Делаю это утверждение по памяти, могу ошибаться. Если брать PC, в защищенном режиме указатель хранит не адрес в памяти, а номер дескриптора (4 байта) в специальной таблице, которую использует процессор для адресации физической памяти. По нему освобождается сегмент данных (фактически, "черный ящик"). Физический адрес процессор сам берет из таблицы, поэтому на уровне C/C++ выход за границы массива никак не отслеживается, так как после выделения памяти для массивов простых типов при помощи new информация о количестве элементов не сохраняется. Зато процессор отслеживает границы, и, если начнете писать за пределы сегмента, программа прекратит работу по системному прерыванию. Увеличение адреса указателя определяет другой адрес - смещение от физического адреса сегмента (который хранит таблица). Когда вызывается delete, процессор находит нужный дескриптор по номеру и вычищает из таблицы. Данные о размере куска и правах доступа к нему содержатся в таблице, и к ним, как я понимаю, на уровне кода C/C++ никто не обращается (к тому же, процессоров много и все работают по-разному, попытка это делать сделает код непереносимым на другие платформы). Кстати, прибавляя к адресу, вы получите адреса следующих элементов. Но попробуйте отнять. Вы не получите физический адрес. Вы выскочите за пределы выделенной памяти с обратной стороны, в пустую область или в область другого блока, процессор это заметит, приложение поймает свисток судьи и прекратит работу.
|
|
|
35
|
Qt / Общие вопросы / Re: Почему вы выбрали Qt
|
: Март 09, 2015, 17:09
|
1) Широчайший диапазон применения, можно решить почти все задачи, не подключая другие библиотеки; 2) В отличии от C# код компилируется, и работает быстрее; 3) Кросс-платформенность (хотя сам пока компилировал только под Windows); 4) Простота. Даже чрезмерная простота, в ущерб качеству кода, но чем-то всегда приходится платить.
Баги в Qt встречаются, иногда серьезные, и думаю, что проблема в квалификации разработчиков. Но плюсы перевешивают.
|
|
|
36
|
Qt / Вопросы новичков / Re: query.next()
|
: Март 09, 2015, 16:51
|
По какой причине может не переходить ко второй записи?
А кто сказал, что query.next() == false? Код оформлен так, что ошибка может возникнуть в любом месте, а предсказать его работу сможет лишь телепат. Думаю, query.next() исправно выдает true, а ячейки не заполняются по другой причине. Лично мне в коде бросается в глаза две вещи: 1) Запрос к базе "SELECT *", а читается value(0). Отличный повод для сбоя - читаем нулевой столбец, как будто на 100% знаем, какой столбец в таблице нулевой. Если выбирается вся строка, делается запрос к ячейке по имени, value("имя_столбца"), а если нужен конкретный столбец, следует выбирать "SELECT имя_столбца" (и читать потом хоть по имени, хоть value(0)); 2) QStandartItem *item объявляется до цикла, а в цикле переменной присваиваются все новые и новые значения, которые потом отдаются наружу... А если указатель передается по ссылке, если функция работает не с содержимым указателя, а с самим указателем? Зачем вообще нужна эта переменная? Следует либо каждый раз объявлять новый указатель внутри тела цикла, QStandartItem *item = new ... , либо вызывать model->setItem(i, j, new QStandartItem(text));
|
|
|
38
|
Qt / Вопросы новичков / Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
|
: Март 08, 2015, 22:54
|
Спасибо, коллеги.
А вот вопрос: как разместить объект с нулевым пэрентом (чтобы не возникло проблем с его удалением при живом основном GUI) где-нибудь... ну, скажем, на вкладке таба, или в QMainWindow, просто по координатам? То есть создать виджет динамически, указать координаты, напичкать данными, показать-поработать, в нужный момент спрятать и удалить? Или это можно сделать только через добавление в лейаут?
Остальные вопросы топика вроде разрешились. На повестке дня сложная задача устранения утечки памяти при работе с QWebView.
|
|
|
39
|
Qt / Базы данных / [РЕШЕНО] SQLite - INSERT, UPDATE, транзакции
|
: Март 08, 2015, 16:32
|
Здравствуйте. Вопрос скорее не по Qt, а по SQLite, но так как любители Qt чаще всего используют SQLite, может быть, кто-то знает ответ.
Мое приложение при старте подгружает с сервера длинный список записей, в особом формате. Загруженный список парсится, данные вносятся в таблицу SQLite. Эта таблица необходима для работы приложения, без данных в ней оно бесполезно. Не самое изящное решение, но пока приложение работает именно так.
Ранее таблица SQLite чистилась, и все поля заполнялись по-новой. Вчера я включил транзакции (с целью ускорения), чистку таблицы выключил, а INSERT OR IGNORE поменял на UPDATE OR REPLACE. Сегодня в таблицу было добавлено 3 новых столбца, данных для которых в центральной базе нет, и которые были заполнены другим способом, раз и навсегда. При рестарте приложения команда UPDATE OR REPLACE прекрасно обновляет данные в таблице, но в новые столбцы вносит значения по умолчанию. Если я обновляю значения новых столбцов, приложение работает с ними до следующего перезапуска.
Вопрос: как оформить запрос SQLite, чтобы новые столбцы не теряли своих значений при UPDATE? При этом, если в таблице нет строки с данным ключом, нужно создать новую запись, заполнить данными, а новые столбцы заполнить значениями по умолчанию. Все это необходимо cделать средствами SQL, без дополнительной проверки, существует запись с нужным ключом в таблице, или нет.
PS Вроде решил, двумя запросами: Сначала INSERT OR IGNORE (добавляющий новые строки), и тут же, с теми же данными, UPDATE (без OR), редактирующий некоторые поля в старых строках.
|
|
|
42
|
Qt / Работа с сетью / Re: QWebView кэширование на диск
|
: Март 07, 2015, 10:42
|
Не могу сказать, что проблема решена кардинально, но подключение дискового кэша (к QNetworkAccessManager и QWebView) несколько улучшило ситуацию.
Еще немного улучшила ситуацию функция setObjectCacheCapacities(int minimal, int maximal, int overal) объекта QWebSettings. С помощью нее можно указать, какое количество ненужного барахла, загруженного ранее, можно позволить себе хранить в памяти.
В результате всех ухищрений приложение (параллельно работает 6 экземпляров) стало раздуваться не до 450 мегабайт за день работы, а до 200-250.
Если у кого-то есть идеи, как кардинально пресечь утечку памяти при работе QWebView, поделитесь пожалуйста.
|
|
|
43
|
Qt / Пользовательский интерфейс (GUI) / QListWidter, настройка цвета градиента подсветки активного элемента
|
: Март 06, 2015, 15:03
|
Здравствуйте. Не могу найти в таблице... Голубое (или серое, если виджет не в фокусе) градиентное выделение текущего элемента QListWidget, или элемента под курсором мыши - как с ним работать? Светлее вверху, темнее внизу, у меня выглядит объемной. Появляется когда виджет в фокусе, когда наведена мышь - менее яркие цвета, после щелчка темнеет. Хочу поменять цвет градиента, он есть в таблице палитры? Если есть, как он называется?
|
|
|
|
|