Просмотр сообщений
|
Страниц: 1 ... 49 50 [51] 52 53 ... 58
|
752
|
Программирование / С/C++ / Re: Как вынести реализацию метода из хидера в cpp (Шаблоны)
|
: Май 14, 2013, 19:30
|
Чтобы определение не включать в код, где используется шаблон, надо использовать ключевое слово export. Ерунда. Сильно. Не все компиляторы это поддерживают, это да. В mingw 4.7 и C++Builder 6.0 это получилось. Страуструп в своем специальном издании (2010 г.) указывал, что виндовые компиляторы Microsoft, к примеру, не поддерживают.
|
|
|
753
|
Qt / Уроки и статьи / Re: Статья: О способе работы с XML с использованием SAX-парсера
|
: Май 05, 2013, 17:55
|
За время, прошедшее с первой публикации, в предлагаемом подходе появились небольшие изменения. Во-первых, из интерфейсных методов исключен за ненадобностью CNode::isTextElement(). При этом обработчик конца элемента меняется совсем немного: bool CSaxHandler::endElement(const QString &namespaceURI, const QString &localName, const QString &qName){ if(nodeStack.isEmpty()) return false;
CNode* node=nodeStack.top();
// инициализация текстовых элементов if(node && textElement.trimmed().length()){ QXmlAttributes textAttr; textAttr.append(localName,"","",textElement); node->setRequisites(localName,textAttr); textElement.clear(); }
// элемент обработан nodeStack.pop(); return true; }
Во-вторых, уточнены некоторые особенности работы с текстовыми элементами, содержащими атрибуты (это было упущение), чему посвящена отдельная небольшая глава: Особенности реализации для текстовых элементов с атрибутамиТекстовые элементы в XML-документах могут содержать атрибуты, например: <?xml version="1.0"?> <CHAPTER cnumber="1"> <VERS vnumber="1">Содержание текстового элемента</VERS> </CHAPTER> В этом случае, элемент оформляется в представлении в виде отдельного узлового класса: class CVERS : public CNode { protected: virtual void setRequisites(const QString &name,const QXmlAttributes &attributes); virtual CNode* getNode(const QString &name); virtual bool writeNode(QXmlStreamWriter& writer,const QString& nsUri);
public: CVERS();
QString vnumber; QString VERS; // текстовый элемент }; Для текста элемента в объявлении предусматриваем отдельный реквизит VERS. Имя этого реквизита особого значения не имеет, Например, его можно было бы назвать text, но нет гарантии, что среди атрибутов в будущем не встретится такого имени. Поэтому, предпочтительнее для этого использовать имя элемента (тега). Реализация интерфейсных методов может быть такой: void CVERS::setRequisites(const QString &name,const QXmlAttributes &attributes){ // проверка отсутствия текстового реквизита if(attributes.value("VERS").isEmpty()){ vnumber=attributes.value("vnumber"); } else // присвоение текстового элемента VERS=attributes.value(name); } //----------------------------------------------------------------------
bool CVERS::writeNode(QXmlStreamWriter& writer,const QString& nsUri){ writer.writeStartElement(nsUri,nodeName);
writer.writeAttribute("vnumber", vnumber); writer.writeCharacters(VERS);
writer.writeEndElement(); return true; } Использовать метод QXmlStreamWriter::writeTextElement() в данном случае нельзя, поскольку этот метод формирует открывающий и закрывающий теги элемента. Поэтому для записи текста используется метод QXmlStreamWriter::writeCharacters(). Полный исправленный текст статьи и пример - во вложении.
|
|
|
755
|
Qt / Общие вопросы / [РЕШЕНО] QTextDocument: не высылается сигнал modificationChanged
|
: Май 03, 2013, 22:08
|
Коллеги, столкнулся с непонятным поведением QTextDocument. Задача тривиальная - индикация изменений в редакторе. Текст в редактор подгружается извне, и должен быть отмечен, как не измененный. Для этого использую QTextDocument::setModified, например: plainTextEdit->setPlainText(text); plainTextEdit->document()->setModified(false);
При этом должен быть два раза выслан сигнал QTextDocument::onScriptChanged(bool) - первый раз с аргументом true, второй раз - false. Так и происходит, если !text.isEmpty(). А если текст пустой, то только один раз - после setPlainText. Почему? Если это особенность, как обойти?
|
|
|
756
|
Программирование / С/C++ / Re: Как вынести реализацию метода из хидера в cpp (Шаблоны)
|
: Апрель 27, 2013, 22:46
|
Вопрос может и тупой, но...
Чтобы определение не включать в код, где используется шаблон, надо использовать ключевое слово export. Примерно так: Объявление в .h: template <typename T> class Array3 { template <class> friend class Array3;
private: T d[3];
public: Array3<T>(const T x, const T y, const T z); inline const T operator [](const int i) const; template <typename TT> inline Array3<T> operator *(Array3<TT> const &a); inline Array3<T> & operator =(const T &a); };
Определение в .cpp: export template <typename T> Array3<T>::Array3(const T x, const T y, const T z) { this->d[0] = x; this->d[1] = y; this->d[2] = z; } export template <typename T> const T Array3<T>::operator [](const int i) const { return this->d[i]; }
export template <typename T> template <typename TT> inline Array3<T> Array3<T>::operator *(Array3<TT> const &a) { return Array3<T>(this->d[0] * a[0], this->d[1] * a[1], this->d[2] * a[2]); }
export template <typename T> inline Array3<T> & Array3<T>::operator =(const T &a) { return (*this = Array3<T>(a, a, a)); }
|
|
|
757
|
Qt / Вопросы новичков / Re: Приложение System Tray only
|
: Апрель 14, 2013, 12:35
|
я бы сделал так: #include "mainwindow.h" #include <QApplication>
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w;
if(onlyTray) w.showTray(); else w.show(); return a.exec(); }
#include "ui_mainwindow.h"
class QSystemTrayIcon; class QAction; class QMenu;
class MainWindow : public QMainWindow, private Ui::MainWindow { Q_OBJECT
private: QSystemTrayIcon *trayIcon; QAction *quitAction; QMenu *trayIconMenu; public: explicit MainWindow(QWidget *parent = 0);
void showTray(); };
const bool onlyTray=true;
#include "mainwindow.h" #include <QSystemTrayIcon>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setupUi(this); }
void MainWindow::showTray(){ // создание иконки trayIconMenu = new QMenu(this); quitAction = new QAction(tr("Выход"), this); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); trayIconMenu->addAction(quitAction);
trayIcon = new QSystemTrayIcon(this); trayIcon->setContextMenu(trayIconMenu); trayIcon->setIcon(QIcon(":/blueflag.png")); trayIcon->setToolTip(this->windowTitle()); trayIcon->show(); }
|
|
|
758
|
Qt / Пользовательский интерфейс (GUI) / Re: Обработчики drag & drop для виджетов, сделанных в дизайнере
|
: Апрель 10, 2013, 16:36
|
2) mapTo - изящный вариант, предоставленный разработчиками Qt. Лучше ты не сделаешь Не очень-то это красиво, ну пусть : void MainWindow::dragMoveEvent(QDragEnterEvent *event){ QPoint dragCursor=mapToGlobal(event->pos()); QPoint topLeft=tabWidget->mapToGlobal(QPoint()); QRect table(topLeft,topLeft+QPoint(tabWidget->width(),tabWidget->height()));
if (event->mimeData()->hasUrls() && table.contains(dragCursor)) { event->acceptProposedAction(); } else { event->ignore(); } }
11.04.2013 поправил условие.
|
|
|
760
|
Qt / Пользовательский интерфейс (GUI) / [РЕШЕНО]Обработчики drag & drop для виджетов, сделанных в дизайнере
|
: Апрель 09, 2013, 13:45
|
Коллеги, помогите, пожалуста, по вопросам, связанным с drag&drop. Перетаскиваю файлы из проводника на один из виджетов главной формы программы. Форма сконструирована в дизайнере. Приемником файлов сделал главную форму (т.к. не знаю, как ответить на 1-й вопрос ниже): MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setupUi(this); setAcceptDrops(true); } Обработчики drag стандартные: void MainWindow::dragEnterEvent(QDragEnterEvent * event){ if (event->mimeData()->hasUrls()) event->acceptProposedAction(); else event->ignore(); } Разрешаю перетаскивание для ограниченной области (одного из виджетов tabWidget): void MainWindow::dragMoveEvent(QDragMoveEvent * event){ bool inside=event->answerRect().intersects(tabWidget->geometry()); if (event->mimeData()->hasUrls() && inside) event->acceptProposedAction(); else event->ignore(); } Вопросы следующие: 1) Можно ли перегрузить обработчики dragEnterEvent, dragMoveEvent, dropEvent для виджетов, сделанных в дизайнере, т.е. не создавая производного класса виджета? 2) В обработчике dragMoveEvent координаты курсора >answerRect(), как я понял, даются в системе координат принимающего виджета, а для главной формы отсчет по оси "y" начинается от верхнего края (т.е. от нижнего края заголовка формы). Координаты дочерних виджетов geometry() даются в системе координат centralWidget(), отличающиеся по оси "y" на высоту панели инструментов. Как лучше привести их к общей системе?
|
|
|
763
|
Qt / Общие вопросы / Re: QString value
|
: Март 29, 2013, 19:58
|
inline QString::QString(const QString &other) : d(other.d) { Q_ASSERT(&other != this); d->ref.ref(); } Собственно, ч.т.д. Реализация. Разработчик запретил такую фигню. И флаг ему.
|
|
|
764
|
Qt / Общие вопросы / Re: QString value
|
: Март 29, 2013, 19:45
|
На мой взгляд просто - вы вызываете конструктор объекта и передаёте ему ещё не созданный объект. Т.е. попытка обратиться к членам класса до его создания.
Давайте подумаем. В конструкции Type x=y выполняется копирующая инициализация объекта x значением y. Т.е. сначала создается объект x, а потом ему присваивается значение у. Таким образом, в приведенном примере производится инициализация объекта значением самого объекта. Не наказуемо. Для выполнения этой операции используется копирующий конструктор, он объявляется как Type(const Type&). В нашем случае, это QString(const QString & other). Может, туда посмотреть? Кстати, C++Builder это делает без ругани.
|
|
|
765
|
Qt / XML / Re: XML парсер
|
: Март 22, 2013, 11:18
|
А теперь представьте, что у вас не по 1 атрибуту в элементе, а по 100. И как все это будет работать?
|
|
|
|
|