qt

Описание: Разработка и отладка приложений. Упор на 3D-графику.

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#7 dyvniy » Пт, 18 июля 2014, 13:46:37

QMutex resursive
http://stackoverflow.com/questions/13637830/how-to-use-recursive-qmutex

QRegExp
http://doc.crossplatform.ru/qt/4.7.x/qregexp.html
Спойлер
Символы и сокращения для наборов символов
Элемент Значение
c Символ представляет сам себя, если у него нет особого значения в регулярном выражении. Напримeр, c соответствует символу c.
\c Символ, который следует за обратной наклонной чертой, соответствует самому себе, за исключением случаев, указанных ниже.
Например, для буквального соответствия символу крышки в начале строки напишите \^.
\a Соответствует ASCII-символу звонка (BEL, 0x07).
\f Соответствует ASCII-символу подачи страницы (FF, 0x0C).
\n Соответствует ASCII-символу перевода строки (LF, 0x0A, новая строка в Unix).
\r Соответствует ASCII-символу возврата каретки (CR, 0x0D).
\t Соответствует ASCII-символу горизонтальной табуляции (HT, 0x09).
\v Соответствует ASCII-символу вертикальной табуляции (VT, 0x0B).
\xhhhh Соответствует Unicode-символу, соответствующему шестнадцатеричному числу hhhh (между 0x0000 и 0xFFFF).
\0ooo (т.е., \zero ooo) Соответствует ASCII/Latin1-символу для восьмеричного числа ooo (между 0 и 0377).
. (точка) Соответствует любому символу (включая новую строку).
\d Соответствует цифре (QChar::isDigit()).
\D Соответствует не цифре.
\s Соответствует пробельному символу (QChar::isSpace()).
\S Соответствует непробельному символу.
\w Соответствует символу слова (QChar::isLetterOrNumber(), QChar::isMark() или '_').
\W Соответствует символу не слова.
\n n-тая обратная ссылка, например, \1, \2 и т.д.
Замечание: Компиляторы C++ преобразуют обратные наклонные черты в строках. Для включения \ в регулярное выражение введите её дважды, т.е. \\. Для соответствия обратной наклонной черты самой себе введите её четыре раза, т.е. \\\\.

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

^ Каретка отрицает набор символов, если она является первым символом (т.е. непосредственно после открывающей квадратной скобки). [abc] соответствует либо 'a', либо 'b', либо 'c', но [^abc] соответствует чему-либо кроме 'a', 'b' и 'c'.
- Тире указывает диапазон символов. [W-Z] соответствует либо 'W', либо 'X', либо 'Y', либо 'Z'.
Использование предопределённых сокращений для наборов символов более переносимо, чем использование диапазонов символов на разных платформах и языках. Например, [0-9] соответствует цифре в западных алфавитах, а \d соответствует цифре в любом алфавите.

Замечание: В другой документации по регулярным выражениям наборы символов часто называют "классами символов".

Кванторы
По умолчанию выражение автоматически определяется {1,1}, т.е. оно должно произойти точно один раз. В следующем списке E обозначает выражение. Выражение - это символ, или сокращение для набора символов, или набор символов в квадратных скобках, или выражение в круглых скобках.

E? Соответствует нулю или одному вхождению E. Этот квантор означает, что предыдущее выражение необязательное, поскольку соответствие всё равно будет, найдено выражение или нет. E? - это то же самое, что и E{0,1}. Например, dents? соответствует 'dent' или 'dents'.
E+ Соответствует одному или нескольким вхождениям E. E+ - это то же самое, что и E{1,}. Например, 0+ соответствует '0', '00', '000' и т.д.
E* Соответствует нулю или нескольким вхождениям E. Это то же самое, что и E{0,}. Квантор * часто используется по ошибке там, где должен быть использован +. Например, если \s*$ будет использоваться в выражении для поиска строк, которые заканчиваются пробельными символами, то оно будет соответствовать любой строке, поскольку \s*$ означает Соответствие нулю или нескольким пробельным символам со следующим концом строки. Корректное регулярное выражение для соответствия строкам, которые имеют как минимум один пробельный символ, это \s+$.
E{n} Соответствует точно n вхождениям E. E{n} то же самое, что и повтор E n раз. Например, x{5} это то же самое, что и xxxxx. Это также то же самое, что и E{n,n}, например, x{5,5}.
E{n,} Соответствует не меньше n вхождений E.
E{,m} Соответствует не больше m вхождений E. E{,m} это то же самое, что и E{0,m}.
E{n,m} Соответствует не меньше n и не больше m вхождений E.
Чтобы применить квантор к больше, чем одному предшествующему символу, используйте круглые скобки для группирования символов в выражение. Например, tag+ соответствует 't' с последующим 'a' с последующим не меньше чем одним 'g', в то время как (tag)+ соответствует не меньше чем одному вхождению 'tag'.

Замечание: Кванторы обычно "жадные". Они всегда соответствуют максимальному количеству текста, которому могут. Например, 0+ соответствует первому нулю, который будет найден, и всем последующим нулям после первого нуля. Применимо к '20005' он соответствует '20005'. Кванторы могут быть не жадными, смотрите setMinimal().

Захват текста
Круглые скобки позволяют группировать элементы таким образом, что можно определить их количество и затем захватить. Например, если у нас есть выражение mail|letter|correspondence, которое соответствует строке, то мы знаем, что одно из слов соответствует, но не знаем, какое. Использование круглых скобок позволяет "захватить" всё, что соответствует в пределах их границ, так что если мы используем (mail|letter|correspondence) и соответствие этого регулярного выражения вместе со строкой "I sent you some email", то мы можем использовать функции cap() или capturedTexts() для извлечения соответствующих символов, в данном случае 'mail'.

Мы можем использовать захваченный текст внутри самого регулярного выражения. Для ссылки на захваченный текст мы используем обратные ссылки, которые нумеруются с 1, как и для cap(). Например, мы могли бы найти повторяющиеся слова в строке при помощи \b(\w+)\W+\1\b, что означает соответствие границе слова со следующими одним или более символами слов со следующими одним или более символами не слов со следующим текстом таким же, как и в первом выражении в скобках.

Если мы хотим использовать круглые скобки только для группировки, но не для захвата, то мы можем использовать незахватывающий синтаксис, например (?:green|blue). Незахватывающие круглые скобки начинаются с '(?:' и заканчиваются на ')'. В этом примере у нас есть соответствие либо 'green', либо 'blue', но мы не захватываем текст, так что известно только то, что соответствие либо есть, либо нет, но не известно, какой цвет был на самом деле найден. Использование незахватывающих круглых скобок является более эффективным, чем использование захватывающих круглых скобок, так как механизм регулярных выражений будет делать меньше подсчётов.

Как захватывающие, так и незахватывающие круглые скобки могут быть вложенными.

По историческим причинам кванторы (например, *), которые применяются к захватывающим круглым скобкам, более "жадные", чем другие кванторы. Например, a*(a)* будет соответствовать "aaa" с cap(1) == "aaa". Это поведение отличается от того, что делают другие механизмы регулярных выражений (например, Perl). Чтобы получить более интуитивное поведение захвата, указывайте QRegExp::RegExp2 в конструкторе QRegExp или вызовите setPatternSyntax(QRegExp::RegExp2).

Когда количество соответствий не может быть определено заранее, обычно принято использовать cap() в цикле. Например:

QRegExp rx("(\\d+)");
QString str = "Offsets: 12 14 99 231 7";
QStringList list;
int pos = 0;

while ((pos = rx.indexIn(str, pos)) != -1) {
list << rx.cap(1);
pos += rx.matchedLength();
}
// list: ["12", "14", "99", "231", "7"]
Утверждения
Утверждения делают некоторые заявления о тексте в точке, где они встречаются в регулярном выражении, но они не соответствуют никаким символам. В следующем списке E обозначает выражение.

^ Каретка означает начало строки. Если вы хотите иметь соответствие символу ^, то вы должны экранировать его, написав \\^. Например, ^#include соответствует только строкам, которые начинаются с символов '#include'. (Когда каретка является первым символом в наборе символов, то она имеет специальное значение, смотрите Наборы символов.)
$ Доллар означает конец строки. Например, \d\s*$ соответствует только строкам, которые заканчиваются цифрой с необязательными пробелами за ней. Если вы хотите иметь соответствие символу $, то вы должны экранировать его, написав \\$.
\b Граница слова. Например, регулярное выражение \bOK\b означает соответствие непосредственно после границы слова (например, начало строки или пробельный символ) символу 'O', затем символу 'K' непосредственно перед другой границей слова (например, концом строки или пробельным символом). Но заметьте, что утверждение на самом деле не соответствует любому пробельному символу, так что если мы написали (\bOK\b) и имеем соответствие, то оно будет содержать только 'OK', даже если строкой является "It's OK now".
\B Не граница слова. Это утверждение истинно, когда \b ложно. Например, если мы ищем \Bon\B в "Left on", то соответствие найдено не будет (пробел и конец строки не являются неграницами слова), но это будет соответствовать "tonne".
(?=E) Позитивный просмотр вперёд. Это утверждение истинно, если для выражения есть соответствие в этой точке регулярного выражения. Например, const(?=\s+char) соответствует 'const' всякий раз, когда за ним следует 'char', как в 'static const char *'. (Сравните с const\s+char, который соответствует 'static const char *'.)
(?!E) Негативный просмотр вперёд. Это утверждение истинно, если для выражения нет соответствия в этой точке регулярного выражения. Например, const(?!\s+char) соответствует 'const' кроме случаев, когда за ним следует 'char'.
Соответствие подстановочных знаков
Большинство командных оболочек, таких как bash или cmd.exe, поддерживают "подстановку файлов", возможность идентифицировать группу файлов при помощи подстановочных знаков. Функция setPatternSyntax() используется для переключения между регулярными выражениями и режимом подстановочных знаков. Соответствие подстановочных знаков более простое, чем полные регулярные выражения, и имеет только четыре возможности:

c Любой символ представляет сам себя, кроме упомянутых ниже. Таким образом c соответствует символу c.
? Соответствует любому одиночному символу. Это то же самое, что и . в полных регулярных выражениях.
* Соответствует нулю или нескольким любым символам. Это то же самое, что и .* в полных регулярных выражениях.
[...] Набор символов может быть представлен в квадратных скобках, подобно полным регулярным выражениям. В классе символов, как и вне его, обратная наклонная черта не имеет особого значения.
В режиме Wildcard символы подстановочных знаков не могут быть экранированы. В режиме WildcardUnix символ '\' экранирует подстановочные знаки.

Например, если мы находимся в режиме подстановочных знаков и имеем строку, которая содержит имена файлов, мы можем идентифицировать файлы с помощью *.html. Это будет соответствовать нулю или нескольким символам со следующей точкой со следующими 'h', 't', 'm' и 'l'.

Чтобы проверить строку с выражением с подстановочными знаками, используйте exactMatch(). Например:

QRegExp rx("*.txt");
rx.setPatternSyntax(QRegExp::Wildcard);
rx.exactMatch("README.txt"); // возвращает true

Код: Выделить всё


Примеры кода
 QRegExp rx
("^\\d\\d?$");    // соответствует целым от 0 до 99
 rx.indexIn("123");          // возвращает -1 (нет соответствия)
 rx.indexIn("-6");           // возвращает -1 (нет соответствия)
 rx.indexIn("6");            // возвращает 0 (соответствие в позиции 0)
Третья строка соответствует '6'. Это простая проверка регулярного выражения на целые в диапазоне от 0 до 99.

 QRegExp rx("^\\S+$");       // соответствует строке без пробельных символов
 rx.indexIn("Hello world");  // возвращает -1 (нет соответствия)
 rx.indexIn("This_is-OK");   // возвращает 0 (соответствие в позиции 0)
Вторая строка соответствует 'This_is-OK'. Мы использовали сокращение для набора символов '\S' (не пробельные символы) и 
якорь для соответствия строке
, не содержащей пробельных символов.

В следующем примере мы ищем соответствие строкам, содержащим 'mail', или 'letter', или 'correspondence', 
но только соответствие целым словам
, т.е. не 'email'.

 QRegExp rx("\\b(mail|letter|correspondence)\\b");
 rx.indexIn("I sent you an email");     // возвращает -1 (нет соответствия)
 rx.indexIn("Please write the letter"); // возвращает 17
Вторая строка соответствует "Please write the letter". Слово 'letter' также захватывается (из-за круглых скобок). Мы можем увидеть, какой текст мы получили, подобно этому:

 QString captured = rx.cap(1); // captured == "letter"
Это захватит текст из первого набора захватывающих круглых скобок (подсчёт захватывающих левых круглых скобок идёт слева направо). 
Круглые скобки подсчитываются
, начиная с 1, так как cap(0) является соответствием всему регулярному выражению 
(эквивалентно '&' в большинстве механизмов регулярных выражений).

 QRegExp rx("&(?!amp;)");      // соответствует амперсанду, но не &amp;
 QString line1 = "This & that";
 line1.replace(rx, "&amp;");
 // line1 == "This &amp; that"
 QString line2 = "His &amp; hers & theirs";
 line2.replace(rx, "&amp;");
 // line2 == "His &amp; hers &amp; theirs"
Здесь мы передали QRegExp в функцию QString replace() для замены соответствующего текста на новый текст.

 QString str = "One Eric another Eirik, and an Ericsson. "
               "How many Eiriks, Eric?";
 QRegExp rx("\\b(Eric|Eirik)\\b"); // соответствие Eric или Eirik
 int pos = 0;    // где мы находимся в строке
 int count = 0;  // подсчитываем, как много Eric и Eirik
 while (pos >= 0) {
     pos = rx.indexIn(str, pos);
     if (pos >= 0) {
         ++pos;      // двигаемся далее по строке
         ++count;    // учитываем нашего Eric или Eirik
     }
 }
Мы использовали функцию indexIn(), чтобы повторно искать соответствие регулярного выражения в строке. 
Заметьте
, что вместо перемещения вперёд на один символ за раз pos++ мы могли бы написать pos += rx.matchedLength(), 
чтобы пропустить уже соответствующие строки
. Количество будет равно 3, соответствуя 'One Eric another Eirik, 
and an Ericsson. How many Eiriks, Eric?'
; это не соответствует 'Ericsson' или 'Eiriks', поскольку они не ограничены границами слова.

Одним из распространённых применений регулярных выражений является разделение строк разграниченных данных на поля.

 str = "Nokia Corporation\tqt.nokia.com\tNorway";
 QString company, web, country;
 rx.setPattern("^([^\t]+)\t([^\t]+)\t([^\t]+)$");
 if (rx.indexIn(str) != -1) {
     company = rx.cap(1);
     web = rx.cap(2);
     country = rx.cap(3);
 }
В этом примере наши входные строки имеют формат название компании, веб-адрес и страна. К сожалению, регулярные выражения очень длинные и не универсальные -- код сломается, если мы добавим больше полей. Более простое и лучшее решение состоит в том, чтобы искать разделитель,
 '\t' в нашем случае, и получать окружающий текст. Функция QString::split() может принять разделяющую строку или регулярное
 выражение как аргумент и соответствующим образом разделить строку
.

 QStringList field = str.split("\t");
Здесь field[0] это компания, field[1] - веб-адрес и так далее.

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

 QRegExp rx("*.html");
 rx.setPatternSyntax(QRegExp::Wildcard);
 rx.exactMatch("index.html");                // возвращает true
 rx.exactMatch("default.htm");               // возвращает false
 
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#8 dyvniy » Пн, 21 июля 2014, 21:27:25

Все версии Qt уже собранные за нас
http://www.tver-soft.org/qt64
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#9 dyvniy » Сб, 26 июля 2014, 16:15:06

Qt + DirectX
http://habrahabr.ru/post/62051/
Спойлер
#ifndef DIRECT3DWIDGET_H
#define DIRECT3DWIDGET_H

#include <QtGui/QWidget>
#include <d3d9.h>
#include <atlbase.h>

class Direct3DWidget : public QWidget
{
Q_OBJECT

CComPtr<IDirect3D9> m_pD3D;
CComPtr<IDirect3DDevice9> m_pd3dDevice;
public:
Direct3DWidget(QWidget *parent = 0);
~Direct3DWidget();
bool InitDirect3D();
public slots:
bool Rendering();
private:
void paintEvent(QPaintEvent *pEvent);
};

#endif




Direct3DWidget.cpp
#include "Direct3DWidget.h"

Direct3DWidget::Direct3DWidget(QWidget *parent /* = 0 */): QWidget(parent)
{
setAttribute(Qt::WA_PaintOnScreen);
}
Direct3DWidget::~Direct3DWidget()
{
}
bool Direct3DWidget::InitDirect3D()
{
m_pD3D = Direct3DCreate9( D3D_SDK_VERSION);
if(!m_pD3D)
return false;
D3DPRESENT_PARAMETERS d3dpp = {0};
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
HRESULT hrResult = m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winId(),
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &m_pd3dDevice );
if(FAILED(hrResult))
return false;
return true;
}
bool Direct3DWidget::Rendering()
{
if(m_pd3dDevice == 0)
return false;
m_pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 0), 1.0f, 0);
if(SUCCEEDED(m_pd3dDevice->BeginScene()))
{
m_pd3dDevice->EndScene();
}
m_pd3dDevice->Present( 0, 0, 0, 0 );
return true;
}

void Direct3DWidget::paintEvent(QPaintEvent *pEvent)
{
Q_UNUSED(pEvent);
Rendering();
}




Пример использования:
#include <QtGui/QWidget>
#include <QtGui/QApplication>
#include <QtGui/QHBoxLayout>
#include "Direct3DWidget.h"

int main(int argc, char *argv[])
{
//------------------------------Start initialization
//Additional parameters, just add a parameter separated by comma
std::string aAdditionalParameters[] = {"-direct3d"};
int iRealArgumentAmount = argc + sizeof(aAdditionalParameters)/sizeof(std::string);
//This double pointer will contain parameters from argv and
//statical parameters which necessary for this application
char** pArguments = new char*[iRealArgumentAmount];
//Copy all source(from the command line) parameters
for(int i = 0; i < argc; ++i)
{
*(pArguments + i) = new char[ strlen(argv[i]) + 1 ];
strcpy( *(pArguments + i), argv[i] );
}
//Append parameters we want to add
for(int i = argc, j = 0; i < iRealArgumentAmount; ++i, ++j)
{
*(pArguments + i) = new char[ aAdditionalParameters[j].size() + 1 ];
strcpy( *(pArguments + i), aAdditionalParameters[j].c_str() );
}
QApplication xApplication(iRealArgumentAmount, pArguments);
for(int i = 0; i < iRealArgumentAmount; ++i)
delete []*(pArguments + i);
delete []pArguments;
//--------------------------------Initialization complete
QWidget xMainWindow;
Direct3DWidget* xScene = new Direct3DWidget(&xMainWindow);
QHBoxLayout* xMainLayout = new QHBoxLayout;
xMainLayout->addWidget(xScene);
xMainWindow.setLayout(xMainLayout);
//It is important to initialize the Direct3d after the widget was embedded to the window
xScene->InitDirect3D();
xMainWindow.show();

return xApplication.exec();
}




Результатом выполнения это кода будет вот такое окно(если его растянуть):
image

Казалось бы теперь есть все, чтобы спокойно использовать direct3d с отличным фреймворком Qt, но, к сожалению, мною были обнаружены некоторые подводные камни.
После того, как я стал использовать Direct3d, на некоторых компьютерах, вместо картинки отрисованной Direct3d был экран, зарисованный цветом фона. Я перебрал все комбинации аттрибутов, но убрать данный дефект так и не смог. Так же не удалось выявить причину неправильной работы direct3d engine на некоторых машинах. Т.к документация по Qt утверждает, что «This functionality is experimental.», то можно предположить, что дело в сыроватости поддержки direct3d.

Но, данный недостаток не может быть причиной не использования Direct3D:). Пока trolltech допиливает direct3d до stable state можно воспользоваться следующим workaround’ом:
Закомментируем вызов Rendering () в paintEvent:
void Direct3DWidget::paintEvent(QPaintEvent *pEvent)
{
Q_UNUSED(pEvent);
//Rendering();
}



и в место использования добавим следующий код:

...
//It is important to initialize the Direct3d after the widget was embedded to the window
xScene->InitDirect3D();
xMainWindow.show();

QTimer xTimer;
QWidget::connect(&xTimer, SIGNAL(timeout()), xScene, SLOT(Rendering()));
xTimer.start(100);

return xApplication.exec();
...
Вложения
test02cool.zip
(115.9 КБ) 108 скачиваний
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#10 dyvniy » Сб, 26 июля 2014, 20:49:36

QAction

Код: Выделить всё

ui->toolBar->addAction(QPixmap(":/icon.png"), QString("Какое-то действие"), thisSLOT(slot_doSomethihg())); 
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#11 dyvniy » Сб, 9 августа 2014, 05:53:18

Сборка под windows на linux
http://qtlinux.narod.ru/make_for_win.htm

Код: Выделить всё

Сборка в Ubuntu приложений для Windows

Представим себе ситуацию. Вы дома работаете только в Ubuntu и не используете Windows, разработку приложений осуществляете с помощью Qt Creator и библиотеки Qt. Требуется собрать приложение для Windows (чтобы использовать его, например, на работе). Qt Creator – кроссплатформенная среда разработки и позволяет выполнить эту задачу, т.е. собрать приложение для Windows в Ubuntu. Для этого необходимо один раз настроить свою среду для выполнения такой задачи, а затем пользоваться.

Сначала необходимо установить компилятор MinGW. Для этого запускаем Центр приложений Ubuntu, набираем в строке поиска mingw32, в найденном выделяем строку Minimalist GNU win32 (cross) compiler и нажимаем кнопку Установить. В результате будут установлены 3 пакета

mingw32_4.2.1.dfsg-2ubuntu1_i386.deb
 mingw32-binutils_2.20-0.2_i386.deb
 mingw32-runtime_3.15.2-0ubuntu1_all.deb
 (версии файлов на момент написания статьи),

а непосредственно сам компилятор появится в папках /usr/i586-mingw32msvc и /usr/amd64-mingw32msvc, мы будем ориентироваться на первую.

Замечание. Если требуется установить компилятор на компьютер, на котором нет доступа в интернет, можно воспользоваться способом, изложенным в соответствующей статье.

Следующим шагом надо раздобыть необходимые файлы библиотеки Qt для платформы Windows. Проще всего их взять на другом компьютере с этой платформой. Пусть библиотека Qt установлена в папку C:\Qt\qt-4.8.2, тогда выполняем следующие действия

1. Создаем в какой-либо временной папке, например, D:\TEMP, папку qt4-win, в которой будем собирать нужные файлы.

2. Копируем содержимое папок C:\Qt\qt-4.8.2\include и C:\Qt\qt-4.8.2\lib соответственно в папки D:\TEMP\qt4-win\include и D:\TEMP\qt4-win\lib.

3. Заголовочные файлы из папки C:\Qt\qt-4.8.2\include ссылаются на файлы из папки C:\Qt\qt-4.8.2\src, ее содержимое нам тоже надо получить. Если у Вас достаточно места, лучше просто скопировать эту папку целиком (она весит больше 200 MB) в папку D:\TEMP\qt4-win\src. Однако, есть у меня подозрение, что из этой папки могут потребоваться только заголовочные файлы, по крайней мере, мне ни разу не встретилась ситуация, когда бы это было не так. Поэтому, если есть желание сэкономить место на диске, скопируем только заголовочные файлы. Для этого заблаговременно создаем папку D:\TEMP\qt4-win\src, запускаем командную строку и выполняем команду

xcopy C:\Qt\qt-4.8.2\src\*.h D:\TEMP\qt4-win\src /S

В результате будут скопированы только заголовочные файлы с сохранением всех относительных путей, а размер папки D:\TEMP\qt4-win\src составит меньше 40 MB.

4. Переносим папку D:\TEMP\qt4-win на свой компьютер в Ubuntu, располагаем ее содержимое, например, в /usr/qt4-win. Поскольку файлов очень много, переносить их лучше в архиве.

5. После копирования (или распаковки) папки /usr/qt4-win проверяем наличие доступа к ее содержимому.

Замечание. Запись в папку /usr возможна только с правами ROOT. В графическом интерфейсе получить их можно, если нажать <Alt–F2> и в открывшемся окне ввести команду gksu nautilus. В результате после ввода пароля откроется файловый менеджер с правами ROOT. Для установки доступа к содержимому папки /usr/qt4-win можно кликнуть правой кнопкой мыши по ее значку в окне файлового менеджера, открытого с правами ROOT, выбрать пункт контекстного меню Свойства и на вкладке Права установить следующее


В заключение следует нажать кнопку Распространить права на вложенные файлы.

Если Вы планируете использовать в своих приложениях библиотеку Qwt, необходимо иметь также файлы этой библиотеки, собранные для платформы Windows. Берем их опять же на другом компьютере с платформой Windows. Пусть библиотека Qwt установлена в папку C:\Qt\qwt-5.2.2, выполняем действия, аналогичные тем, что описаны выше.

1. Создаем папку D:\TEMP\qwt5-win, в которой будем собирать нужные файлы.

2. Копируем содержимое папок C:\Qt\qwt-5.2.2\include и C:\Qt\qwt-5.2.2\lib соответственно в папки D:\TEMP\qwt5-win\include и D:\TEMP\qwt5-win\lib.

3. Переносим папку D:\TEMP\qwt5-win на свой компьютер в Ubuntu, располагаем ее содержимое в /usr/qwt5-win.

4. После копирования папки /usr/qwt5-win проверяем наличие доступа к ее содержимому.

Далее необходимо создать новую спецификацию сборки, для этого в каталоге /usr/share/qt4/mkspecs создаем папку win32-x-g++, копируем в нее содержимое папки win32-g++ из того же каталога и правим файл qmake.conf из новой папки так, как показано ниже в подсвеченных строках.
исходный файл qmake.conf
     файл qmake.conf с исправлениями
 
#   #
# qmake configuration for win32-g++   # qmake configuration for win32-x-g++
#
 # Written for MinGW
 #

 MAKEFILE_GENERATOR = MINGW
 TEMPLATE = app
 CONFIG += qt warn_on release link_prl copy_dir_files debug_and_release debug_and_release_target precompile_header
 QT += core gui
 DEFINES += UNICODE QT_LARGEFILE_SUPPORT
 QMAKE_COMPILER_DEFINES += __GNUC__ WIN32

 QMAKE_EXT_OBJ = .o
 QMAKE_EXT_RES = _res.o
     #
 # Written for MinGW
 #

 MAKEFILE_GENERATOR = MINGW
 TEMPLATE = app
 CONFIG += qt warn_on release link_prl copy_dir_files debug_and_release debug_and_release_target precompile_header
 QT += core gui
 DEFINES += UNICODE QT_LARGEFILE_SUPPORT
 QMAKE_COMPILER_DEFINES += __GNUC__ WIN32

 QMAKE_EXT_OBJ = .o
 QMAKE_EXT_RES = _res.o
 
QMAKE_CC = gcc   QMAKE_CC = i586-mingw32msvc-gcc
QMAKE_LEX = flex
 QMAKE_LEXFLAGS =
 QMAKE_YACC = byacc
 QMAKE_YACCFLAGS = -d
 QMAKE_CFLAGS =
 QMAKE_CFLAGS_DEPS = -M
 QMAKE_CFLAGS_WARN_ON = -Wall
 QMAKE_CFLAGS_WARN_OFF = -w
 QMAKE_CFLAGS_RELEASE = -O2
 QMAKE_CFLAGS_DEBUG = -g
 QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
     QMAKE_LEX = flex
 QMAKE_LEXFLAGS =
 QMAKE_YACC = byacc
 QMAKE_YACCFLAGS = -d
 QMAKE_CFLAGS =
 QMAKE_CFLAGS_DEPS = -M
 QMAKE_CFLAGS_WARN_ON = -Wall
 QMAKE_CFLAGS_WARN_OFF = -w
 QMAKE_CFLAGS_RELEASE = -O2
 QMAKE_CFLAGS_DEBUG = -g
 QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
 
QMAKE_CXX = g++   QMAKE_CXX = i586-mingw32msvc-g++
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
 QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
 QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
 QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
 QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
 QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
 QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
 QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
 QMAKE_CXXFLAGS_RTTI_ON = -frtti
 QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
 QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
 QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions

 QMAKE_INCDIR =   QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
 QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
 QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
 QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
 QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
 QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
 QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
 QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
 QMAKE_CXXFLAGS_RTTI_ON = -frtti
 QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
 QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
 QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions

 QMAKE_INCDIR =
QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]   QMAKE_INCDIR_QT = /usr/qt4-win/include
QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]   QMAKE_LIBDIR_QT = /usr/qt4-win/lib

 QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
 QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
 QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
 QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
     
 QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
 QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
 QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
 QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
 
QMAKE_LINK = g++   QMAKE_LINK = i586-mingw32msvc-g++
QMAKE_LINK_C = gcc   QMAKE_LINK_C = i586-mingw32msvc-gcc
QMAKE_LFLAGS =
 QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads
 QMAKE_LFLAGS_EXCEPTIONS_OFF =
 QMAKE_LFLAGS_RELEASE = -Wl,-s
 QMAKE_LFLAGS_DEBUG =
 QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
 QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
 QMAKE_LFLAGS_DLL = -shared
 QMAKE_LINK_OBJECT_MAX = 10
 QMAKE_LINK_OBJECT_SCRIPT= object_script
 QMAKE_PREFIX_STATICLIB = lib
 QMAKE_EXTENSION_STATICLIB = a


 QMAKE_LIBS =
 QMAKE_LIBS_CORE = -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32
 QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lws2_32 -lole32 -luuid -luser32 -ladvapi32
 QMAKE_LIBS_NETWORK = -lws2_32
 QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
 QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
 QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain

 !isEmpty(QMAKE_SH) {
 MINGW_IN_SHELL = 1
 QMAKE_DIR_SEP = /
 QMAKE_QMAKE ~= s,\\\\,/,
 QMAKE_COPY = cp
 QMAKE_STREAM_EDITOR = sed
 QMAKE_COPY_DIR = cp -r
 QMAKE_MOVE = mv
 QMAKE_DEL_FILE = rm
 QMAKE_MKDIR = mkdir -p
 QMAKE_DEL_DIR = rmdir
 QMAKE_CHK_DIR_EXISTS = test -d
 } else {
 QMAKE_COPY = copy /y
 QMAKE_COPY_DIR = xcopy /s /q /y /i
 QMAKE_MOVE = move
 QMAKE_DEL_FILE = del
 QMAKE_MKDIR = mkdir
 QMAKE_DEL_DIR = rmdir
 QMAKE_CHK_DIR_EXISTS = if not exist
 }
     QMAKE_LFLAGS =
 QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads
 QMAKE_LFLAGS_EXCEPTIONS_OFF =
 QMAKE_LFLAGS_RELEASE = -Wl,-s
 QMAKE_LFLAGS_DEBUG =
 QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
 QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
 QMAKE_LFLAGS_DLL = -shared
 QMAKE_LINK_OBJECT_MAX = 10
 QMAKE_LINK_OBJECT_SCRIPT= object_script
 QMAKE_PREFIX_STATICLIB = lib
 QMAKE_EXTENSION_STATICLIB = a


 QMAKE_LIBS =
 QMAKE_LIBS_CORE = -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32
 QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lws2_32 -lole32 -luuid -luser32 -ladvapi32
 QMAKE_LIBS_NETWORK = -lws2_32
 QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
 QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
 QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain

 !isEmpty(QMAKE_SH) {
 MINGW_IN_SHELL = 1
 QMAKE_DIR_SEP = /
 QMAKE_QMAKE ~= s,\\\\,/,
 QMAKE_COPY = cp
 QMAKE_STREAM_EDITOR = sed
 QMAKE_COPY_DIR = cp -r
 QMAKE_MOVE = mv
 QMAKE_DEL_FILE = rm
 QMAKE_MKDIR = mkdir -p
 QMAKE_DEL_DIR = rmdir
 QMAKE_CHK_DIR_EXISTS = test -d
 } else {
 QMAKE_COPY = copy /y
 QMAKE_COPY_DIR = xcopy /s /q /y /i
 QMAKE_MOVE = move
 QMAKE_DEL_FILE = del
 QMAKE_MKDIR = mkdir
 QMAKE_DEL_DIR = rmdir
 QMAKE_CHK_DIR_EXISTS = if not exist
 }
 
QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc.exe   QMAKE_MOC = /usr/share/qt4/bin/moc
QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic.exe   QMAKE_UIC = /usr/share/qt4/bin/uic
QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc.exe   QMAKE_IDC = /usr/share/qt4/bin/idc

 QMAKE_IDL = midl
 QMAKE_LIB = ar -ru   
 QMAKE_IDL = midl
 QMAKE_LIB = ar -ru
QMAKE_RC = windres   QMAKE_RC = i586-mingw32msvc-windres
QMAKE_ZIP = zip -r -9
      QMAKE_ZIP = zip -r -9
 
QMAKE_STRIP = strip   QMAKE_STRIP = i586-mingw32msvc-strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
 load(qt_config)   QMAKE_STRIPFLAGS_LIB += --strip-unneeded
 load(qt_config)


В заключение проверяем наличие доступа к содержимому папки /usr/share/qt4/mkspecs/win32-x-g++.

Теперь все готово к сборке Ваших проектов для Windows. Сборка осуществляется из командной строки терминала. Для сборки в конфигурации Выпуск необходимо перейти в каталог с Вашим проектом и выполнить команды

qmake -r -spec win32-x-g++
 make

В результате должен появиться исполняемый файл с расширением exe. Для сборки в конфигурации Отладка команды имеют вид

qmake -r -spec win32-x-g++ CONFIG+=debug
 make

Несколько замечаний.

1) Для однозначности в команде qmake можно указать файл своего проекта.

2) В Windows для версий библиотеки Qt младше, чем 4.8.2, по умолчанию выбирается конфигурация сборки Отладка. Конфигурацию сборки Выпуск необходимо в команде qmake указывать явно параметром CONFIG+=release. В Ubuntu, как видим, все наоборот. Для версии Qt 4.8.2 в Windows выбирается конфигурация сборки Выпуск (также как в Ubuntu), подробнее об этом читайте здесь.

3) В Windows сборка проекта осуществляется в папки debug или release в зависимости от выбора конфигурации. В Ubuntu само по себе это не происходит, обе конфигурации собираются в одну и ту же папку. Если мы хотим добиться такого же порядка сборки как и в Windows, в файл проекта необходимо включить строки

CONFIG(debug,debug|release) {
   MOC_DIR = debug
   RCC_DIR = debug
   OBJECTS_DIR = debug
   DESTDIR = debug
 } else {
   MOC_DIR = release
   RCC_DIR = release
   OBJECTS_DIR = release
   DESTDIR = release
 }

4) Собирать приложение в Ubuntu для Windows в конфигурации Отладка большого смысла нет. Если отказаться от такой возможности, то можно уменьшить размер папок /usr/qt4-win и /usr/qwt5-win, удалив из них некоторые файлы библиотек, используемых только в конфигурации Отладка. Например, в папке /usr/qt4-win/lib имеются файлы

libQtGui4.a
 libQtGuid4.a

Второй файл используется только в конфигурации Отладка, поэтому его можно удалить. И далее по аналогии... После такой очистки размер папки/usr/qt4-win уменьшается со 104 до 64 MB, а размер папки /usr/qwt5-win – с 24 до 2,5 MB.

Остается перенести сформированный exe-файл на компьютер с платформой Windows, но для его работы нужны dll-библиотеки Qt. Их можно взять на компьютере с установленной библиотекой Qt, они лежат в папке C:\Qt\qt-4.8.2\bin. Для большинства случаев достаточно только двух файлов – QtCore4.dll и QtGui4.dll. Кроме того, не забываем про dll-файлы библиотеки Qwt, если она используется в собранном приложении. Общий объем библиотек можно сократить, если брать только релизные версии файлов. Разместив dll-библиотеки в какой-либо папке, например, C:\Qt-dll, прописываем в системе путь к ней. Для этого кликаем правой кнопкой мыши по значку Мой компьютер, выбираем пункт контекстного меню Свойства, открываем вкладку Дополнительно, нажимаем кнопку Переменные среды, выбираем переменную Path, нажимаем кнопку Изменить и дописываем через точку с запятой путь

C:\Qt-dll

Теперь все приложения, использующие библиотеку Qt, будут работать на этом компьютере.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#12 dyvniy » Чт, 21 августа 2014, 14:52:20

Диалог открытия дирректории

Код: Выделить всё

#include <QApplication>

#include <QFileDialog>

class Tester : public QWidget
{
public:
  void openFile()
  {
    QFileDialog::getOpenFileName( this, tr("Open Document"), QDir::currentPath(), tr("Document files (*.doc *.rtf);;All files (*.*)"), 0, QFileDialog::DontUseNativeDialog );

    QString filename = QFileDialog::getOpenFileName( 
        this
, 
        tr
("Open Document"), 
        QDir
::currentPath(), 
        tr
("Document files (*.doc *.rtf);;All files (*.*)") );
    if( !filename.isNull() )
    {
      qDebug( filename.toAscii() );
    }
  }
  
  void openFiles
()
  {
    QStringList filenames = QFileDialog::getOpenFileNames( 
        this
, 
        tr
("Open Document"), 
        QDir
::currentPath(), 
        tr
("Documents (*.doc);;All files (*.*)") );
    if( !filenames.isEmpty() )
    {
      qDebug( filenames.join(",").toAscii() );
    }
  }
  
  void openDir
()
  {
    QString dirname = QFileDialog::getExistingDirectory( 
        this
, 
        tr
("Select a Directory"), 
        QDir
::currentPath() );
    if( !dirname.isNull() )
    {
      qDebug( dirname.toAscii() );
    }
  }
  
  void saveFile
()
  {
    QString filename = QFileDialog::getSaveFileName( 
        this
, 
        tr
("Save Document"), 
        QDir
::currentPath(), 
        tr
("Documents (*.doc)") );
    if( !filename.isNull() )
    {
      qDebug( filename.toAscii() );
    }
  }
};

int main( int argc, char **argv )
{
  QApplication app( argc, argv );
  
  Tester t
;
  
  t
.openFile();
  t.openFiles();
  t.openDir();
  t.saveFile();
  
  return 0
;
}
Изображение


Название раздела: Программирование (под Desktop и Android)
Описание: Разработка и отладка приложений. Упор на 3D-графику.

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Программирование (под Desktop и Android)»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 13 гостей