crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

История благодарностей участнику SABROG ::: Спасибо сказали: 215 раз(а)
Дата поста: В теме: За сообщение: Спасибо сказали:
25.1.2011, 22:15 Секреты и интересные возможности Qt
В Wiki, на Developer Network нашел интересный вариант размещения окна по центру:

#include <QtGui/QStyle>
#include <QtGui/QDesktopWidget>
...
window->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, window->size(), qApp->desktop()->availableGeometry()));
arial, Jabberwocky,
14.12.2010, 11:39 .ico
Цитата(KLIF @ 14.12.2010, 11:31) *
То при запуске ехе-шника их не видно ....

Плагинчик qico4.dll надо таскать еще с программой из $QTDIR/plugins/imageformats
KLIF,
10.12.2010, 21:04 Как в QDataStream указать разделитель при считывании файла?
Можно использовать метод QString QTextStream::readLine ( qint64 maxlen = 0 ) + QString::split()

Rocky,
3.8.2010, 11:51 Программа падает при выходе из QMessageBox
Похоже Qt Tool окна не считает за полноценные окна. Так будет работать, если указать родителя:

networkdemo::networkdemo(QWidget *parent) : QMainWindow(parent), ui(new Ui::networkdemo), msgBox(this)


И так будет работать, если родителя не указывать:

QApplication::setQuitOnLastWindowClosed(false);


По умолчанию setQuitOnLastWindowClosed = true. Видимо когда QMessageBox закрывается, то Qt думает, что это последнее окно.

Но после решений, что я написал выше возникает другая проблема - приложение остается висеть в процессах, слот close() для Tool окна почему-то не срабатывает. Аттрибут Qt::WA_DeleteOnClose тоже не помогает.
---
В общем, если дальше работать с Tool окном, то нужно взять за правило, что все Top Level окна должны иметь родителя. Затем прописать такое, чтобы корректно обрабатывать закрытие главного Tool окна:

void MainWindow::closeEvent(QCloseEvent *e)
{
    qApp->quit();
}

Gambit,
2.8.2010, 17:46 рандом
Юр, мне кажется это не так.

Цитата
The sequence of random numbers generated is deterministic per thread. For example, if two threads call qsrand(1) and subsequently calls qrand(), the threads will get the same random number sequence.


Последовтельность сгенеренных номеров предопределены для каждого потока. Для примера 2 потока вызывают qsrand(1) и подпоследовательность вызывает qrand(), потоки получат ту же последовательность номеров.

Поэтому я предложил такой вариант:

qsrand(QTime(0,0,0).msecsTo(QTime::currentTime())); // вызов в main()
for (int i = 0; i < threads.size(); ++i) {
    int rand = qrand()%100;
    threads[i].setRandomSeed(rand);
}

void MyThread::run()
{
    qsrand(getRandomSeed());
    ...
    qrand()%100;
}


В итоге распределения "семечек" по потокам может быть таким:

Thread 1 - 1
Thread 2 - 50
Thread 3 - 23
Thread 4 - 78
...
А уж от этих "семечек" мы получаем разную последовательность случайных чисел при вызове qrand() в каждом из потоков.

В принципе можно еще как-нибудь так извернуться: qsrand((int)this)
eldar85,
2.8.2010, 14:15 рандом
Оно и понятно, потоки наверняка почти одновременно запускаются, не успевает даже время пройти. Ты вызови один раз qsrand(), потом вызови qrand() для каждого потока, затем в каждом потоке вызови снова qsrand(), но уже со значениями полученными от предыдущего qrand'a().
eldar85,
28.7.2010, 10:47 В очередной раз о компоновщиках
Не знаю зачем это надо, но сделать можно так:

QSizePolicy sizePolicy = ui->lineEdit->sizePolicy();
sizePolicy.setVerticalPolicy(QSizePolicy::Expanding);
ui->lineEdit->setSizePolicy(sizePolicy);
...
// или с забиванием на горизонтальную политику, еще проще
ui->lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


Конечно в дизайнере проще выставить через редактор свойств.
AntonH851,
6.7.2010, 19:55 Подскажите чем лучше создавать программ?
Цитата(bynet @ 6.7.2010, 20:29) *
Программно или при помощи дизайнера создавать окна, работа с БД.

Дизайнером или вручную без разницы, все-равно .ui файл превращается в .cpp uic'ом, где построчно идет создание каждого окна также как бы это было вручную.
bynet,
6.7.2010, 17:23 В продолжение о TableView + checkState
Если слоты с сигналами не подходят, тогда остается наследование от QStandardItem например. Перекрываешь метод setCheckState(Qt::CheckState state) и пишешь логику. Если у итема есть родитель, то проверяем его галки и выставляем, если итем сам родитель то пробегаемся по всем детям и ставим галку в зависимости от результата. Стандартного подобного поведения в Qt нет.
ЙаМайскЫйПчОЛ,
21.6.2010, 18:23 Секреты и интересные возможности Qt
Реализовал установку приоритета потока в параллельном программировании.

Как многие заметили в Qt есть метод QThread::setPriority(), а вот как задать приоритет потоку запущенному например через QtConcurrent::run() не понятно. В новом стандарте C++0x будет метод std::call_once, который является потокобезопасной функций для выполнения определеннной функции один лишь раз. Аналогичная функция есть и в BOOST'e. Посмотрев на код функции я пришел к выводу, что проще переписать её на Qt, чем заставлять людей тащить с собой BOOST. С другой стороны моя реализация получилась в 2 раза быстрей BOOST'овской, но медленней std::call_once. Связано это со скудными возможностями класса QAtomicInt, там где я бы мог обойтись быстрыми атомарными операциями загрузки (load) и сохранения (store), мне пришлось импровизировать и использовать более медленные атомарные методы (fetchAndStoreAcquire, fetchAndStoreRelease).

call_once.h

#ifndef CALL_ONCE_H
#define CALL_ONCE_H

#include <QtCore/QtGlobal>
#include <QtCore/QAtomicInt>
#include <QtCore/QMutex>
#include <QtCore/QWaitCondition>
#include <QtCore/QThreadStorage>
#include <QtCore/QThread>

namespace CallOnce {
    enum ECallOnce {
        CO_Request,
        CO_InProgress,
        CO_Finished
    };

    Q_GLOBAL_STATIC(QThreadStorage<QAtomicInt*>, once_flag)
}

template <class Function>
        inline static void qCallOnce(Function func, QBasicAtomicInt& flag)
{
    using namespace CallOnce;
    int protectFlag = flag.fetchAndStoreAcquire((int)flag);
    if (protectFlag == CO_Finished)
        return;
    if (protectFlag == CO_Request && flag.testAndSetRelaxed(protectFlag,
                                                            CO_InProgress)) {
        func();
        flag.fetchAndStoreRelease(CO_Finished);
    }
    else {
        do {
            QThread::yieldCurrentThread();
        }
        while (!flag.testAndSetAcquire(CO_Finished, CO_Finished));
    }
}

template <class Function>
        inline static void qCallOncePerThread(Function func)
{
    using namespace CallOnce;
    if (!once_flag()->hasLocalData()) {
        once_flag()->setLocalData(new QAtomicInt(CallOnce::CO_Request));
        qCallOnce(func, *once_flag()->localData());
    }
}

#endif // CALL_ONCE_H

call_once_test.cpp
#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>

#include <QtCore/QTimer>

#include <QtCore/QTime>

#include <QtCore/QVector>
#include <QtCore/QThread>
#include <QtCore/QtConcurrentMap>
#include <QtCore/QtConcurrentFilter>
#include <QtCore/QCoreApplication>

#include <algorithm>

#include "call_once.h"

enum {Max = 100};

struct run_once
{
    void operator()()
    {
        qDebug() << "Functor: This only once...";
    }
};

void func_run_once()
{
    qDebug() << "Function: This only once...";
}

struct inc_functor
{
    inc_functor() : counter(0) {}
    inline int operator()() {return counter++;}
    int counter;
};

struct setPriorityFunctor
{
    setPriorityFunctor(QThread::Priority priority = QThread::NormalPriority)
        : m_priority(priority) {}
    inline void operator()()
    {
        QThread* thread = QThread::currentThread();
        thread->setPriority(m_priority);
    }
    QThread::Priority m_priority;
};

void setLowestPriorityFunction()
{
    QThread* thread = QThread::currentThread();
    thread->setPriority(QThread::LowestPriority);

    qDebug("Current thread %x. Thread set to Lowest priority",
           (quintptr)thread);
}

void setHighestPriorityFunction()
{
    QThread* thread = QThread::currentThread();
    thread->setPriority(QThread::HighestPriority);

    qDebug("Current thread %x. Thread set to Highest priority",
           (quintptr)thread);
}

int calculate(const int& num)
{
#if 0 // Test once call per thread with function
    #if 0 // Set lowest thread priority
        qCallOncePerThread(setLowestPriorityFunction);
    #else // Set highest thread priority
        qCallOncePerThread(setHighestPriorityFunction);
    #endif
#else // Test once call per thread with functor
    #if 0
        qCallOncePerThread(setPriorityFunctor(QThread::HighestPriority));
    #else
        qCallOncePerThread(setPriorityFunctor(QThread::LowestPriority));
    #endif
#endif

    return ~num;
}

static QBasicAtomicInt flag = Q_BASIC_ATOMIC_INITIALIZER(CallOnce::CO_Request);

int parityFilter(const int& num)
{
    qCallOnce(run_once(), flag);

    return num % 2 ? false : true;
}

static QBasicAtomicInt testflag = Q_BASIC_ATOMIC_INITIALIZER(CallOnce::CO_Request);

int main(int argc, char* argv[])
{
    QCoreApplication a(argc, argv);

    QTime t; t.start();
    for (int i = 0; i < 1000 * 1000 * 100; ++i)
        qCallOnce(run_once(), testflag);
    qDebug("%d ms", t.elapsed());

    QVector<int> ints;

    std::generate_n(std::back_insert_iterator<QVector<int> >(ints),
                                                (int)Max, inc_functor());

// Test qCallOnce
    {
        QVector<int> results = QtConcurrent::blockingMapped(ints, calculate);
        qDebug() << results;
    }

// Test qCallOncePerThread
    {
        QtConcurrent::blockingFilter(ints, parityFilter);
        qDebug() << ints;
    }

    return 0;
}


P.S.: функция также может пригодится для создания потоко-безопасных синглтонов.
kwisp, Litkevich Yuriy,
26.5.2010, 17:27 Секреты и интересные возможности Qt
На заметку:

Заполняем Qt контейнер без for:
#include <algorithm>

#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>
#include <QtCore/QList>

struct inc_functor
{
    inc_functor() : counter(0) {}
    inline int operator()() {return counter++;}
    int counter;
};

int main(int argc, char** argv)
{
    QList<int> testList;
    std::generate_n(std::back_insert_iterator<QList<int> >(testList),
                10, inc_functor());
    qDebug() << testList;
    return 0;
}


(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)


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

// поиск первого неактивного (Disabled) виджета через аттрибуты
struct testAttributePredicate {
    testAttributePredicate(Qt::WidgetAttribute attrib) : m_attrib(attrib) {}
    inline bool operator()(QWidget* widget) {
        return widget->testAttribute(m_attrib);
    }
    Qt::WidgetAttribute m_attrib;
};
...
{
    QWidgetList widgets = qApp->allWidgets();
    QWidgetList::iterator result =
            std::find_if(widgets.begin(), widgets.end(),
                         testAttributePredicate(Qt::WA_Disabled));
    if (result != widgets.end())
        qDebug() << (*result)->objectName();
}


Передача указателя на метод класса для QtConcurrent::mapped() вместо обычной функции:

#include <QtConcurrentMap>
#include <functional>
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QVector<int> test;
    test << 1 << 2 << 3;

    QtConcurrent::mapped(test, std::bind1st(std::mem_fun(&MainWindow::myMethod), this));
}

int MainWindow::myMethod(int i)
{
    qDebug() << i;
    return i;
}
Litkevich Yuriy,
30.4.2010, 8:28 Как получить индекс вкладки в QTabWidget?
Конечно так делать не правильно и нужно наследоваться, но если вопрос поставлен таким образом, что отвергает единственно верный вариант, то приведу пару неверных, но пока рабочих на Qt 4.6.2:

struct HackTabWidget : public QTabWidget
{
    using QTabWidget::tabBar;
};
...
HackTabWidget* hTabWidget = reinterpret_cast<HackTabWidget*>(ui->tabWidget);
hTabWidget->tabBar();


QTabBar* tabBar = ui->tabWidget->findChild<QTabBar*>("qt_tabwidget_tabbar");
molchanoviv,
24.4.2010, 11:55 Секреты и интересные возможности Qt
Администратор одного программерского форума удалил мой блог, который я вел 2 года. Там был код, который я выкладывал в постах. Никакие кэши гугла и archive.org не сохранили информацию. В общем, если вы не против, то буду тут периодически выкладывать интересные/полезные решения.
---

Добавление сигнала clicked() в QLabel средствами State Machine Framework:

    QStateMachine* machine = new QStateMachine(this);
    QState* s1 = new QState(machine);
    QMouseEventTransition* mouseTrans =
            new QMouseEventTransition(ui->label, QEvent::MouseButtonRelease, Qt::LeftButton, s1);
    QObject::connect(mouseTrans, SIGNAL(triggered()), msgBox, SLOT(show()));
    machine->setInitialState(s1);
    machine->start();



Добавление флагов в свой класс на базе QObject'a и вывод состояния флагов в консоль:

// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H

#include <QtCore/QObject>
class MyClass : public QObject
{
    Q_OBJECT
    Q_FLAGS(MyMode)

public:
    MyClass(QObject* parent = 0);

    enum MyModeFlag {
        NoOptions = 0,
        Option1 =   1L << 0,
        Option2 =   1L << 1,
        Option3 =   1L << 2,
        Option4 =   1L << 3,
        Option5 =   1L << 4
    };

    Q_DECLARE_FLAGS(MyMode, MyModeFlag)

    void setMode(MyMode m);
    inline MyMode mode() const;

private:
    MyMode m_mode;
};

Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::MyMode)

inline MyClass::MyMode MyClass::mode() const {return m_mode;}

class QDebug;
QDebug operator << (QDebug debug, MyClass::MyMode mode);

#endif // MYCLASS_H


// myclass.cpp

#include <QtCore/QDebug>
#include <QtCore/QMetaEnum>

#include "myclass.h"


MyClass::MyClass(QObject* parent)
        : QObject(parent), m_mode(MyClass::NoOptions)
{
}

void MyClass::setMode(MyMode m)
{
    m_mode = m;
}

QDebug operator << (QDebug debug, MyClass::MyMode modes)
{
    const QMetaObject& mo = MyClass::staticMetaObject;
    int index = mo.indexOfEnumerator("MyMode");
    QMetaEnum me = mo.enumerator(index);
    debug << me.valueToKeys(modes);
    return debug;
}


Результат:

"Option1|Option3|Option5"
Litkevich Yuriy,
22.4.2010, 1:14 Нажмите любую клавишу чтобы продолжить
Можно попробовать унаследоваться от QApplication и переопределить метод notify, где ловить все нажатия..
precious,
19.4.2010, 12:13 Секреты и интересные возможности Qt
Цитата(Andrewshkovskii @ 17.4.2010, 16:48) *
что делает функция этого тимплейта?

Возвращает указатель, который содержится в d_ptr переменной и приводит его к одному из приватному базовому классу. Например для QLineEdit можно получить сразу 3 приватных класса: QLineEditPrivate, QWidgetPrivate, QObjectPrivate. Нужный можно выбрать.

Цитата(Andrewshkovskii @ 17.4.2010, 16:48) *
Я так понимаю, метод и пропертя placeholderText для QLineEdit будет только в версии 4.7 ?

Да.
Andrewshkovskii,
12.4.2010, 17:59 Как сохранить экземпляр объекта QWidget в ui файле?
QtDesigner модуль. void QAbstractFormBuilder::save ( QIODevice * device, QWidget * widget ) [virtual]
maint, mva,
2.4.2010, 0:05 Секреты и интересные возможности Qt
Выложу сегодня 2 полезных "хака", которые могут пригодится при отладке приложения:

Первый хак - для доступа к приватным классам Qt:

namespace Hack { template <class To, class From> inline To* d_ptr(From* ptr){ return (To*)QObjectPrivate::get(ptr);}}


Эту функцию можно использовать например для включения функционала в QLineEdit, который пишет текст типа "введите сюда что-нибудь", когда в QLineEdit ничего нет:
#include "private/qlineedit_p.h"
...
{
    Hack::d_ptr<QLineEditPrivate>(ui->lineEdit)->placeholderText = "Test";
}


Или для установки своего виджета вместо QTableCornerButton в QTableView:

#include "private/qtableview_p.h"
...
QLabel* label = new QLabel(ui->tableWidget);
label->setText("<span style=\"color: red\">Bye</span> <span style=\"color: green\">Bye</span>, <span style=\"color: blue\">World!</span>");
label->setAlignment(Qt::AlignCenter);
QTableViewPrivate* tvPrivate = Hack::d_ptr<QTableViewPrivate>(ui->tableWidget);
tvPrivate->cornerWidget->deleteLater();
tvPrivate->cornerWidget = label;


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

struct StaticQtMetaObject : public QObject
{
    static inline const QMetaObject& get() {return staticQtMetaObject;}
};


Использовать так:

#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>
#include <QtCore/QMetaEnum>

struct StaticQtMetaObject : public QObject
{
    static inline const QMetaObject& get() {return staticQtMetaObject;}
};

int main(int argc, char *argv[])
{
    const QMetaObject& mo = StaticQtMetaObject::get();
    int index = mo.indexOfEnumerator("Key");
    QMetaEnum me = mo.enumerator(index);
    Qt::Key myKey = Qt::Key_F35;
    qDebug() << me.valueToKey(myKey);
    return 0;
}


Методы опробованы на Qt версии 4.6.2, в других версиях они могут не работать.
DaiV, Litkevich Yuriy,
13.3.2010, 1:15 Проблема со сборкой проекта в Windows
Обычно такое возникает, когда проект пытаются собрать на разных версиях mingw/gcc. Сначала всё собрали на одной версии, потом перенесли и пытаются собрать на другой. Возможно проблема в путях, 2 mingw разных версий на одной машине. Как бы там ни было пересборка с distclean должна решить проблему.
asdf,
10.3.2010, 16:04 Выделить текст в QComboBox
QLineEdit * QComboBox::lineEdit () const
void QLineEdit::selectAll () [slot]
AntonH851,
8.3.2010, 23:06 Как запустить QThread чтобы он не вешал GUI?
Цитата(DEADHUNT @ 8.3.2010, 22:57) *
это уже не запуск, а простой вызов метода. только тогда не понятно зачем QThread использовать.


Так и есть. Интересно почему тролли не поместили метод run() в protected секцию, тогда бы можно было бы его спокойно наследовать и при этом невозможно было бы его вызвать за пределами класса QThread и наследников, а только через start(). Брр, ничего не понимаю, он в protected секции. Почему-то его возможно вызвать :huh: ? Ой, кое-кто его вытащил "наружу":

class QMCToolProcessor :
    public QThread
{
    Q_OBJECT
    public:
    void setArguments ( const QStringList & );
    void setArguments ( const QString & );

    void run( );
    protected:
    QStringList arguments;
    QProcess *process;
    private slots:
    void hasStderr();
    void hasStdout();
    signals:
    void processHasStderr( QByteArray );
    void processHasStdout( QByteArray );



    void passChanged( int );
};


Вопрос к знатокам C++, возможно ли создать класс с protected членами, которым бы невозможно было бы поменять спецификатор доступа при наследовании?
Теоретически можно сделать run() чистой виртуальной функцией с private спецификатором доступа. Вот только наследование от QObject'a может не дать это сделать.
flareguner,
8.3.2010, 20:39 c++ double
Так например:

da = 123.0001;
da = int(da*1000+0.005)/1000.0


10.0 - десятые, 1 знак
100.0 - сотые, 2 знака
1000.0 - тысячные, 3 знака
...
1000000.0 - миллионные, 6 знаков после запятой

Только надо проверку какую-нибудь, чтобы int не переполнился.
mycoding,
8.3.2010, 20:17 Текст в system tray
Писал пару лет назад:

void Animate::timerEvent(QTimerEvent *event)
{
    QString text = QDateTime::currentDateTime().toString("s");
    QFont font("Tahoma");
    font.setPointSize(tray.geometry().size().height()/text.size());
    QImage image(tray.geometry().size(), QImage::Format_ARGB32);
    image.fill(0);
    QPainter painter(&image);
    painter.setFont(font);
    painter.setBrush(Qt::black);
    painter.setPen(Qt::blue);
    painter.drawText(image.rect(), Qt::AlignCenter, text);
    painter.end();

    QPixmap pix = QPixmap::fromImage(image);
    tray.setIcon(pix);
}


Думаю идея ясна.
coo_zoo,
1.3.2010, 23:34 Всплывающие окна
Проблема может только появится, если диалогов может быть несколько и они скрыты например. Зато если задать уникальное имя объекту, то промахов быть не должно:

T QObject::findChild ( const QString & name = QString() ) const


Но я не пойму как мы вообще до такого докатились? Диалоги сам по себе редко когда создаются, а это значит, что в большинстве случаев у нас есть указатель на него, который можно поместить в private секцию класса. А проверка делается легко QWidget::isVisible().
breeve,
28.2.2010, 22:53 Всплывающие окна
Не вызывай show() в main.cpp. Твой hide() выполняется в конструкторе, еще до того как ты вызовешь show() или a.exec().
breeve,
28.2.2010, 22:44 Всплывающие окна
Цитата(breeve @ 28.2.2010, 22:19) *
А у меня появляется пустое окно.


Выражайтесь яснее. Речь ведь идет о панели задач, где появляется лишний пустой прямоугольник.
breeve,

7 страниц V   1 2 3 > » 
RSS Текстовая версия Сейчас: 19.8.2017, 10:13