Форум программистов, компьютерный форум CyberForum.ru

Вопрос - Ответ для новичков по Qt - C++ Qt

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 634, средняя оценка - 4.81
Чистый
Автор FAQ
 Аватар для Чистый
2574 / 1381 / 70
Регистрация: 08.09.2011
Сообщений: 3,706
Записей в блоге: 1
21.02.2012, 11:15     Вопрос - Ответ для новичков по Qt #1
В данной теме буду выкладывать готовые решения на вопросы новичков.
Обсуждение, замечание, критика и т.п. вещи по данной теме тут:
Основные вопросы, вызывающие сложности у новичков (обсуждение)
 Комментарий модератора 
Если у вас есть пример, который вы хотите добавить в этот список, то пишите мне в личку!


Итак прежде чем писать какие-либо решения дам несколько, на мой взгляд, полезных советов:
  1. В не зависимости от того какой ОС вы пользуетесь, держите исходный текст в формате UTF-8. Этим вы исключите будущие проблемы с кириллицей непосредственно в тексте исходного кода. Для этого в QtCreator зайдите: Инструменты - Параметры - Текстовый редактор, выбирайте закладку "Поведение" и там укажите кодировку файлов как "UTF-8".
  2. Путь к исходным файлам ваших проектов, а так же путь куда установлена QtSDK, не должны содержат пробелов и кириллицы. Этот совет поможет избежать "магических" ошибок при компиляции, когда код верен, а компиляция не проходит.
  3. Используйте Теневую сборку для своих проектов (Смотрите в свойствах проекта). Теневая сборка - это когда сборка проекта идет в отдельном каталоге (пут к нему так же не должен содержать пробелов и кириллицы ), это позволяет держать в чистоте каталог исходных кодов и избавит в будущем от проблем, если вы надумаете несколько конфигурация для одних исходников
  4. Я тут посмотрел на советы выше, перечитал их и дам еще один совет, забудьте про кириллицу в программировании .
Данные советы будут пополнятся как только в моей голове возникнет еще какой-нибудь совет или его подскажет кто-то. Исполнять в точности эти советы нет необходимости, но прислушаться к ним новичкам, думаю стоит.....

Теперь непосредственно вопросы:
  1. Кириллица в ваших приложениях
  2. CheckListBox
  3. Перевод приложений на другие языки
  4. Система плагинов для вашего приложения
  5. Система плагинов вариант 2
  6. Работаем с ресурсами
  7. Регулярные выражения и строки [черновик]
  8. Отображение программы с различной формой
  9. Функция определения операционной системы
  10. Qml - перемещение формы мышкой
  11. Qml - графические эффекты (эффекты изменения обьектов)
  12. Qml - создаем внешний элемент
  13. Qml - доступ к внешним элементам
  14. Модули Qt
  15. Работа с zip архивами в Qt (разархивация)
  16. QLabel. Размер текста относительно ширины QLabel.
  17. Qml. Обьединение Qml и виджетов Qt
  18. Нестандартная форма окна приложения [черновик]
  19. Установка OpenCV на linux. Использование библиотеки в Qt Creator.
  20. Выбор кодировки текста
  21. Циклы в отдельном потоке.
  22. Сборка MySql драйвера под Windows
  23. Работа с SQLite

    Вопросы не касающиеся программирования:
  24. Исправляем кириллицу при ошибках компиляции

    что бы не забыть вопросы помечаю тут:
  25. Tableview tablewidget model и т.п.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Чистый
Автор FAQ
 Аватар для Чистый
2574 / 1381 / 70
Регистрация: 08.09.2011
Сообщений: 3,706
Записей в блоге: 1
21.02.2012, 11:36  [ТС]     Вопрос - Ответ для новичков по Qt #2
Кириллица в ваших приложениях

Предположим у нас есть вот такая форма:

Вопрос - Ответ для новичков по Qt

Нам бы хотелось что бы форма содержала кириллицу, первое что приходит в голову это добавить в проект сл код:
C++
1
2
ui->lineEdit->setText("Тут мы пишем текст...");
ui->pushButton->setText("Закрыть");
Добавили, компилируем, получаем:

Вопрос - Ответ для новичков по Qt

согласитесь не красиво как-то, решается данная проблема сл способом: в функцию main (файл main.cpp) добавляем следующий код:
C++
1
2
3
QTextCodec *utfcodec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForTr(utfcodec);
QTextCodec::setCodecForCStrings(utfcodec);
Естественно UTF-8 вы можете заменить на CP-1251 или любую другую необходимую вам кодировку

Не забываем так же подключить заголовочный файл:
C++
1
#include <QTextCodec>
Компилируем, получаем:
Вопрос - Ответ для новичков по Qt

То что нам и хотелось, но если в будущем мы захотим наше приложение перевести на др языки, то надо еще немного подкорректировать код, т.е. весь текст который вы планируете переводить на др языки стоит обернуть функцией tr() было так:

C++
1
2
ui->lineEdit->setText("Тут мы пишем текст...");
ui->pushButton->setText("Закрыть");
стало так:
C++
1
2
ui->lineEdit->setText(tr("Тут мы пишем текст..."));
ui->pushButton->setText(tr("Закрыть"));
Этим вы только упростите себе в будущем жизнь

Вот в этом архиве проект который расписан в данном вопросе: Cyrillic.rar
Чистый
Автор FAQ
 Аватар для Чистый
2574 / 1381 / 70
Регистрация: 08.09.2011
Сообщений: 3,706
Записей в блоге: 1
21.02.2012, 12:07  [ТС]     Вопрос - Ответ для новичков по Qt #3
CheckListBox

В Qt нет столь замечательного виджета как CheckListBox, но не все так плохо как кажется, данный вопрос решается достаточно быстро и легко, для этого на форму добавляем виджет QListWidget. Теперь в конструктор формы с QListWidget добавим сл код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//формируем список содержимого ChekListBox;
QStringList lst;
lst <<tr("Красный")<<tr("Оранжевый")<<tr("Жёлтый")<<tr("Зелёный")<<tr("Голубой")<<tr("Синий")<<tr("Фиолетовый");
 
// добавим сформированный списко в ChekListBox
for (int i=0; i <lst.size(); i++)
{
    QListWidgetItem *items = new QListWidgetItem(ui->lstChekListBox);
   //указываем текст
    items->setText(lst.at(i));
   //Состояние флажка отмечен( Qt::Checked) или нет (Qt::Unchecked)
   items->setCheckState(Qt::Unchecked);
}
В результате получаем вот это:

Название: checklist_0.PNG
Просмотров: 16964

Размер: 9.3 Кб

Элементы очень близко расположены друг к другу, это можно поправить добавив после указанного выше кода строку:

C++
1
ui->lstChekListBox->setSpacing(2);
В результате получаем вот это:

Название: checklist_1.PNG
Просмотров: 16928

Размер: 9.6 Кб

что на мой взгляд немного удобнее

Архив с проектом: ChekListBox.rar
Чистый
Автор FAQ
 Аватар для Чистый
2574 / 1381 / 70
Регистрация: 08.09.2011
Сообщений: 3,706
Записей в блоге: 1
21.02.2012, 17:34  [ТС]     Вопрос - Ответ для новичков по Qt #4
Перевод приложений на другие языки

И вот вы написали свое первое приложение и вы осознали что научить "разговаривать" приложение на других языках было бы очень хорошо, для это в Qt есть все необходимое. Если у вас установлен QtSDK то вы в полной боевой готовности, если же нет, то для решения данного вопроса вам понадобится два приложения QtCreator и QtLinguist. Будем считать что эти два приложения у вас установлены. Для примера я сделал приложение вот с такой формой:

Вопрос - Ответ для новичков по Qt

Как видим все не по-нашенски, учим приложение великому и могучему, для этого в файл *.pro добавляем строчку

TRANSLATIONS += translateapp_ru_RU.ts
где:
translateapp - имя файла перевода с которым будем в дальнейшем работать
ru_RU - идентификатор языка, желательно указывать его в виде (ru_RU, en_EN, by_BY) и т.д.
ts - расширение файла перевода
Добавить эту строку можно в конец файла, роли это не играет...

Теперь делаем следующее в QtCreator-e идем по пути Инструменты - Внешние - Linguist - Обновить перевод (lupdate) на англ это Update Translations (lupdate)

в результате этой операции в QtCreator вы увидите сообщение подобно этому:

Вопрос - Ответ для новичков по Qt

а в каталоге где лежат исходники появится файлик translateapp_ru_RU.ts.Имейте ввиду что в файл попадут только те строки из исходников, которые вы обернули функцией tr(). Теперь открываем приложение QtLinguist и в нем открываем только что сформированный файл получим что то подобное:

Вопрос - Ответ для новичков по Qt

Думаю разобраться что, куда и как писать не составит труда, поэтом просто переводим приложение на необходимый язык, не забываем после перевода каждой строчки помечать ее переведенной, для это жмем кнопку на панели инструментов:Название: translta_3.PNG
Просмотров: 17601

Размер: 1.2 Кб

После того как перевели все строки сохраняем изменения в файле и делаем следующее: File- Release
В результате получаем файл: translateapp_ru_RU.qm находящийся рядом с файлом translateapp_ru_RU.ts. После перевода в QtLinguist файл с расширением qm можно получить и из QtCreator, для этого идем: Инструменты - Внешние - Linguist - Release Translations(lrelease)

Теперь давайте научим наше приложение использовать полученный файл, для этого скопируйте этот файл (*.qm) в каталог где у вас собирается приложение (Помните про теневую сборку?) после этого в функцию main добавим следующий код:

C++
1
2
3
QTranslator transApp;
transApp.load("translateapp_" + QLocale::system().name());
a.installTranslator(&transApp);
методу load передается имя файла перевода, который надо загрузить, QLocale::system().name() возвращает идентификатор языка, тот самый который мы указывали в имени файла (ru_RU, en_EN, by_BY), a - это экземпляр QApplications. Естественно вы можете расположить файлы перевода(*.qm) куда вам удобнее главное что бы вы могли передать их методу load

Не забываем подключить заголовочный файлы:

C++
1
2
#include <QTranslator>
#include <QLocale>
в результате после компиляции получим вот это:

Вопрос - Ответ для новичков по Qt

Есть небольшие проблемы с тем что ваше приложение при компиляции в debug может не видеть файлы qm не смотря на то что вы положили их куда положено, тут два решения или забить на эту проблему или методу load передавать абсолютный путь к файлу, если же вы компилируете в release то данной проблемы нет.

Архив с тестовым проектом: TranslateApp.rar
Maxim Prishchepa
Эксперт С++
 Аватар для Maxim Prishchepa
1917 / 1029 / 71
Регистрация: 29.03.2010
Сообщений: 3,160
22.02.2012, 12:30     Вопрос - Ответ для новичков по Qt #5
Система плагинов для вашего приложения
Вставлю и я свои 5 копеек, расскажу немножко о работе с плагинами (не теми, которые используются QtCreator-ом, а теми, которые dll-кой лежат рядышком с программой и динамически подгружаются в приложение).

Для начала, создадим интерфейс для нашего плагина:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef IMODULE_H
#define IMODULE_H
 
class IModule : public QObject {
//--------------------------------------------------------------------------------------------------
    public:     IModule(ICore * parent = NULL) : QObject(parent) {
                }
//--------------------------------------------------------------------------------------------------
    public:     virtual ~IModule() {
                }
//--------------------------------------------------------------------------------------------------
    public:     virtual bool start(QObject * parent) {
                    return true;
                }
//--------------------------------------------------------------------------------------------------
    public:        virtual QString getVersion()  const = 0;
    public:        virtual QString getName()     const = 0;
//--------------------------------------------------------------------------------------------------
};
 
Q_DECLARE_INTERFACE(IModule, "my.super.puper.domenName/MyCoolProject/IModule/1.0.0");
#endif//IMODULE_H
Здесь всё вроде бы понятно и просто: создаём интерфейс, с функцией "старт" - которая вернёт результат выполнения нашего модуля, и две функции, что бы понять, с чем же мы всё таки работаем, а именно: получение имени нашего плагина и получение версии плагина.

после объявления класса идёт объявление этого класса как интерфейса для плагина:
Q_DECLARE_INTERFACE(IModule, "my.super.puper.domenName/MyCoolProject/IModule/1.0.0");
Здесь мы передаём первым параметром имя нашего интерфейса, а вторым ставим уникальную строку, с помощью которой будет идентифицироваться наш интерфейс.

поехали дальше, реализовываем наш плагин. Для этого - создаём в солюшене проект, который на выходе нам даст динамическую библиотеку (как это делать, рассказывать не буду - звыняйте, лень...) и добавляем в неё класс (в данном случае это будет FTP сервер):

ftpServer.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef SX_FTP_SERVER_H
#define SX_FTP_SERVER_H
 
#include "IModule.h"
#include "IFtpServer.h"
//--------------------------------------------------------------------------------------------------
class sxFtpServer : public IModule, public IFtpServer{ Q_OBJECT Q_INTERFACES(IModule)
public:             sxFtpServer();
public:             ~sxFtpServer();
//--------------------------------------------------------------------------------------------------
public:     virtual bool start(ICore * parent);
//--------------------------------------------------------------------------------------------------
public:     QString getVersion() const;
public:     QString getName()    const;
//--------------------------------------------------------------------------------------------------
public:     void startFtpServer();
public:     void stopFtpServer();
public:     void restartFtpServer();
 
public:     void                                addSharedDirectory(const IFtpServer::SharedDirectory & sd);
public:     void                             removeSharedDirectory(const IFtpServer::SharedDirectory & sd);
public:     QList<IFtpServer::SharedDirectory>  sharedDirectoryList();
 
public:     virtual void setPort(int port);
public:     virtual int  getPort() const;
 
private:
 
};
//--------------------------------------------------------------------------------------------------
#endif // SX_FTP_SERVER_H
здесь думаю то же всё предельно ясно и просто (на интерфейс IFtpServer - не обращайте внимание, это я как всегда коммерческими тайнами разбрасываюсь).
Основное внимание уделяем тому, что сразу после объявления класса идёт два макроса:
Q_OBJECT Q_INTERFACES(IModule)
без запятых, точек с запятой и прочих разделителей, просто макросы! про Q_OBJECT - думаю всё понятно, а вот в Q_INTERFACES нужно передать имя интерфейса, который будет реализован в нашем плагине, в данном примере - это IModule.
Реализация проста и тривиальна, весь код приводить не буду, вот кусочек:
ftpServer.cpp
C++
1
2
3
4
5
6
7
8
#include "stdafx.h"
#include "sxftpserver.h"
 
Q_EXPORT_PLUGIN(sxFtpServer);
//--------------------------------------------------------------------------------------------------
sxFtpServer::sxFtpServer(){
...
}
Единственное, что отличает этот "плагинистый" срр файл, от обыкновенного, это то, что после includе-ов идёт макрос:
Q_EXPORT_PLUGIN(sxFtpServer);
которым мы говорим, что требуется экспортировать наш плагин и в качестве параметра передаём имя конкретной реализации нашего интерфейса, в данном случае это имя класса: sxFtpServer.

В принципе и всё - наш плагин готов к работе! компилируем и получаем на выходе dll-ку с плагином.

Теперь было бы логично использовать наш плагин. Для этого создаём ещё один проект, который из себя будет представлять консольное приложение. и в main файл или ещё куда добавляем что-то типа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void loadPlugins(const QDir &pluginsDir) {
    QStringList filter;
    filter << QString("*.%1").arg(Constant::pluginExtantion);
 
    foreach (QString fileName, pluginsDir.entryList(filter, QDir::Files)) {
        QPluginLoader loader(pluginsDir.absoluteFilePath(fileName), this);
        if (loader.isLoaded()) {
            qDebug() << QString("%1: %2 %3.").arg("Plugin file").arg(fileName).arg(tr("is already loaded"));
            continue;
        }
 
        if (loader.load() == false) {
            qDebug() << QString("%1 %2\n%3: %4")
                .arg(tr("Can't load a plugin"))
                .arg(fileName).arg(tr("error"))
                .arg(loader.errorString());
        } else {
            QObject * obj = loader.instance();
            if (IModule * plugin = qobject_cast<IModule *>(obj)) {
                m_modules.insert(plugin->getName(), plugin);                       
                qDebug() << QString("%1: %2 %3")
                    .arg(tr("Load plugin file"))
                    .arg(fileName)
                    .arg(plugin->getVersion());
 
                plugin->start(this);//TODO:
            }
        }
    }
}
из Main-а или ещё откуда небудь вызываем нашу волшебную функцию и получаем проект, который будет загружать плагин и вызывать его start функцию.

В общем то и всё... для пущей важности добавлю наверное скриншот:
Вопрос - Ответ для новичков по Qt

Да и последнее и очень важное: проект плагина и программы которая его вызывает должн, нет да же не так: ДОЛЖНЫ быть скомпилированы в одной конфигурации (либо оба в Debug-e либо оба в Release) иначе - работать не будет.

Собственно и всё, спасибо за внимание.
Критика и спасибки - приветствуются

если ругаеться на макрос
C++
1
Q_EXPORT_PLUGIN
подключите:
C++
1
#include <QtCore>
ЗЫ: Вспомнил ещё один момент - в интерфейсе плагина, мы декларируем его уникальный идентификатор, если плагин будет скомпилирован с одним идентификатором, а программа, которая будет вызывать этот плагин - с другим, то логично предположить, что плагин загрузиться не сможет.
Чистый
Автор FAQ
 Аватар для Чистый
2574 / 1381 / 70
Регистрация: 08.09.2011
Сообщений: 3,706
Записей в блоге: 1
27.02.2012, 14:57  [ТС]     Вопрос - Ответ для новичков по Qt #6
Работаем с файлом ресурсов в QtCreator

Большинство приложений содержит в себе различного рода "дополнительны материал" в виде картинок звуков и т.п. Зачастую этот материал "вшит" в само приложение, хотя не исключаю и того что данный материал может лежать где то в директории приложения. Сейчас и разберем как "вшить" в свое приложение этот самый материал, и самое главное как им пользоваться в коде...

Для начала добавить в свой проект файл ресурсов Qt, для этого на проекте щёлкаем правой кнопкой мыши и выбираем пункт: "Добавить новый...":
Вопрос - Ответ для новичков по Qt

в появившемся мастере выбираем Qt и файл ресурсов Qt:
Вопрос - Ответ для новичков по Qt

затем указываем расположение и имя файла:
расположение лучше всего указывать корень каталога проекта...
Вопрос - Ответ для новичков по Qt

Жмём далее, указываем в какой проект добавить новый файл и завершаем мастер нажатием кнопки "Завершить":
Вопрос - Ответ для новичков по Qt

В результате в проекте появится файл с расширением qrc, данный файл автоматически будет добавлен в pro файл проекта, поэтому имейте ввиду что если вы добавили ранее созданный файл ресурсов, то его надо подключить в файле проекта:
RESOURCES = file_name.qrc
Теперь откроем только что добавленный файл:
Вопрос - Ответ для новичков по Qt

Как видим он пустой, прежде чем добавлять файлы, скопируйте их в каталог в котором расположен ваш проект, при этом файлы эти могу быть катализированы как вам угодно, например картинки вы можете положить в папку img, звуки в sounds и т.д. после того как все необходимое скопировали давайте добавим файлы в файл ресурсов. Для этого жмем кнопку "Добавить" и выбираем пункт "Добавить префикс":
Вопрос - Ответ для новичков по Qt

префикс лучше всего выставлять как "/" дабы избежать длинных путей при работе с ресурсами в коде.
После того как добавили префикс, добавьте необходимые файлы, выбрав пункт "Добавить файлы", добавлять можно сразу выделив n-e количество файлов, в результате добавления у вас получится что то подобное:
Вопрос - Ответ для новичков по Qt

Заметьте что в файл ресурсов указывается относительный путь к добавленному файлу, именно с ним вы и будете работать в дальнейшем, так же есть возможность указать "Псевдоним" файлу, это дает возможность обращаться к файлу указав только "Псевдоним", например: вы добавили файл "/img/log.png" если ему указать "Псевдоним" например "logo" то из кода можно обращаться к файлу по псевдониму. После всех внесенных файлов сохраните файл ресурсов (Ctrl + S) и приступим к работе с добавленными файлами.

Например поместим на кнопку иконку ранее добавленную в файл ресурсов, для этого переходим в сво-ва кнопку, ищем свойство "icon" открываем окно добавления ресурса:
Вопрос - Ответ для новичков по Qt

в левой части окна выбирайте подкаталог где лежит ресурс (если он есть) справа будет отображаться ресурсы:
Вопрос - Ответ для новичков по Qt

Если ресурсу задан "Псевдоним" то ресурс будет находится в <resource root>, хотя физически он будет там куда вы его положили. В правой части выбираем необходимое изображение и жмем Ок. Таким образом добавляются ресурсы с помощью GUI, через код это делается так:
например добавляем картинку в Label...
C++
1
 ui->lblImg->setPixmap(QPixmap(":/img/logo.png"));
а так если был указа "Псевдоним"
C++
1
 ui->lblImg->setPixmap(QPixmap(":/logo"));
Все ресурсы хранятся в памяти в виде дерева объектов, если вам необходимо пройтись по всему дереву, то для этого можно использовать QDir инициализированный строкой ":/".

Если у вас есть двоичный файл ресурсов (расширение файла rcc), то его необходимо зарегистрировать в приложении:
C++
1
QResource::registerResource("path_to_file.rcc");
Если же файл ресурсов находится в статической библиотеке и необходимо им воспользоваться, то для его необходимо инициализировать с помощью макроса:
C++
1
 Q_INIT_RESOURCE(file_res);
где file_res - это базовое имя файла ресурсов в стат библиотеке, после того как ресурсы из этой библиотеки вам не нужны, их надо выгрузить из приложения:
C++
1
Q_CLEANUP_RESOURCE(file_res)
Ну вот на этом наверно и все про ресурсы, архив с тестовым проектом:QtRes.rar
Чистый
Автор FAQ
 Аватар для Чистый
2574 / 1381 / 70
Регистрация: 08.09.2011
Сообщений: 3,706
Записей в блоге: 1
16.03.2012, 11:56  [ТС]     Вопрос - Ответ для новичков по Qt #7
Регулярные выражения и строки черновой вариант будет даписан и доработан!

Регулярные выражения достаточно популярный метод поиска части строки(текста) не зависимо от сложности условий поиска. В Qt за регулярные выражения отвечает класс QRegExp, он нормально работает с Unicode а значит регулярные выражения могут содержать кириллицу.

Регулярные выражения в Qt состоят из 3 компонентов:
  1. Символы и их классы
  2. Квалификатор арности (кол-во совпадений подстроки поиска)
  3. Спец символы привязки

Символы и их классы
Тут все достаточно просто символы и это обычное вхождения строки т.е. "search", "поиск" и т.п. т.е. строка это и есть своеобразное регулярное выражение. Теперь немного про классы. Классы символов задаются в квадратных скобках [] например:
Дата рождения: 01.01.198[1234567890]
будет искать строки вида:
Дата рождения: 01.01.1980
Дата рождения: 01.01.1980
Дата рождения: 01.01.1981
Дата рождения: 01.01.1982
.....
Дата рождения: 01.01.1989
данное регулярное выражение можно сократить:
Дата рождения: 01.01.198[0-9]
тут используется дефис как способ задать интервал значений, результат работы этого регулярного выражения будет такой же как и тот что был показан выше.
В квадратных скобка можно указывать и др символы будь-то цифры, буквы или вовсе спец символы:
[0-9]
[A-Z]
[a-z]
[а-я]
и т.д. и т.п.
но данные выражения буду искать только один символ, для поиска всего выражения надо использовать Квалификаторы арности или условные обозначения. Относительно полный список представлен ниже:

СимволыОписаниеПример
. (точка)Любой символст.к
$Должен быть конец строкиКонец.$ Проверка
[]Любой символ из указаных в скобках[12345]
-Диапазон сомволов [A-Z0-9a-z]
^Все кроме перечисленного 
*Символ должне встретиться несколько раз или не встретится вообщест*к
+Символ должен встретится минимум один разКар+сон
?Символ должен встретится один раз или не встретится вообщеКар?сон
{i}Символ должен встретится i разДлинноше{3}
{i,}Возможно минимум i совпаденийДлинноше{3,}
{,j}Возможно совпадение до j разДлинноше{,3}
{i,j}Возможно совпадение от i до j разДлинноше{1,3}
|"оператор" ИЛИ ищет или одно условии или другое[0-3]|[7-9]
( )Ищет и сохраняет найденые выражения([0-3]|[7-9]) 99
\dЛюбое число 
\DВсе кроме чисел 
\sЛюбой тип пробела 
\SВсе кроме пробелов 
\wЛюбая буква, цифра или знак подчеркивани 
\WВсе кроме букв 
\AНачало строки 
\bЦелое слово 
\BНе слово 
\zКонец строки, совпадает с символом конца строки или символом перевода каретки  
\ZКонец строки, совпадает только с концом строки 

Теперь немного пояснений:
символ ^ работает только в том случае, если он стоит в начала выражения т.е. в этом выражении:
[^orn]
он действует как отрицание, т.е. все кроме o, r и n, а вот в этом:
[or^n]
он никак не действует, т.е. тут он просто один из символов на равне с o, r или n. Помните об этом

Дабы не гадать как будет вести ваше регулярное выражение в коде его предварительно можно проверить, благо об этом позаботились как создатели Qt так и сообщество Qt разработчиков, вот ссылки на два приложения которые помогут вам проверить ваше регулярное выражение на правильность:
  1. QRegExp Planner 1.0
  2. regexp лежит тут: QtSDK/Examples/4.7/tools/regexp/
Чистый
Автор FAQ
 Аватар для Чистый
2574 / 1381 / 70
Регистрация: 08.09.2011
Сообщений: 3,706
Записей в блоге: 1
21.03.2012, 11:36  [ТС]     Вопрос - Ответ для новичков по Qt #8
Исправляем кириллицу при ошибках компиляции

Установив QtSDK и приступив к работе, при первой же ошибка, если таковая будет, вы обнаружите неприятный баг, компилятор выводя сообщения об ошибках на русском языке, отображает их мягко сказать не корректно, выглядит это так:
Название: Безымянный.png
Просмотров: 17187

Размер: 6.2 Кб

Проблема проявляется только при использовании компилятора от VS (насколько мне известно, хотя могу и ошибаться), так как используется кодировка DOS(866). Данная ошибка как минимум затрудняет выявления ошибок в в коде программы. Причиной тому файл jom.exe. Для исправления достаточно просто заменить этот файл на исправленный, после чего проблема уйдет.

Итак оригинальный файл jom.exe находится тут:
QtSDK/QtCreator/bin
где: QtSDK - путь куда вы установили QtSDK

Делаем его резервную копию, после чего качаем вот этот файл:
jom.zip
Распаковываем на место старого файла и соглашаемся на замену.
После чего можно проверить исправилась проблема или нет, откомпилировав простой проект с заведомо известной ошибкой и убедиться что с кириллицей теперь все нормально!

Tут с завидной регулярностью выкладывают обновления для этого файла: jom.exe update попробуйте может там нет уже этой проблемы, я пока не пробовал

На сим спасибо за внимание
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
08.08.2012, 15:38     Вопрос - Ответ для новичков по Qt #9
Отображение программы с различной формой
Долого с этим бился. Упрощю задачу кому потребуется изменить форму приложения.

Будем использовать функцию setMask(). Она спрячет нужные участки программы.
Участки программы для отображения зададим в QPolygon.

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    QPolygon pol;
 
    // Установка точек в QPolygon
    pol << QPoint(3, 110);
 
    int j = 40;
    for(int i = 20; i<j; i++)
    {
        qreal fAngle = 2*3.14 * i/j;
        qreal x = 100 + cos(fAngle) * 100;
        qreal y = 100 + sin(fAngle) * 100;
        pol << QPoint(x,y);
    }
 
    j = 40;
    for(int i = 20; i<j; i++)
    {
        qreal fAngle = 2*3.14 * i/j;
        qreal x = 300 + cos(fAngle) * 100;
        qreal y = 100 + sin(fAngle) * 100;
        pol << QPoint(x,y);
    }
 
    pol << QPoint(400, 115);
 
    pol << QPoint(200,400);
 
    this->setMask(QRegion(pol)); // Отображаем выбранный участок остальное скрываем
После этого отключаем обводку программы

C++ (Qt)
1
this->setWindowFlags(Qt::CustomizeWindowHint);  // Отключаем обводку
Немного подкрасим и добавим кнопку:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
    // Подкрасим фон
    // так вставляем картинку
    QPalette pal;
    pal.setBrush(QPalette::Background,QBrush(QPixmap(":/picture/fon"))); // Картинка из файла ресурсов
    this->setPalette(pal);
 
    // Добавим кнопку для отключения программы
    QPushButton *quit = new QPushButton("Close", this);
    quit->move(150,200);
    connect(quit,SIGNAL(clicked()),this,SLOT(close()));

Готовая функция которая закруглит углы программы с нужным радиусом:
Готовая функция которая закруглит углы программы с нужным радиусом:

Применяется просто:
C++ (Qt)
1
setRoundedCorners(20,20,20,20); // Вызываем функцию которая закруглит углы
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Функция закругляет углы MainWindow
void setRoundedCorners(int radius_tl, int radius_tr, int radius_bl, int radius_br)
{
    QRegion region(0, 0, width(), height(), QRegion::Rectangle);
 
    // top left
    QRegion round (0, 0, 2*radius_tl, 2*radius_tl, QRegion::Ellipse);
    QRegion corner(0, 0, radius_tl, radius_tl, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));
 
    // top right
    round = QRegion(width()-2*radius_tr, 0, 2*radius_tr, 2*radius_tr, QRegion::Ellipse);
    corner = QRegion(width()-radius_tr, 0, radius_tr, radius_tr, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));
 
    // bottom right
    round = QRegion(width()-2*radius_br, height()-2*radius_br, 2*radius_br, 2*radius_br, QRegion::Ellipse);
    corner = QRegion(width()-radius_br, height()-radius_br, radius_br, radius_br, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));
 
    // bottom left
    round = QRegion(0, height()-2*radius_bl, 2*radius_bl, 2*radius_bl, QRegion::Ellipse);
    corner = QRegion(0, height()-radius_bl, radius_bl, radius_bl, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));
 
    setMask(region);
}


Удачи!
Миниатюры
Вопрос - Ответ для новичков по Qt   Вопрос - Ответ для новичков по Qt  
Вложения
Тип файла: 7z Mask.7z (69.5 Кб, 110 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
09.08.2012, 01:07     Вопрос - Ответ для новичков по Qt #10
Функция определения операционной системы

Функция определяет ОС и возвращает QString с информацией о ней.

Для функции добавте:
C++ (Qt)
1
#include <sys/utsname.h>
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Определение операционной системы
QString osVersion()
{
    static QString osVersion;
    if(osVersion.isEmpty())
    {
#if defined(Q_OS_MAC)
        switch(QSysInfo::MacintoshVersion)
        {
            case QSysInfo::MV_LEOPARD:
                osVersion = QLatin1String("MacOS 10.5(Leopard)");
                break;
            case QSysInfo::MV_TIGER:
                osVersion = QLatin1String("MacOS 10.4(Tiger)");
                break;
            case QSysInfo::MV_PANTHER:
                osVersion = QLatin1String("MacOS 10.3(Panther)");
                break;
            case QSysInfo::MV_JAGUAR:
                osVersion = QLatin1String("MacOS 10.2(Jaguar)");
                break;
            case QSysInfo::MV_PUMA:
                osVersion = QLatin1String("MacOS 10.1(Puma)");
                break;
            case QSysInfo::MV_CHEETAH:
                osVersion = QLatin1String("MacOS 10.0(Cheetah)");
                break;
            case QSysInfo::MV_9:
                osVersion = QLatin1String("MacOS 9");
                break;
 
            case QSysInfo::MV_Unknown:
            default:
                osVersion = QLatin1String("MacOS(unknown)");
                break;
        }
#elif defined(Q_OS_UNIX)
        utsname buf;
        if(uname(&buf) != -1)
        {
            osVersion.append(buf.release).append(QLatin1Char(' '));
            osVersion.append(buf.sysname).append(QLatin1Char(' '));
            osVersion.append(buf.machine).append(QLatin1Char(' '));
            osVersion.append(QLatin1String(" (")).append(buf.machine).append(QLatin1Char(')'));
        }
        else
        {
            osVersion = QLatin1String("Linux/Unix(unknown)");
        }
#elif defined(Q_WS_WIN) || defined(Q_OS_CYGWIN)
        switch(QSysInfo::WindowsVersion)
        {
            case QSysInfo::WV_CE_6:
                osVersion = QLatin1String("Windows CE 6.x");
                break;
            case QSysInfo::WV_CE_5:
                osVersion = QLatin1String("Windows CE 5.x");
                break;
            case QSysInfo::WV_CENET:
                osVersion = QLatin1String("Windows CE .NET");
                break;
            case QSysInfo::WV_CE:
                osVersion = QLatin1String("Windows CE");
                break;
 
            case QSysInfo::WV_VISTA:
                osVersion = QLatin1String("Windows Vista");
                break;
            case QSysInfo::WV_2003:
                osVersion = QLatin1String("Windows Server 2003");
                break;
            case QSysInfo::WV_XP:
                osVersion = QLatin1String("Windows XP");
                break;
            case QSysInfo::WV_2000:
                osVersion = QLatin1String("Windows 2000");
                break;
            case QSysInfo::WV_NT:
                osVersion = QLatin1String("Windows NT");
                break;
 
            case QSysInfo::WV_Me:
                osVersion = QLatin1String("Windows Me");
                break;
            case QSysInfo::WV_98:
                osVersion = QLatin1String("Windows 98");
                break;
            case QSysInfo::WV_95:
                osVersion = QLatin1String("Windows 95");
                break;
            case QSysInfo::WV_32s:
                osVersion = QLatin1String("Windows 3.1 with Win32s");
                break;
 
            default:
                osVersion = QLatin1String("Windows(unknown)");
                break;
        }
 
        if(QSysInfo::WindowsVersion & QSysInfo::WV_CE_based)
            osVersion.append(QLatin1String(" (CE-based)"));
        else if(QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
            osVersion.append(QLatin1String(" (NT-based)"));
        else if(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)
            osVersion.append(QLatin1String(" (MS-DOS-based)"));
#else
        return QLatin1String("Unknown");
#endif
    }
 
    return osVersion;
}
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
09.08.2012, 02:11     Вопрос - Ответ для новичков по Qt #11
Qml - перемещение формы мышкой

Итак, qml готов:

*.h
C++ (Qt)
1
2
3
4
5
6
#include <QtDeclarative/QDeclarativeContext>
#include <QtDeclarative/QDeclarativeView>
#include <QGraphicsObject>
....
    QDeclarativeView *ui;               // Qml
    QObject *Root;                      // Корневой элемент QML модели
*.cpp
C++ (Qt)
1
2
3
4
5
    //Включаем наш QML
    ui = new QDeclarativeView();
    ui->setSource(QUrl("qrc:/mainQml.qml")); // Что бы сработало добовляем qml файл в файл ресурсов 
 
    this->setCentralWidget(ui);

Соединяем C++ и QML, делая видимым функции С++ через элемент Qt_fun (Qt_fun - мой выбор, писать можно что угодно):
*.cpp
C++ (Qt)
1
2
3
4
    //Находим корневой элемент
    Root = ui->rootObject();
    //Соединяем C++ и QML, делая видимым функции С++ через элемент Qt_fun
    ui->rootContext()->setContextProperty("Qt_fun", this);
Добавим функции которые будет видеть qml
*.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
 
    Q_INVOKABLE void move_window();    // Функция C++ вызываемая из QML премещающие окно
    Q_INVOKABLE void cursor_up();          // Функция C++ вызываемая из QML изменяющие вид курсора
    Q_INVOKABLE void cursor_down();      // Функция C++ вызываемая из QML возвращающия вид курсора в первоначальное состояние
...

Добавим две переменные:
*.h
C++ (Qt)
1
2
    int save_x;                         // Сохраняет X положение MainWindow на экране
    int save_y;                         // Сохраняет Y положение MainWindow на экране
Реализация функций:
*.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Функция C++ вызываемая из QML изменяющие курсор при отжатии
void MainWindow::cursor_down()
{
    this->setCursor(QCursor(Qt::ArrowCursor));  // Востанавливает нормальный вид курсора
}
 
//Функция C++ вызываемая из QML изменяющие курсор при нажатии
void MainWindow::cursor_up()
{
    this->setCursor(QCursor(Qt::SizeAllCursor));    // Изменяет вид курсора при клике на обьект
 
    save_x = QCursor::pos().x() - this->pos().x();  // Отмечает где вы клацнули мышкой на форме x позицию
    save_y = QCursor::pos().y() - this->pos().y();  // Отмечает где вы клацнули мышкой на форме y позицию
}
 
//Функция C++ вызываемая из QML премещающие окно
void MainWindow::move_window()
{
    // Перемещаем окно
    this->move(QCursor::pos().x()-save_x , QCursor::pos().y() - save_y);
}
И последнее добавим функции в qml:
mainQml.qml
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Rectangle {
    width: 300 // Ширина
    height: 300 // Высота
 
    // Цвет - градиетнт установка
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#4c0000"}
        GradientStop { position: 0.5; color: "#df8c73"}
        GradientStop { position: 1.0; color: "#4c0000"}
    }
 
    // Обработка событий мышки
    MouseArea {
        id: mainAllMouse   // Имя MouseArea для qml
        anchors.fill: parent   // parent
        onClicked: Qt.LeftButton  // Если нажата левая кнопка мыши
        onPositionChanged: Qt_fun.move_window();  // Срабатывает функция при изменении положения зажатой левой кнопки мышки
        onEntered: Qt_fun.cursor_up() // Вызывает функцию при нажатии кнопки
        onExited: Qt_fun.cursor_down() // Вызывает функцию при отжатии кнопки
    }
}
Миниатюры
Вопрос - Ответ для новичков по Qt  
Вложения
Тип файла: 7z MoveWindow.7z (4.3 Кб, 112 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
09.08.2012, 17:12     Вопрос - Ответ для новичков по Qt #12
Qml - графические эффекты (эффекты изменения обьектов)

В qml есть встроенные специальные эффекты для изменения различных изменений обьекта.

Допустим у нас есть Rectangle :

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Прямоугольник
Rectangle {
    id: main        // Имя прямоугольника для qml
    width: 200      // Ширина прямоугольника
    height: 100     // Высота прямоугольника
 
    radius: 10      // Радиус углов прямоугольника
    smooth: true    // Заглаживает края
 
    x: -180         // Положение прямоугольника на форме
    color: "red"   // Цвет прямоугольника
 
    // Обработка событий мыши
    MouseArea {
        anchors.fill: parent            // Родитель
        onClicked: console.log("console")   // Срабатывает при клике
    }
}
Вот что получилось:

Вопрос - Ответ для новичков по Qt
















Добавим позиции формы ( x позицию и позицию цвета ) прямоугольника:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Прямоугольник
Rectangle {
    id: main        // Имя прямоугольника для qml
    width: 200      // Ширина прямоугольника
    height: 100     // Высота прямоугольника
 
    radius: 10      // Радиус углов прямоугольника
    smooth: true    // Заглаживает края
 
    state: "normal"
 
    states: [
        State {
            name: "normal"
            PropertyChanges {target: main; x: -180; /* положение прямоугольника */ color: "red" /* цвет прямоугольника */}
        },
        State {
            name: "shift"
            PropertyChanges {target: main; x: 180; /* положение прямоугольника */ color: "green" /* цвет прямоугольника */}
        }
    ]
 
    // Обработка событий мыши
    MouseArea {
        anchors.fill: parent            // Родитель
        // Срабатывает при клике
        onClicked:
        {
            // Изменения позиции формы при клике
            if(main.state == "normal")
                main.state = "shift"
            else
                main.state = "normal"
        }
    }
}
( Обратие внимание на знак ; )

При клике на прямоугольнике позиция и цвет меняется:

Вопрос - Ответ для новичков по Qt
















А теперь добавим эффекты изменения позиции формы ( x позицию и позицию цвета ) прямоугольника:

Есть два варианта (насколько я знаю):

Первый вариант:
C++ (Qt)
1
2
3
4
    transitions: Transition {
        PropertyAnimation { properties: "x"; duration: 500; /* Время выполнения */ easing.type: Easing.InOutSine /* Эффект */}
        PropertyAnimation { properties: "color"; duration: 500; /* Время выполнения */ easing.type: Easing.InOutSine /* Эффект */}
    }
Второй вариант:
C++ (Qt)
1
2
    Behavior on x { PropertyAnimation {duration: 500; /* Время выполнения */ easing.type: Easing.InOutBack /* Эффект */} }
    Behavior on color { PropertyAnimation {duration: 500; /* Время выполнения */ easing.type: Easing.InOutBack /* Эффект */} }
Разница в том что второй реагирует на все изменения значений color или х, а первый только на изменения state

Вот пример:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    // Обработка событий мыши
    MouseArea {
        anchors.fill: parent            // Родитель
        // Срабатывает при клике
        onClicked:
        {
            // Первый и вторй вариат работают
            // Изменения позиции формы при клике
            if(main.state == "normal")
                main.state = "shift"
            else
                main.state = "normal"
 
            // Работает только вторй вариант
            // Изменения позиции формы при клике
            if(main.x == -180)
            {
                main.color = "green"
                main.x = 180
            }
            else
            {
                main.color = "red"
                main.x = -180
            }
 
        }
    }
Ну пока все. Удачи!

Программа прилагается:
Вложения
Тип файла: 7z Transition.7z (4.1 Кб, 89 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
11.08.2012, 10:45     Вопрос - Ответ для новичков по Qt #13
Qml - создаем внешний элемент

Допустим нам нужна кнопка которая будет повторяться на форме. Чтобы не создаветь ее много раз зделаем ее отдельным элиментом.

Приступим:

У нас имеется форма mainQml:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
Rectangle {
    width: 300
    height: 300
 
    // Цвет - градиент
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#4c0000"}
        GradientStop { position: 0.5; color: "#df8c73"}
        GradientStop { position: 1.0; color: "#4c0000"}
    }
}
Вопрос - Ответ для новичков по Qt


























Создадим новую форму в отдельном файле qml
(Он обязательно должен иметь названия которое начинается с заглавной буквы):

Жмем: Ctrl-N :
Вопрос - Ответ для новичков по Qt
Вопрос - Ответ для новичков по Qt



















Вопрос - Ответ для новичков по Qt
Вопрос - Ответ для новичков по Qt



















Назовет файл qml - Push.

Добавим его в файл ресусов:

Вопрос - Ответ для новичков по Qt




















Pash.qml имеет такой вид:
C++ (Qt)
1
2
3
4
5
6
7
// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
import QtQuick 1.1
 
Rectangle {
    width: 100
    height: 62
}
Преукрасим его:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Rectangle {
    id: push
 
    width: 150
    height: 40
 
    y: 130
    // По центру
    anchors.horizontalCenter: parent.horizontalCenter
 
    // Цвет
    color: "green"
 
    // Радиус углов
    radius: 20
 
    // Сглаживание включено
    smooth: true
 
    Text {
        id: textPush
        text: qsTr("Настройки")
 
        // По центру
        anchors.verticalCenter: push.verticalCenter
        anchors.horizontalCenter: push.horizontalCenter
    }
 
    scale: pushMouse.pressed? 0.8 : 1.0 // При нажатии будет уменьшатся
 
    MouseArea {
        id: pushMouse
        anchors.fill: parent
        acceptedButtons: Qt.LeftButton | Qt.RightButton // Левая и правая кнопка мыши
    }
}
И добавим его в mainQml:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Rectangle {
    id: mainQml
    width: 300
    height: 300
 
    // Цвет - градиент
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#4c0000"}
        GradientStop { position: 0.5; color: "#df8c73"}
        GradientStop { position: 1.0; color: "#4c0000"}
    }
 
    Push{}
}
Вот что получилось:
Вопрос - Ответ для новичков по Qt
























В Push можно указывать параметры насторек (они будут замещать старые параметры):
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Rectangle {
    id: mainQml
    width: 300
    height: 300
 
    // Цвет - градиент
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#4c0000"}
        GradientStop { position: 0.5; color: "#df8c73"}
        GradientStop { position: 1.0; color: "#4c0000"}
    }
 
    Push{
        id: pushOne
        color: "red"
 
        y: 50
    }
 
    Push{
        id: pushTwo
        color: "green"
 
        y: pushOne.y + pushTwo.height + 10
    }
 
    Push{
        id: pushThree
        color: "#ffffff"
 
        y: pushTwo.y + pushThree.height + 10
    }
 
    Push{
        id: pushFour
        color: "yellow"
 
        y: pushThree.y + pushFour.height + 10
    }
}

Ну вот и все:
Вопрос - Ответ для новичков по Qt


























Программа:
Вложения
Тип файла: zip Push.zip (3.3 Кб, 77 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
11.08.2012, 11:37     Вопрос - Ответ для новичков по Qt #14
Qml - доступ к внешним элиментам

Создавши внешний элимент нам может потребоватся изменить параметры клика по ним и доступ к элиментам (наприме изменить текст на кнопке). Вот как это делал я:

Итак, у нас имеется mainQml.qml и Push.qml - внешний элимент:

mainQml:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import QtQuick 1.1
 
Rectangle {
    id: mainQml
    width: 300
    height: 300
 
    // Цвет - градиент
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#4c0000"}
        GradientStop { position: 0.5; color: "#df8c73"}
        GradientStop { position: 1.0; color: "#4c0000"}
    }
 
    Push{}
}
Push:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import QtQuick 1.1
 
Rectangle {
    id: push
 
    width: 150
    height: 40
 
    y: 130
    // По центру
    anchors.horizontalCenter: parent.horizontalCenter
 
    // Цвет
    color: "green"
 
    // Радиус углов
    radius: 20
 
    // Сглаживание включено
    smooth: true
 
    Text {
        id: textPush
        text: qsTr("Настройки")
 
        // По центру
        anchors.verticalCenter: push.verticalCenter
        anchors.horizontalCenter: push.horizontalCenter
    }
 
    scale: pushMouse.pressed? 0.8 : 1.0 // При нажатии будет уменьшатся
 
    MouseArea {
        id: pushMouse
        anchors.fill: parent
        acceptedButtons: Qt.LeftButton | Qt.RightButton // Левая и правая кнопка мыши
    }
}
Что бы добраться до обьекта Text в Push.qml ему нужно назначить имя доступа:
В нашем случае это будет выглядеть так:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
...
    // Разрешаем доступ textPush
    property alias textPush /*Имя вы придумываете сами*/: textPush.text /*Установка к чему вы хотите получить доступ*/
 
    Text {
        id: textPush
        text: qsTr("Настройки")
 
        // По центру
        anchors.verticalCenter: push.verticalCenter
        anchors.horizontalCenter: push.horizontalCenter
    }
...
В mainQml установка будет выглядеть так:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Rectangle {
    id: mainQml
    width: 300
    height: 300
 
    // Цвет - градиент
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#4c0000"}
        GradientStop { position: 0.5; color: "#df8c73"}
        GradientStop { position: 1.0; color: "#4c0000"}
    }
 
    Push{
        textPush: "new Text"
    }
}
А теперь добавим несколько кнопок и назначим разные параметры при клике на них:

Добовляем кнопки:
mainQml:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Rectangle {
    id: mainQml
    width: 300
    height: 300
 
    // Цвет - градиент
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#4c0000"}
        GradientStop { position: 0.5; color: "#df8c73"}
        GradientStop { position: 1.0; color: "#4c0000"}
    }
 
    Push{
        id: pushOne
        objectName: "pushOne"
        color: "red"
        textPush: "pushOne"
        y: 50
    }
 
    Push{
        id: pushTwo
        objectName: "pushTwo"
        color: "green"
        textPush: "pushTwo"
        y: pushOne.y + pushTwo.height + 10
    }
 
    Push{
        id: pushThree
        objectName: "pushThree"
        color: "#ffffff"
        textPush: "pushThree"
        y: pushTwo.y + pushThree.height + 10
    }
 
    Push{
        id: pushFour
        objectName: "pushFour"
        color: "yellow"
        textPush: "pushFour"
        y: pushThree.y + pushFour.height + 10
    }
}
objectName - имя обькта. По этому имени можно получить доступ как в qml так из qt. В данном случае мы его используем для назначения разных параметров при клике.

Вот что у нас получилось:
Вопрос - Ответ для новичков по Qt


























А теперь назначим параметры клика в Push.qml:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Rectangle {
    id: push
 
    width: 150
    height: 40
 
    y: 130
    // По центру
    anchors.horizontalCenter: parent.horizontalCenter
 
    // Цвет
    color: "green"
 
    // Радиус углов
    radius: 20
 
    // Сглаживание включено
    smooth: true
 
    // Разрешаем доступ textPush
    property alias textPush /*Имя вы придумываете сами*/: textPush.text /*Установка к чему вы хотите получить доступ*/
 
    Text {
        id: textPush
        text: qsTr("Настройки")
 
        // По центру
        anchors.verticalCenter: push.verticalCenter
        anchors.horizontalCenter: push.horizontalCenter
    }
 
    scale: pushMouse.pressed? 0.8 : 1.0 // При нажатии будет уменьшатся
 
    MouseArea {
        id: pushMouse
        anchors.fill: parent
        acceptedButtons: Qt.LeftButton | Qt.RightButton // Левая и правая кнопка мыши
        onClicked:
        {
            /* Отталкиваясь от objectName назначаем разные
              параметры клика по кнопке*/
 
            if(push.objectName == "pushOne")
                console.log("clicked pushOne")
 
            else if(push.objectName == "pushTwo")
                console.log("clicked pushTwo")
 
            else if(push.objectName == "pushThree")
                console.log("clicked pushThree")
 
            else if(push.objectName == "pushFour")
                console.log("clicked pushFour")
        }
    }
}


Вопрос - Ответ для новичков по Qt























Так делал я, возможно есть другое решение. Спасибо за внимание

Программа:
Вложения
Тип файла: zip Property.zip (3.6 Кб, 64 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
11.08.2012, 18:36     Вопрос - Ответ для новичков по Qt #15
Модули Qt

Иерархия классов Qt имеетчеткую внутреннюю структуру, которую важно понять, чтобы уметь хорошои интуитивно ориентироваться в этой библиотеке. Библиотека Qt — это множество классов (более 500), которые охватываютбольшую часть функциональных возможностей операционных систем,предоставляя разработчику мощные механизмы, расширяющие и, вместе с тем,упрощающие разработку приложений. При этом не нарушается идеологияоперационной системы. Qt не является единым целым, она разбита на модули:
  • Библиотека:
    QtCore
    Обозначение в проектном файле:
    core
    Назначение:
    Основополагающий модуль, состоящийиз классов, не связанных с графическим интерфейсом
  • Библиотека:
    QtGui
    Обозначение в проектном файле:
    gui
    Назначение:
    Модуль для программирования графического интерфейса
  • Библиотека:
    QtNetwork
    Обозначение в проектном файле:
    network
    Назначение:
    Модуль для программирования сети
  • Библиотека:
    QtOpenGL
    Обозначение в проектном файле:
    opengl
    Назначение:
    Модуль для программирования графики OpenGL
  • Библиотека:
    QtSql
    Обозначение в проектном файле:
    sql
    Назначение:
    Модуль для программирования базданных
  • Библиотека:
    QtSvg
    Обозначение в проектном файле:
    svg
    Назначение:
    Модуль для работы с SVG (ScalableVector Graphics, масштабируемаявекторная графика)
  • Библиотека:
    QtXml
    Обозначение в проектном файле:
    xml
    Назначение:
    Модуль поддержки XML, классы,относящиеся к SAX и DOM
  • Библиотека:
    Qt3Support
    Обозначение в проектном файле:
    qt3support
    Назначение:
    Модуль, содержащий классы для совместимости с предыдущей библиотекой Qt
  • Библиотека:
    QtScript
    Обозначение в проектном файле:
    script
    Назначение:
    Модуль поддержки языка сценариев
  • Библиотека:
    Phonon
    Обозначение в проектном файле:
    phonon
    Назначение:
    Модуль мультимедиа
  • Библиотека:
    QtWebKit
    Обозначение в проектном файле:
    webkit
    Назначение:
    Модуль для создания веб-приложений
  • Библиотека:
    QtScriptTools
    Обозначение в проектном файле:
    scripttools
    Назначение:
    Модуль дополнительных возможностей поддержки языка сценария. На настоящий момент предоставляет отладчик
  • Библиотека:
    QtTest
    Обозначение в проектном файле:
    test
    Назначение:
    Модуль, содержащий классы для тестирования кода

Любая Qt-программа так или иначе должна использовать хотя бы один из модулей, в большинстве случаев это QtCore и QtGui, поэтому эти два модуля определены в программе создания make-файлов по умолчанию. Для использования других модулей в своих проектах необходимо перечислить их в проектном файле. Например, чтобы добавить модули, нужно написать:


QT += opengl network sql
А чтобы исключить модуль из проекта:

QT -= gui
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
13.08.2012, 20:05     Вопрос - Ответ для новичков по Qt #16
Работа с zip архивами в Qt (разархивация)

В Qt есть не документированные классы для работы с zip архивами. Эти классы позволяют распаковывать уже существующие архивы по заданному пути, так и создавать новые архивы. Для создания используется класс QZipWriter, для распаковки QZipReader. Для использования этих классов предлагаю скопировать указанные файлы в свой проект и добавить их в компиляцию.

Напишу способ разархивирования zip файлов из заданной директории.
Воспользуемся классом QZipReader.

В папку с пограммой добавим папку qzip (прилагается к посту). Ее содержимое:
qzipreader_p.h
qzipwriter_p.h
qzip.cpp

QZipReader и QZipWriter используют библеотеку zlib. На linux проблем не возникало, а при переносе прграммы на Windows библиотека zlib небыла найдена. Поэтому я изночально включил в проект эту библиотеку:

Папка zlib:
zlib-1.2.5.zip - полная библиотека zlib
zlib125dll.zip - dll zlib
// файлы которые потребуються для QZipReader и QZipWriter
zlib.h
zconf.h.in
zconf.h

Создадим функцию которая будет принемать путь к дериктории и возвращать результат:
1 - разархивация прошла успешно
0 - ошибка разорхивации

int readerZip(QString str);

Подключение библиотеки будет выглядеть в нашем случае вот так:
C++ (Qt)
1
2
#include "qzip/qzipreader_p.h"  // для распаковки
#include "qzip/qzip.cpp"
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Распаковка zip
int MainWindow::readerZip(QString str)
{
    QDir dir(str.toAscii());    // Создаем QDir в указанном пути (str)
 
    QStringList filters;                // Устанавливаем фильтры
    filters << "*.zip";                 // Устанавливаем фильтры
    dir.setNameFilters(filters);        // Устанавливаем фильтры
 
    QFileInfoList list = dir.entryInfoList();   // Чтение инфо о файлах в указанном пути (str) c раширением zip
 
    for (int i = 0; i < list.size(); ++i) {
 
        QZipReader zip_reader(QLatin1String(str.toAscii() + "/" + list.at(i).fileName().toAscii())); // чтение указанного zip архива
 
        if (zip_reader.exists()) {          // Если все чудно
 
            // вывод информации об архиве
            qDebug() << "Количество элементов в архиве =" << zip_reader.count(); // Количество элементов в архиве
 
            foreach (QZipReader::FileInfo info, zip_reader.fileInfoList()) { // Инфорация о архиве
                if(info.isFile)
                    qDebug() << "File:" << info.filePath << info.size; // размер извлекаемого файла
                else if (info.isDir)
                    qDebug() << "Dir:" << info.filePath;
                else
                    qDebug() << "SymLink:" << info.filePath;
            }
 
            // распаковка архива по указанному пути
            zip_reader.extractAll(str.toAscii());
        }
        else
        {
            // Вернем ошибку
            return 0;
        }
    }
 
    return 1;
}
Удачи!

qzip.zip - библиотеки
zipreader.zip - программа-пример
Миниатюры
Вопрос - Ответ для новичков по Qt  
Вложения
Тип файла: zip qzip.zip (1.46 Мб, 178 просмотров)
Тип файла: zip zipreader.zip (1.46 Мб, 167 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
04.09.2012, 11:54     Вопрос - Ответ для новичков по Qt #17
QLabel. Размер текста относительно ширины QLabel.

При увеличении шрифта текста и вывод его на QLabel он не всегда поместиться на обьекте и может выйти за границы:

Вопрос - Ответ для новичков по Qt

















Для того что бы этого не случалось. Если ширина текта привысит ширину обьекта будем его уменьшать - чем длиннее текст тем меньше шрифт.

QLabel принимает html код. Воспользуемся этим. Вот мое произвидение на эту тему:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Функция устанавливающая размер шрифта относительно размера окна
QString MainWindow::setWidthFont(QString str, int maxwidth, int maxfont)
{
    /*
      str = текст передоваемый для проверки на размер
      maxwidth = размер нашего окна
      maxfont = максимально-нужный размер текста
    */
 
 
    QString newHtml;    // Будуший текст
 
    QFont font; // Это QFont :)
 
    int i;
    for(i = maxfont; i>0; i--)
    {
        font.setPixelSize(i);   // Циклом проверяем оптимально подходящий размер
 
        if(QFontMetrics(font).width(str) < maxwidth-10) // Если ширина шрифта меньше ширины mazwidth
        {
            break;
        }
    }
 
    // Создаем html с нужным нам размером
    newHtml = "<center>";   // Отцентрируем текст
    newHtml += "<span style=" font-size:" + QString::number(i,10) + "px;">" + str + "</span>";
    newHtml += "</center>"; // Отцентрируем текст
 
    return newHtml; // Готово, возвращаем QString
}
Вот пример приминения:
C++ (Qt)
1
ui->label->setText(setWidthFont(words.at(3)/*Слово/Текст*/,ui->label->width()/*Размер QLabel*/,70/*Нужный размер шрифта*/));

Вопрос - Ответ для новичков по Qt

















Удачи!
Программа-пример прилагается:
Вложения
Тип файла: zip Font_size.zip (3.2 Кб, 73 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
06.09.2012, 14:32     Вопрос - Ответ для новичков по Qt #18
Qml. Обьединение Qml и виджетов Qt

Допусти имеется у нас итерфейс на qml:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
import QtQuick 1.1
 
Rectangle {
    id: main
    objectName: "main"
 
    width: 800
    height: 250
 
    color: "black"
 
    smooth: true
 
    Rectangle{
        id: mainMenu
 
        width: 800
        height: 0 // Обратите внимание!
                     // Это вам может пригодиться если нужно будет перемещать mainMenu (id) 
                     //(его не будет видно!) и не трогать main (id). В данном случае мы 
                     //перемещение mainMenu не используем, а перемещаем main (id).
 
        state: "normal"
 
        states: [
            State {
                name: "normal"
                PropertyChanges {target: main; x:0;}
            },
            State {
                name: "shift"
                PropertyChanges {target: main; x: -400}
            }
        ]
 
        transitions: Transition {
            PropertyAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutSine }
        }
 
        Rectangle{
            id: one
 
            x: 10
            y: 10
 
            objectName: "one"
 
            color: "green"
 
            width: 380
            height: 230
 
            radius: 20
            smooth: true
 
            Text {
                id: text
                font.pixelSize: 40
 
                text: qsTr("Hello world!")
 
                anchors.verticalCenter: one.verticalCenter
                anchors.horizontalCenter: one.horizontalCenter
            }
 
            Rectangle{
                id: up
                width: 100
                height: 30
 
                x: parent.width/2 - up.width/2
                y: parent.height - up.height - 10
 
                radius: 20
                smooth: true
 
                Text{
                    text: "Далее >>"
 
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.horizontalCenter: parent.horizontalCenter
                }
 
                scale: buttonMouse.pressed? 0.8 : 1.0
 
                MouseArea {
                    id: buttonMouse
                    anchors.fill: parent
                    acceptedButtons: Qt.LeftButton | Qt.RightButton
                    onClicked:
                    {
                        mainMenu.state = "shift";
                    }
                }
            }
        }
 
        Rectangle{
            id: two
 
            x: 410
            y: 10
 
            objectName: "two"
 
            color: "yellow"
 
            width: 380
            height: 230
 
            radius: 20
            smooth: true
 
            Text {
                id: textTwo
                font.pixelSize: 40
 
                text: qsTr("Goodby world!")
 
                anchors.verticalCenter: parent.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
            }
 
            Rectangle{
                id: down
                width: 100
                height: 30
 
                x: parent.width/2 - up.width/2
                y: parent.height - up.height - 10
 
                radius: 20
                smooth: true
 
                Text{
                    text: "<< Назад"
 
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.horizontalCenter: parent.horizontalCenter
                }
 
                scale: buttonMouseTwo.pressed? 0.8 : 1.0
 
                MouseArea {
                    id: buttonMouseTwo
                    anchors.fill: parent
                    acceptedButtons: Qt.LeftButton | Qt.RightButton
                    onClicked:
                    {
                        mainMenu.state = "normal";
                    }
                }
            }
        }
    }
}

Он переключает с помощью кнопки "Далее >>" или "<< Назад" между двумя формами Rectangle.

Вопрос - Ответ для новичков по Qt
Вопрос - Ответ для новичков по Qt


















Добавим на форму "Goodby world!" (two) допустим обьект QListWidget. Добавляем его так:

MainWindow.h
C++ (Qt)
1
2
3
4
5
6
...
#include <QListWidget>
...
private:
QListWidget *list;
...
MainWindow.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
    list = new QListWidget(this);
    list->setFixedSize(360,70); // Установим его размер
    list->move(420,20);     // Установим нужое положение
                            // (при перемещении нашей формы "Goodby world!"
                            // будем перемещать и QListWidget)
    // Добавим intems для наглядности
    list->addItem("one item");
    list->addItem("two item");
    list->addItem("three item");
    list->addItem("four item");
В MainWindow.h добавим функцию которая нам позволит перемещать наш обьект QListWidget:

C++ (Qt)
1
2
3
4
5
6
7
...
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
 
    Q_INVOKABLE void moveobject(int);      // Функция C++ вызываемая из QML для зименения положения QListWidget
...
В MainWindow.cpp реализация:
C++ (Qt)
1
2
3
4
5
6
7
// Функция C++ вызываемая из QML для зименения положения QListWidget
void MainWindow::moveobject(int x)
{
    list->move(420 + x,20);     // Установим нужое положение
                            // (при перемещении нашей формы "Goodby world!"
                            // будем перемещать и QListWidget)
}
В *.qml (в программе-примере main.qml):

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
                Text{
                    text: "<< Назад"
 
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.horizontalCenter: parent.horizontalCenter
                }
 
                scale: buttonMouseTwo.pressed? 0.8 : 1.0
 
                MouseArea {
                    id: buttonMouseTwo
                    anchors.fill: parent
                    acceptedButtons: Qt.LeftButton | Qt.RightButton
                    onClicked:
                    {
                        mainMenu.state = "normal";
                    }
                }
            }
        }
    }
 
    onXChanged: Qt_fun.moveobject(main.x) // Передает сигнал при перемещении main (id)
}
Ну вот и все:

Нажмите на изображение для увеличения
Название: 96460754804433736524.png
Просмотров: 7
Размер:	15.8 Кб
ID:	587527
Вопрос - Ответ для новичков по Qt


















Удачи!

Программа-пример:
Вложения
Тип файла: zip Qml-qt.zip (3.7 Кб, 80 просмотров)
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
12.09.2012, 00:39     Вопрос - Ответ для новичков по Qt #19
Циклы в отдельном потоке.

При запуске цикла происходит подвесание GUI. Если вам нужно во время его (цикла) работы выводить информацию на GUI можно применить обновление отображения всей программы:

C++ (Qt)
1
QApplication::processEvents();
Это ресурсоемкая операция не лучший вариант.

Для долгих циклов можно создать отдельный поток его обработки.

Описываем свой класс, который будет проводить все действия:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass : public QObject
{
    Q_OBJECT
 
public:
    explicit MyClass(QObject *parent = 0);
 
private:
    bool needStop; // эта переменная нам будет сигнализировать, что пора завершать работу
 
signals:
    void finished();  // сигнал будем вызвать, когда закончили работу
    void sendString(QString); // через этот сигнал будем общаться с главным окном
 
public slots:
    void start(); // в этом слоте будут выполняться все действия
    void stop(); // этот слот будет говорить нам, что пора завершать работу (просто сделает needStop=true)
};
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
MyClass::MyClass(QObject *parent) :
    QObject(parent)
{
    needStop = false;
}
 
void MyClass::start() // будем имитировать полезное действие... просто сравнивать время и каждую секунду обращаться к окну
{
    QDateTime dt = QDateTime::currentDateTime();
    uint curSec = dt.toTime_t();
    while (!needStop) // пока переменная needStop=false
    {
        dt = QDateTime::currentDateTime(); // проверяем время
        if (curSec!=dt.toTime_t()) // изменилась ли секунда
        {
            curSec=dt.toTime_t();  // обновить секунды и...
            emit sendString(dt.toString()); // вызвать сигнал, который отправит строку в главное окно
        }
    }
    emit finished(); // вызываем сигнал, что мы закончили работу
}
 
void MyClass::stop()
{
    needStop = true; // думаю, комментарии не нужны
}

На форме ставим две кнопки и QLabel для вывода получаемого сигнала из нашего класса
Вопрос - Ответ для новичков по Qt













C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
 
private:
    Ui::MainWindow *ui;
 
private slots:
    void on_pushButton_clicked();  // слот для первой кнопки будет запускать поток
};
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <QThread>
#include <QDateTime>
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}
 
void MainWindow::on_pushButton_clicked()
{
    QThread *thread = new QThread;  // создаём поток... вначале он создаётся остановленным
 
    MyClass *job = new MyClass; // создаём экземпляр нашего класса
 
    job->moveToThread(thread); // наш класс мы уводим на только что созданный поток... теперь класс будет выполняться независимо от главного окна
    connect(thread,SIGNAL(started()),job,SLOT(start())); // когда поток стартует, то начать выполнение работы нашего класса
    connect(job,SIGNAL(finished()),thread,SLOT(quit())); // когда работа будет завершена, завершить поток
    connect(job,SIGNAL(finished()),job,SLOT(deleteLater())); // когда работа будет завершена, удалить наш экземпляр класса
    connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater())); // когда поток остановится, удалить его
    //connect(job,SIGNAL(sendString(QString)),this,SLOT(reciveString(QString))); // соединить сигнал передачи строки нашего класса со слотом главного окна
    connect(ui->pushButton_2,SIGNAL(clicked()),job,SLOT(stop()),Qt::DirectConnection); // при нажатии на вторую кнопку вызывать MyClass::stop()
           // обрати внимание, что там ещё указан пятый параметр Qt::DirectConnection... он необходим, т.к. наш класс работает в цикле без перерывов
           // и без этого параметра наш сигнал никогда не достигнет слота класса.
           // Если бы мы класс делали основанным на событиях, где функции время от времени завершают работу, тогда этот параметр можно было не указывать.
    thread->start(); // всё настроено, теперь просто запускаем поток.
 
 
    connect(job,SIGNAL(sendString(QString)),ui->label,SLOT(setText(QString))); // Подсоединим сигнал нашего класса к слоту label
}
Ну вот что получилось:
Вопрос - Ответ для новичков по Qt














Удачи! Спасибо Humanoid.

Программа:
Вложения
Тип файла: zip cycle_stream.zip (4.3 Кб, 133 просмотров)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2012, 23:22     Вопрос - Ответ для новичков по Qt
Еще ссылки по теме:

Посоветуйте книгу для новичков C++ Qt
C++ Qt Распаковывать gzip ответ QNetworkAccessManager
C++ Qt Как вывести ответ на окно?
C++ Qt Спарсить ответ, QRegExp
C++ Qt Спарсить ответ

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
KeyGen
 Аватар для KeyGen
333 / 289 / 6
Регистрация: 07.08.2011
Сообщений: 789
Записей в блоге: 1
19.09.2012, 23:22     Вопрос - Ответ для новичков по Qt #20
Выбор кодировки текста

Для отображения нужной кодировки текста в программе можно преобразовать кодировку в нужную нам.

Допустим мы имеем форму:

(QLabel, QComboBox)

Вопрос - Ответ для новичков по Qt














Добавим в наш MainWindow slot и QString:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QTextCodec>
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private:
    Ui::MainWindow *ui;
    QString text; // Этой строке будем менять кодировку
 
private slots:
    void setCodec(QString); // Слот для изменения кодека
};
 
#endif // MAINWINDOW_H
В comboBox добавим нужные нам кодировки и подключим слот:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    QStringList listCodec;
    // Вот некоторые кодеки из доступных в Qt
    listCodec << "Apple Roman";
    listCodec << "Big5";
    listCodec << "Big5-HKSCS";
    listCodec << "CP949";
    listCodec << "EUC-JP";
    listCodec << "EUC-KR";
    listCodec << "KOI8-R";
    listCodec << "KOI8-U";
    listCodec << "MuleLao-1";
    listCodec << "ROMAN8";
    listCodec << "Shift-JIS";
    listCodec << "TIS-620";
    listCodec << "TSCII";
    listCodec << "UTF-8";
    listCodec << "UTF-16";
    listCodec << "UTF-16BE";
    listCodec << "Windows-1250"; // to 1258
    listCodec << "Windows-1251"; // Русский
 
    text = "Русский";
    ui->label->setText(text);
 
    // Добавим из в comboBox
    ui->comboBox->addItems(listCodec);
 
    // Подключим сигнал изменеия comboBox
    connect(ui->comboBox,SIGNAL(activated(QString)),this,SLOT(setCodec(QString)));
 
    // Установим comboBox на нашу кодировку
    ui->comboBox->setCurrentIndex(listCodec.indexOf("UTF-8"));
 
}

А вот реализация слота для преобразования кодека:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
// Слот для изменения кодека
void MainWindow::setCodec(QString newCodec)
{
    // Выбор кодека
     QTextCodec *codec = QTextCodec::codecForName(newCodec.toAscii());
 
     // Изменяем кодировку
     QByteArray encodedString = codec->fromUnicode(text);
 
     // В label вписываем текст с новой кодировкой
     ui->label->setText(encodedString);
}
Вот что получилось:
Вопрос - Ответ для новичков по Qt Вопрос - Ответ для новичков по Qt















Спасибо за внимание!

Программа-пример прилагается:
Вложения
Тип файла: zip codec.zip (5.4 Кб, 142 просмотров)
Yandex
Объявления
19.09.2012, 23:22     Вопрос - Ответ для новичков по Qt
Закрытая тема Создать тему

Метки
faq, qtsdk, новички, проблемы, Решение, советы, фак
Опции темы

Текущее время: 15:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru