crossplatform.ru

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

void*
  опции профиля:
сообщение 23.7.2008, 22:28
Сообщение #1


Программист-самоучка
***

Группа: Участник
Сообщений: 429
Регистрация: 4.6.2008
Пользователь №: 193

Спасибо сказали: 28 раз(а)




Репутация:   3  


Предлагаю в данную тему скидывать все известные вам интересные фичи и "секреты" Qt. Думаю, так можно собрать неплохую коллекцию интересных возможностей Qt, где каждый сможет найти что-нибудь интересное для себя или узнать новое. Начну сам:
1) Макрос Q_UNUSED позволяет избежать предупреждений по поводу неиспользования какой-то переменной. Пример:
void someFunc(int var) {
     Q_UNUSED(var); //тут мы избавлемся от возможного предупреждения от компилятора
}

2) Функция QString Qt::escape(const QString &plain) позволяет конвертировать в строке, задаваемую параметром plain метасимволы HTML (<, >, &) в их HTML-эквиваленты. Пример:
QString plain = "#include <QtCore>"
QString html = Qt::escape(plain);  // html == #include <QtCore>

3) Макрос Q_PROPERTY позволяет в некоторых случаях избежать приведения. Пример:
class SomeClass : public QObject {
     Q_OBJECT
     Q_PROPERTY(bool prop READ prop WRITE setProp);
private:
     bool var;
public:
     SomeClass() : var(true) { }
     bool prop() const { return var; }
     void setProp(bool newValue) { var = newValue; }
};
//а теперь, имея указатель на QObject, мы можем изменять значения переменных унаследованного класса:
SomeClass *sc = new SomeClass;
QObject *obj = sc;
obj->setProperty("prop", true); //тоже самое, что и sc->setProp(true);


to be continued...

P.S. Надеюсь тема не умрет, и каждый будет ее поддерживать своими находками :)

-----------------------
Ссылки на интересные возможности:
1) QComboBox-Изменение размера выпадающего списка
2) qmake, как обратится к текущему каталогу?

Сообщение отредактировал Litkevich Yuriy - 31.1.2009, 12:52
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
10 страниц V   1 2 3 > »   
Начать новую тему
Ответов (1 - 99)
AD
  опции профиля:
сообщение 24.7.2008, 9:29
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


P.S. Мне кажется тему можно вверху прикрепить! :)

Не знаю, возможно, это и известный факт, но мне показалось не совсем обычным такое применение функции read/write. При этом применении она становится аналогом функций Windows Api ::ReadFile/::WriteFile:

    _str strIn;
    QFile f1("nt.dat");
    f1.open(QIODevice::WriteOnly);
    f1.write( (const char *)&strIn, sizeof( strIn));
    f1.close();

    _str strOut;
    strOut.n = .0123;
    strOut.s = "test";
    strOut.y = 1;

    QFile f2("nt.dat");
    f2.open(QIODevice::ReadOnly);
    f2.read( (char *)&strOut, sizeof( strOut));
    f2.close();

В данном коде, тип _str - это пользовательский тип. В функциях read/write считываются в эту структуру данные указанного типа при преобразовании в const char*, а не в void*!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 24.7.2008, 9:36
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


void*, для 1-го пункта часто имя переменной коментируют, чтоб компиллер не ругался:
void someFunc(int /*var*/) {
     ...
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
void*
  опции профиля:
сообщение 24.7.2008, 10:09
Сообщение #4


Программист-самоучка
***

Группа: Участник
Сообщений: 429
Регистрация: 4.6.2008
Пользователь №: 193

Спасибо сказали: 28 раз(а)




Репутация:   3  


LitkevichВ Yuriy, приколупался :) лучше бы продолжил идею :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 24.7.2008, 10:16
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(AD @ 24.7.2008, 13:29) *
Не знаю, возможно, это и известный факт, но мне показалось не совсем обычным такое применение функции read/write. При этом применении она становится аналогом функций Windows Api ::ReadFile/::WriteFile:

Оно вполне обычное - сохранение буфера.
Но мне кажется, код у тебя не правильный.
Если сохранение/восстановление происходят в разных программах, или даже при разных запусках одной программы, в поле strOut.s с большой вероятностью будет мусор.

Сообщение отредактировал Tonal - 24.7.2008, 10:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 24.7.2008, 10:33
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Tonal @ 24.7.2008, 11:16) *
Оно вполне обычное - сохранение буфера.
Но мне кажется, код у тебя не правильный.
Если сохранение/восстановление происходят в разных программах, или даже при разных запусках одной программы, в поле strOut.s с большой вероятностью будет мусор.

не совсем понял почему неправильный. Но он исправно работает. Проверял на нескольких машинах! ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ЙаМайскЫйПчОЛ
  опции профиля:
сообщение 24.7.2008, 11:12
Сообщение #7


Участник
**

Группа: Участник
Сообщений: 154
Регистрация: 10.7.2008
Из: СПб
Пользователь №: 232

Спасибо сказали: 7 раз(а)




Репутация:   5  


Цитата(AD @ 24.7.2008, 10:29) *
Не знаю, возможно, это и известный факт, но мне показалось не совсем обычным такое применение функции read/write. При этом применении она становится аналогом функций Windows Api ::ReadFile/::WriteFile:

Это обычно для программирования под *nix'ы read/write можно применить для любого дескриптора, в т.ч. для дескриптора файла, а файл в *nix'ах это всё что есть и может быть в системе. )))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 24.7.2008, 11:48
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(AD @ 24.7.2008, 14:33) *
Цитата(Tonal @ 24.7.2008, 11:16) *
...в поле strOut.s с большой вероятностью будет мусор.

не совсем понял почему неправильный. Но он исправно работает. Проверял на нескольких машинах! ;)

1) Как объявлено поле _str.s? Как char* ?
2) На что указывает поле strIn.s перед сохранением (где живёт массив символов)?
3) Как ты думаешь, что именно сохраняется в файле на месте соответствующем полю _str.s?
4) Что будет находится в поле strOut.s после чтения?
5) Куда будет указывать поле strOut.s в другой программе?
Или в этой же, если выполнится например вот такой код:
char* buf = new char[10];
_str strIn;
strIn.s = buf;
f1.write( (const char *)&strIn, sizeof( strIn));
delete[] buf;
_str strOut;
f2.read( (char *)&strOut, sizeof( strOut));
cout<<strOut.s<<endl; //???


P.S. В своём первом посте, ты strOut и strIn местами не перепутал? :)
P.P.S Если я ошибся в первом предположении, и поле _str.s имеет тип строки (QString, или std::string, или ещё какой), задумайся, как он устроен, и где хранятся те символы, которые представляют строку.

Сообщение отредактировал Tonal - 24.7.2008, 11:50
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
void*
  опции профиля:
сообщение 25.7.2008, 23:26
Сообщение #9


Программист-самоучка
***

Группа: Участник
Сообщений: 429
Регистрация: 4.6.2008
Пользователь №: 193

Спасибо сказали: 28 раз(а)




Репутация:   3  


Собственно продолжение. Простенький пример того, что можно сделать с помощью Qt Style Sheets. Скомпилируйте это у себя и зацените кнопочку:
#include <QtGui>
int main(int argc, char **argv) {
    QApplication app(argc, argv);
    QPushButton btn;
    
    qApp->setStyleSheet(
          "QPushButton {"
             "border: 1px solid #000000;"
             "border-radius: 10px;"
             "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
                                               "stop: 0 #dedede, stop: 0.5 #434343, stop: 0.51 #000000, stop: 1 #656a6d);"
             "min-width: 80px;"
         "}"

         "QPushButton:pressed {"
             "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
                                               "stop: 0 #cfcccc, stop: 0.5 #333232, stop: 0.51 #000000, stop: 1 #585c5f);"
         "}"

         "QPushButton:flat {"
             "border: none; "
         "}"
         );
    btn.resize(100, 50);
    btn.show();
    return app.exec();
}

думаю вам понравится :)

Сообщение отредактировал void* - 25.7.2008, 23:27
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Петров Виталий
  опции профиля:
сообщение 18.9.2008, 8:31
Сообщение #10


Студент
*

Группа: Участник
Сообщений: 29
Регистрация: 8.1.2008
Пользователь №: 63

Спасибо сказали: 2 раз(а)




Репутация:   0  


Тоже поделюсь парой интересных моментов.

1) Если вы не используете потоки. но при этом имеется к примеру большой цикл, то интерфейс приложения может блокироваться и не перерисовывается.
Чтобы решить эту проблему можно вызывать метод QApplication::processEvents(); при каждой итерации цикла.

2) Сделать фон любого виджета прозрачным можно так:

listwidget->setFrameShape(QFrame::NoFrame);
listwidget->viewport()->setAutoFillBackground(false);

это может пригодится например, если вы пишете плазмоид для kde4 а в плазме пока нет некоторых нативных прозрачных виджетов =)))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
void*
  опции профиля:
сообщение 23.9.2008, 20:11
Сообщение #11


Программист-самоучка
***

Группа: Участник
Сообщений: 429
Регистрация: 4.6.2008
Пользователь №: 193

Спасибо сказали: 28 раз(а)




Репутация:   3  


также можно регулировать прозрачность любого окошка с помощью метода QWidget::setWindowOpacity(), который принимает в качестве параметра вещественное число, где 1.0 - полная непрозрачность, а 0.0 - полная прозрачность. Соответственно по умолчанию это значение является равным 1.0
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 26.11.2008, 17:58
Сообщение #12


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


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

1. если соединить один и тот же сигнал с одним и тем же слотом несколько раз(n), и вызвать сигнал один раз, то
слот вызовется столько раз сколько соединений с этим сигналом мы сделали(n):)....

2. если разъединить сигнал со слотом - то рушатся все соединения этого сигнала с этим слотом.

... известен ли кому нибудь метод узнать соединен ли сигнал со слотом и если соединен то сколько раз???
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 29.11.2008, 12:13
Сообщение #13


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Litkevich Yuriy, та ни ма за шо. ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 1.12.2008, 18:59
Сообщение #14


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(kwisp @ 26.11.2008, 20:58) *
... известен ли кому нибудь метод узнать соединен ли сигнал со слотом и если соединен то сколько раз???
сообщения перенес в отдельную тему: Есть ли метод, чтобы узнать соединен ли сигнал со слотом?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 8.12.2008, 16:05
Сообщение #15


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Использовать QLatin1String вместо QString где это возможно, т.к. первый быстрее.

QString - конвертирует копирует и конвертирует ASCII строку в Unicode каждый раз, когда ему передается строка в конструкторе.
QLatin1String - класс-обертка над Си строкой (char *). Строка никуда не копируется, поэтому программист должен сам следить за ней.

Имеет смысл использовать отдельно от визуальных компонентов, там где не нужна интернационализация.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
molchanoviv
  опции профиля:
сообщение 8.12.2008, 16:11
Сообщение #16


Старейший участник
****

Группа: Сомодератор
Сообщений: 597
Регистрация: 18.7.2008
Из: Саратов
Пользователь №: 238

Спасибо сказали: 41 раз(а)




Репутация:   5  


Только прирост этот будет незаметен. Так зачем этот геморой?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 8.12.2008, 16:17
Сообщение #17


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(molchanoviv @ 8.12.2008, 16:11) *
Только прирост этот будет незаметен. Так зачем этот геморой?


Это смотря какая специфика приложения. Если предположить, что есть большой QList с такими строками и строки тоже не маленькие, а в приложении используется меньшая часть списка, то зачем конвертировать весь список сразу ? И экономия процессора и памяти, все-таки Unicode не однобайтовая кодировка.

Вопрос. Как редактировать свои посты, а то опечатки вылазят :) ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 8.12.2008, 16:44
Сообщение #18


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


К теме о сигналах. Бывают случаи, когда надо испустить сигнал внутри обработчика событий, но подобное не работает, т.к. это может привести к зацикливанию и Qt блокирует такие сигналы. В метод connect можно передать дополнительный флаг Qt::QueuedConnection, что говорит Qt вызвать слот для сигнала при следующем цикле QEventLoop (т.е. после выхода из обработчика событий или метода). Такой прием обычно используется для помещения приложения в tray через кнопку minimize.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 8.12.2008, 18:01
Сообщение #19


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


В Qt есть возможность использовать системные иконки (разные для каждой ОС, определяются динамически). К сожалению в QtDesigner'e почему-то такой возможности нет и подобный метод рассчитан на ручную простановку иконок для каждого элемента. Поможет в этом метод QStyle::standardIcon(). Доступ к методу можно получить через указатель qApp->style()->standardIcon(...);

Выбор иконок не велик, но некоторые могут пригодится: http://doc.trolltech.com/main-snapshot/qst...dardPixmap-enum
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 9.12.2008, 14:31
Сообщение #20


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


В Qt можно соединять не только сигнал со слотом, но и сигнал с сигналом. Это приведет к тому, что сигнал запустит второй сигнал. При этом если первый и второй сигналы были подключены к слотам, то они тоже вызываются (естественно, если на нем что-то завязано, сигнал типа clicked() врятли кликнет на кнопку).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Admin
  опции профиля:
сообщение 9.12.2008, 15:59
Сообщение #21


Администратор
****

Группа: Администратор
Сообщений: 646
Регистрация: 9.10.2007
Из: crossplatform.ru
Пользователь №: 1

Спасибо сказали: 17 раз(а)




Репутация:   2  


Треп перенесен в тему Треп из темы Секреты и интересные возможности Qt.

Так как он всеже не изкореним в этой теме, то весь треп будет всегда переносится в ту тему...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 5.2.2009, 19:45
Сообщение #22


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


обнаружил интересное поведение в QTableView
если выделена ячейка в столбце N, то нажимая кнопки букв или цифр на клавиатуре будет осуществлятся навигация по этому столбцу.

например есть таблица:
id    RefDes    TypeName    Layer
52    C12    EMR-35V-47U(7*6.3*2.5) 47,0*35В    top
53    C17    EMR-35V-47U(7*6.3*2.5) 47,0*35В    top
54    DD2    ADM2483BRW     top
55    DD4    ADM2483BRW     top
56    FU1    MF-R017 MF-R017    top
57    FU2    MF-R017 MF-R017    top
58    FU3    MF-R017 MF-R017    top
59    R3    CR-0805 10к    top
60    R4    CR-0805 10к    top

если выделим ячейку с RefDes=C17, а затем будем нажимать кнопку "F", то выделение и фокус перейдет сначала на FU1, а при последующих нажатиях на FU2, FU3. Затем все повторится с начала.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 9.2.2009, 20:43
Сообщение #23


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Не знаю куда это отнести к секретам или интересным возможностям. Вроде и не секрет, да и не возможность. А просто любопытная информация мимо которой многие могли бы пройти. Дерево классов Qt 4.3, распечатать и повесить на стенку. В ассистенте его нет, т.к. оно в PDF формате: http://doc.trolltech.com/extras/qt43-class-chart.pdf
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Константин
  опции профиля:
сообщение 11.2.2009, 6:15
Сообщение #24


Студент
*

Группа: Участник
Сообщений: 69
Регистрация: 9.2.2009
Пользователь №: 539

Спасибо сказали: 15 раз(а)




Репутация:   1  


ну и секреты у вас :)
но всё-равно внесу свои пять копеек:

если в кастомном виджете в paintEvent используется `setOpacity(a)` для активного Q(|Style)Painter, где `a<1.0` (например, эффект плавного показа/скрытия виджета), и у виджета имеется родитель, то соседи родителя получат такой же фактор прозрачности через /* кривую */ групповую прозрачность.
чтобы этого избежать, необходимо использовать сохранение/восстановление состояния QPainter:
void MyWidget::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    painter.save();
    painter.setOpacity(this->currentOpacityValue());

    //painter.drawSomething(...);
    painter.restore();
}

вышесказанное верно для Qt < 4.5, в 4.5 групповая прозрачность забыта, как страшный сон...

Сообщение отредактировал Константин - 13.2.2009, 5:43
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Admin
  опции профиля:
сообщение 11.2.2009, 16:35
Сообщение #25


Администратор
****

Группа: Администратор
Сообщений: 646
Регистрация: 9.10.2007
Из: crossplatform.ru
Пользователь №: 1

Спасибо сказали: 17 раз(а)




Репутация:   2  


Перенес обсуждение не относящееся к данной теме в тему: QAction::activated()[signal]
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 27.2.2009, 10:08
Сообщение #26


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Еще один способ вывода отладочных сообщений для GUI приложений. Позволяет не прописывать CONFIG += console в .pro файле.
На qDebug, qWarning, QFatal будет всплывать диалог, вместо того, чтобы писаться в консоль.

MyClass::MyClass(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
#if 1 //0 - если надо выключить
    QErrorMessage *emsg = new QErrorMessage(this);
    emsg->qtHandler();
#endif
}


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
CrackedMind
  опции профиля:
сообщение 13.3.2009, 12:59
Сообщение #27


Студент
*

Группа: Участник
Сообщений: 44
Регистрация: 13.3.2009
Пользователь №: 611

Спасибо сказали: 7 раз(а)




Репутация:   0  


Вообще этого будет более чем достаточно
Цитата
QErrorMessage::qtHandler(); // т.к. статический метод
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 13.3.2009, 13:09
Сообщение #28


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(SABROG @ 27.2.2009, 10:08) *
Еще один способ вывода отладочных сообщений для GUI приложений. Позволяет не прописывать CONFIG += console в .pro файле.
На qDebug, qWarning, QFatal будет всплывать диалог, вместо того, чтобы писаться в консоль.

А еще можно перехватить весь вывод и писать его в лог-файлы, например.

QtMsgHandler qInstallMsgHandler ( QtMsgHandler handler )
В документации есть пример использования.

В проекте freeremote, я все строки добавляю в QStringListModel, что дает возможность в необходимых местах сделать просмотр лога, просто создав QListView и указав эту модель в качестве активной.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 13.3.2009, 14:49
Сообщение #29


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Добавлю метод альтернативный методу QTimer::singleShot(), чтобы выполнить слот при возврате в главный event loop, т.е. после выхода из метода.

QMetaObject::invokeMethod(this, "nashSlot", Qt::QueuedConnection);


Этот код помещает в очередь событий информацию о том, что надо вызвать наш слот. Эквивалентно emit signalName с connection type Qt::QueuedConnection.

В принципе таким методом можно и сигналы симулировать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 13.3.2009, 20:18
Сообщение #30


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Пожалуй вопрос с enum'ом сюда помещу. В общем задача - получить название перечисляемого типа по значению. Решение вопроса в стиле Qt :)

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

class Programmer : public QObject
{
    Q_OBJECT
public:
    enum Language {ASM, C, CPP, PASCAL, FORTRAN, BASIC, JAVA};
    Q_ENUMS(Language)
};

int main(int argc, char *argv[])
{
    const QMetaObject &mo = Programmer::staticMetaObject;
    int index = mo.indexOfEnumerator("Language");
    QMetaEnum me = mo.enumerator(index);
    Programmer::Language p = Programmer::CPP;
    Programmer::Language l= static_cast<Programmer::Language>(me.keyToValue("CPP"));
    qDebug() << me.valueToKey(p) << ":" << l;
    return 0;
}

#include "main.moc"
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 16.3.2009, 12:12
Сообщение #31


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Интересная особенность Qt Designer'а
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 20.3.2009, 15:02
Сообщение #32


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Немножко заморочился на тему создания и извлечения zip архивов средствами Qt. Посмотреть что из этого вышло можно тут http://vingrad.ru/blogs/sabrog/2009/03/20/...s-zip-arhivami/
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 20.3.2009, 15:12
Сообщение #33


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


SABROG, напиши, пожалуйста, тут о тех двух функциях-то! ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 20.3.2009, 15:15
Сообщение #34


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(AD @ 20.3.2009, 15:12) *
SABROG, напиши, пожалуйста, тут о тех двух функциях-то! ;)

В Qt 4.5 если классы, которые используются для поддержки Open Document Format, среди них есть классы для работы с .zip архивами. В документации о них не слова и классы по сути только для внутреннего использования. Нас интересуют классы QZipReader и QZipWriter. Чтобы можно было их использовать надо:

- в .pro файле добавить это:
INCLUDEPATH += $(QTDIR)/src/gui/text

- в хедеры прописать пути:
#include <Qt/private/qzipreader_p.h>
#include <Qt/private/qzipwriter_p.h>
#include <qzip.cpp>


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

//распаковка архивов
    QZipReader zip("file.zip"); // загружаем файл
    zip.extractAll("directory"); // извлекаем все что в нем в папку directory


С сжатием сложнее, но принцип такой:

    QZipWriter zip("file.zip"); // создаем файл
    zip.addDirectory("directory"); // добавляется пустая папка в zip архив с именем directory
    ....
//в созданную папку "directory" предыдущей командой мы добавляем файл file.ext. 
//При этом мы сами должны открыть файл file.ext через QFile, прочитать все содержимое и передать как QByteArray в эту функцию
    zip.addFile("directory/file.ext", myByteArray); 
    zip.close();


Сообщение отредактировал SABROG - 20.3.2009, 15:27
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 20.3.2009, 16:40
Сообщение #35


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


:) Да нет! Я про аналоги getenv!!!!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 20.3.2009, 17:11
Сообщение #36


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


В Qt есть недокументированные кроссплатформменные функции qgetenv() и qputenv() для получения и установки переменных окружения.

QByteArray qgetenv(const char *varName);
bool qputenv(const char *varName, const QByteArray& value);


Описаны в <QtCore/QtGlobal>

Использовать на свой страх и риск.

Сообщение отредактировал SABROG - 20.3.2009, 17:15
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 20.3.2009, 17:43
Сообщение #37


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(SABROG @ 20.3.2009, 20:11) *
В Qt есть недокументированные кроссплатформменные функции qgetenv() и qputenv()
любопытно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 20.3.2009, 22:06
Сообщение #38


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Прикрепленный файл  qconfig_myconfig.zip ( 826 байт ) Кол-во скачиваний: 588


Для тех кто помешан на обезжиривании Qt. Вместе с исходниками Qt для мобильных систем поставляется утилита QConfig, которая позволяет отключать возможности (features).



При этом утилита сама смотрит за зависимостями и отключает зависимые компоненты.
Дистрибутивы для win и *nix идут без этой утилиты. Поэтому, чтобы воспользоваться данной утилитой нам понадобится скачать общий дистрибутив Qt для всех платформ. Сделать это можно в .torrent репозитории http://dist.trolltech.com/torrents/ Качать надо это: http://dist.trolltech.com/torrents/qt-all-...5.0.zip.torrent

Сразу скажу, что у меня уже стояла Qt собранная статически, поэтому я просто зашел в папку $(QTDIR)/tools/qconfig и вбил заветные команды:
qmake
mingw32-make release


После этого я получил в папке release готовую утилиту. Я её залил сюда (3Mb): http://filebeam.com/b143c6b3d9bb05976e6ab1ea2fed7756

Далее запускаем её, не важно откуда. Появится диалог выбора файла. Надо выбрать файл $(QTDIR)/src/corelib/global/qfeatures.txt
Затем снимаем галки, которые нам не нужны и сохраняем в файл $(QTDIR)/src/corelib/global/qconfig-НАШЕИМЯ.h
Расположение и имя файла должно быть именно таким иначе он не найдется.

Затем используем не документированный для виндовых/линуксовых дистрибутивов, но существующий ключ -qconfig таким образом:
configure.exe -qconfig НАШЕИМЯ [тут идут остальные обычные параметры типа -confirm-license -static -no-exceptions и т.д.]


Дальше собираем как обычно. В аттаче я прикрепил свою конфигурацию, не уверен, что она оптимальная или правильная.

Проверил на примере /examples/widgets/calculator.
В обычном статике размер: 7,14 МБ (7 494 656 байт)
C теми же ключами но после редактирования через qconfig: 6,19 МБ (6 496 256 байт)
UPX сжал exe файл до : 2,34 МБ (2 463 232 байт)
Для сравнения обычная (shared) сборка, сумма всех файлов в папке: 13,1 МБ (13 779 036 байт)
---
Я пошел дальше в своих изысканиях и решил собрать Qt с оптимизацией по размеру. Отредактировал файл $QTDIR/mkspecs/win32-g++/qmake.conf и заменил строчку:
Цитата
QMAKE_CFLAGS_RELEASE = -O2

на
Цитата
QMAKE_CFLAGS_RELEASE = -Os

Проделал ту же операцию, что и раньше. Теперь пример calculator.exe сжатый UPX'ом весит: 1,99 МБ (2 095 104 байт)
Хоть и в ущерб скорости (оптимизация убрала выравнивание страниц), зато в пользу размера. Еще бы, есть разница 13Мб и 1,99Мб ;) ?

---
Немного погуглив нашел еще пару ключей для компилятора, которые прописал тоже в qmake.conf
Цитата
-fmerge-all-constants
-fno-default-inline
-fno-inline
-ffunction-sections
-fdata-sections
-Wl,--gc-sections

Новый рекорд: 1,86 МБ (1 951 744 байт)

Но есть побочный эффект. Простейшие примеры линкуются около минуты.


В общем экспериментируйте.

Сообщение отредактировал SABROG - 22.3.2009, 20:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 20.3.2009, 22:21
Сообщение #39


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


любопытно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 22.3.2009, 16:28
Сообщение #40


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(Litkevich Yuriy @ 20.3.2009, 22:21) *
любопытно

Обновил пост. Уже сам поражаюсь чего удалось добиться.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 22.3.2009, 17:18
Сообщение #41


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Тянет на статью в wiki. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.3.2009, 17:24
Сообщение #42


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(ViGOur @ 22.3.2009, 20:18) *
Тянет на статью в wiki.
точно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
CrackedMind
  опции профиля:
сообщение 23.3.2009, 9:25
Сообщение #43


Студент
*

Группа: Участник
Сообщений: 44
Регистрация: 13.3.2009
Пользователь №: 611

Спасибо сказали: 7 раз(а)




Репутация:   0  


Лишь одно скажу. Если конфигурировать сразу так без предварительной компиляции
Цитата
configure -qconfig нашеимя

то утилиты не будут собираться, будет требовать dist-config

Если задефайнить QT_NO_SESSION_MANAGER то опять же сборка не пройдет. По крайней мере на каком-то снэпшоте 4.5 точно так было, починили ли они это в релизе без понятия. Да и зависимости там бывают странные.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.4.2009, 18:30
Сообщение #44


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Эх, как бы всё это разгрести. Я уже несколько раз порывался. Но как только начну рисовать набумажке, что и куда, так волосы на голове начинают шевелиться.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 5.4.2009, 9:56
Сообщение #45


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Ковырялся с документацией Qt 4.6 и сделал для себя открытие:
Оказвается в Qt 4.4 был введен новый класс компоновки QFormLayout
А его презентация появилась только в 4.5. на странице описания компоновок
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
CrackedMind
  опции профиля:
сообщение 11.4.2009, 23:06
Сообщение #46


Студент
*

Группа: Участник
Сообщений: 44
Регистрация: 13.3.2009
Пользователь №: 611

Спасибо сказали: 7 раз(а)




Репутация:   0  


А кто-нибудь обратил внимание, что в 4.5 появились смарт-пойнтеры? Классы QSharedPointer & QWeakPointer.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Sokoloff
  опции профиля:
сообщение 6.5.2009, 9:47
Сообщение #47


Участник
**

Группа: Участник
Сообщений: 237
Регистрация: 1.4.2009
Из: Москва
Пользователь №: 654

Спасибо сказали: 50 раз(а)




Репутация:   11  


Обнаружил тут, что QImage умеет читать postscript файлы. Обнаружил случайно, смотрел пример из qt4/examples/widgets/imageviewer и вместо png файла кликнул на ps, и был нескозанно удивлен увидев что программа показала его.

На windows у меня не заработало (мо возможно нужно что-то доставить/настроить), но на kubunt-e 9.04 с QT 4.5.0 и ghostscript работает.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 6.5.2009, 10:06
Сообщение #48


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Sokoloff @ 6.5.2009, 13:47) *
ghostscript работает.
вот его в стандартной комплектации в виндовозе нет. Надо ставить какой-нибудь Ghostgum
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Sokoloff
  опции профиля:
сообщение 6.5.2009, 10:18
Сообщение #49


Участник
**

Группа: Участник
Сообщений: 237
Регистрация: 1.4.2009
Из: Москва
Пользователь №: 654

Спасибо сказали: 50 раз(а)




Репутация:   11  


Цитата(Litkevich Yuriy @ 6.5.2009, 11:06) *
Ghostgum

Я ставил вот это http://pages.cs.wisc.edu/~ghost/doc/GPL/gpl864.htm но результата нет.
Впрочем, мне по windows и не надо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 8.5.2009, 21:50
Сообщение #50


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Думаю никто не будет против, если я буду использовать эту тему немного не по назначению? А именно как закладки, в каком-то смысле, чтобы не потерять.
_________

В документации по сигналам и слотам есть такая фраза:

Цитата
If several slots are connected to one signal, the slots will be executed one after the other, in an arbitrary order, when the signal is emitted.


Которая дает нам понять, что один сигнал подключенный к нескольким слотам не дает гарантии того, что эти слоты будут вызываться в порадке подключения сигналов. А именно в произвольном порядке.

Изучив немного посты в mailist'e trolltech я вынесл для себя следующую мысль. На данный момент порядок вызовов слотов можно предсказать, однако разработчики не дают гарантии того, что в новых версиях библиотеки порядок вызовов не изменится. Может быть вариант, когда вызовы будут сортироваться для достижения максимальной производительности. Поэтому, если нужен строгий порядок вызовов слотов по одному сигналу можно воспользоваться этим каркасом:

class X : public QObject
{
  Q_OBJECT
  ....  
signals:
       void fooPriority1();
       void fooPriority2();
       void fooPriority3();
       void fooPriority4();
slots:
       void emitFoo();
...
};
void X::emitFoo()
{
     emit fooPriority1();
     emit fooPriority2();
     emit fooPriority3();
     emit fooPriority4();
}

_________
А это уже на память мне, если захочу вспомнить как надо инициализировать seed перед использованием qrand:

qsrand(QDateTime::currentDateTime().toTime_t());


Сообщение отредактировал SABROG - 9.5.2009, 10:02
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 20.6.2009, 15:02
Сообщение #51


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Немного про нормализацию сигнатур. Мое внимание привлекло требование о необходимости нормализовывать все сигнатуры прежде чем использовать connect при изменении исходников Qt.

Нормализация представляет собой парсинг строки, уменьшение её длинны путем удаления лишних пробельных символов. Перестановка ключевых слов для оптимизации поиска нужного сигнала или слота у QObject'a. Подобный разбор происходит каждый раз, когда мы используем connect. Макросы SIGNAL() и SLOT() не дают нам нормализованную строку, они нам дают просто строку типа:

2mysignal(QString, QString)


После нормализации (QObject::normalizeSignature()) видно, что один пробел пропал:

2mysignal(QString,QString)


И т.п. В составе Qt появилась утилита /util/normalize, она пробегается по исходникам и заменяет макросы SIGNAL()/SLOT() на нормализованные сигнатуры, что сказывается на скорости соединения сигналов и слотов. Вероятно, в программах, где идет постоянное соединение/разъединение это помогло бы немного выйграть в скорости.

P.S.: однако мне не понятно, почему тролли не изменили moc компилятор таким образом, чтобы это делалось всегда на автомате.

Сообщение отредактировал SABROG - 20.6.2009, 16:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 28.6.2009, 13:52
Сообщение #52


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Пользователи Qt, которые собирают свои приложения с помощью компилятора gcc наверняка замечали, что при компиляции их приложений используется ключ оптимизации -O2. В первую очередь это связано с тем, что сама библиотека Qt собранная с ключем оптимизации -O3 ведет себя не стабильно. Однако никто вам не запрещает иметь библиотеку Qt собранную с оптимизацией -O2, а вашу программу с оптимизацией -O3 или любой другой. Однако ключи компилятора прописаны в одном из spec файлов. К тому же не удобно каждый раз лезть в исходники Qt и что-то там менять глобально для всех приложений. Я нашел несколько иной выход, это замена ключей компилятора на свои прямо в .pro файле:

#OPTIMIZE += 0 #no optimization
#OPTIMIZE += 1 #code size, execution time
#OPTIMIZE += 2 #code size, exectuion time, performance of generated code
#OPTIMIZE += 3 #as 2 and some more
#OPTIMIZE += s #only size code optimization
OPTIMIZE += 3

CONFIG(release, debug|release){
    !isEmpty(OPTIMIZE) {
        *-g++*{
        OPT += -O
        QMAKE_CFLAGS_RELEASE ~= s,-O.,$$join(OPT,,, $${OPTIMIZE}),
        QMAKE_CXXFLAGS_RELEASE ~= s,-O.,$$join(OPT,,, $${OPTIMIZE}),
        QMAKE_OBJECTIVE_CFLAGS_RELEASE ~= s,-O.,$$join(OPT,,, $${OPTIMIZE}),
        message(Selected optimization: $${QMAKE_CFLAGS_RELEASE})
        }
    }
}


Таким образом наша программа может быть собрана с максимальной оптимизацией, нужно лишь изменить значение переменной OPTIMIZE. К тому же это может быть полезным на этапе проектирования приложения. В больших проектах release сборка может собираться десятками минут. Конечно можно собирать только debug, но случаи бывают разными. Поэтому, чтобы уменьшить время компиляции релизных сборок можно отключить для них оптимизацию совсем (OPTIMIZE += 0). Когда, по мнению автора, программа будет готова к выпуску в свет - оптимизацию можно включить обратно. И конечно никто вам не запрещает на свой страх использовать тонкую настройку под разные платформы:
OPTIMIZE += 3 -mtune=core2 -march=core2 -mmmx -msse -msse2 -msse3 -msse4 -mfpmath=sse
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.6.2009, 14:28
Сообщение #53


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


-O3 на самом деле не макисальная, а альтернативная оптимизация, и может существенно проигрывать -O2, это и в руководстве по GCC написано и по моей практике так.

Есть ещё -Os - оптимизация по размеру, жмёт основательно, я в контроллерах такую использую.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 28.6.2009, 15:04
Сообщение #54


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


0x - полная автоматизация. Ее ведь тоже можно использовать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.6.2009, 15:27
Сообщение #55


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(AD @ 28.6.2009, 19:04) *
0x
такого ключа в GCC нет.
Их всего вот: -O, -O0, -O1 -O2, -O3, -Os.

Цитата(AD @ 28.6.2009, 19:04) *
автоматизация
оптимизация :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 28.6.2009, 16:19
Сообщение #56


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Litkevich Yuriy @ 28.6.2009, 16:27) *
оптимизация :)

Опечатка! :)

Я думал, ключи gcc и studio совпадают. Значит, ошибался....
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
trdm
  опции профиля:
сообщение 28.6.2009, 16:45
Сообщение #57


Дмитрий Трошин
****

Группа: Участник
Сообщений: 575
Регистрация: 12.1.2008
Пользователь №: 68

Спасибо сказали: 21 раз(а)




Репутация:   6  


Не такая уж и опечатка, :) у человека правильно мозги повернуты :)
автоматизация в некоторых случаях дает оптимизацю :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 28.6.2009, 17:25
Сообщение #58


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(trdm @ 28.6.2009, 17:45) *
Не такая уж и опечатка, :) у человека правильно мозги повернуты :)
автоматизация в некоторых случаях дает оптимизацю :)

:) Спасибо, конечно. Но в данном, конкретном случае эти ключики могут дать только оптимизацию! Сомневаюсь, что они могут повысить автоматизированность системы! :) Потому это действительно была опечатка!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 6.7.2009, 13:39
Сообщение #59


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


__fastcall в стиле Qt. В Delphi и MSVC есть аттрибут для функций __fastcall, который позволяет вызывать функции быстрее, т.к. при передаче параметров используются регистры eax, edx и ecx. К сожалению в связи с этим есть некоторые ограничения. Параметров может быть 3 и все они должны иметь целочисленный тип (4 байта). Например:

QString QT_FASTCALL MyClass::myFunc(int par1, ushort par2, uint *par3);

Чтобы использовать макрос QT_FASTCALL нужно подключить заголовок:

#include <QtCore/QtGlobal>


Само объявление макроса выглядит так:

#if defined(__i386__) || defined(_WIN32) || defined(_WIN32_WCE)
#  if defined(Q_CC_GNU)
#if !defined(Q_CC_INTEL) && ((100*(__GNUC__ - 0) + 10*(__GNUC_MINOR__ - 0) + __GNUC_PATCHLEVEL__) >= 332)
#    define QT_FASTCALL __attribute__((regparm(3)))
#else
#    define QT_FASTCALL
#endif
#  elif defined(Q_CC_MSVC) && (_MSC_VER > 1300 || defined(Q_CC_INTEL))
#    define QT_FASTCALL __fastcall
#  else
#     define QT_FASTCALL
#  endif
#else
#  define QT_FASTCALL
#endif


Сообщение отредактировал SABROG - 6.7.2009, 14:53
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SergSh
  опции профиля:
сообщение 27.8.2009, 9:49
Сообщение #60


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 27.8.2009
Пользователь №: 1024

Спасибо сказали: 3 раз(а)




Репутация:   0  


QListView при инициализации считывает все строки для определения размеров.
На больших наборах данных это очень существенные затраты времени.

Чтобы этого не происходило достаточно воспользоваться setGridSize().

Правда у меня осталась другая проблема - предельное количество строк,
которое может отобразить QlistVIew - 134217724
Это огранечиние класса QVector. При этом объем, занимаемый приложением в памяти 520Mb.

Получил на форуме прикольный номер пользователя - килобайт 8)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 23.2.2010, 16:36
Сообщение #61


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Кроссплатформенный метод установки приоритета для приложени. Навеяно этим постом.

Вариант 1.
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qApp->thread()->setPriority(QThread::HighestPriority);
    return a.exec();
}


Вариант 2. Установка приоритета после входа в цикл событий.
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <QtCore/QMetaType>
 
Q_DECLARE_METATYPE(QThread::Priority)
class CoreApplication : public QCoreApplication
{
        Q_OBJECT;
public:
        CoreApplication(int& argc, char* argv[], QThread::Priority priority = QThread::InheritPriority)
            : QCoreApplication(argc, argv)
        {
            qRegisterMetaType<QThread::Priority>();
            connect(this, SIGNAL(priorityChanged(QThread::Priority)),
                            SLOT(changePriority(QThread::Priority)),
                            Qt::QueuedConnection);
            if (priority != QThread::InheritPriority)
                setPriority(priority);
        }
 
        inline void setPriority(QThread::Priority priority) {emit priorityChanged(priority);}
        inline QThread::Priority priority() const {return thread()->priority();}
protected slots:
        void changePriority(QThread::Priority priority)
        {
            thread()->setPriority(priority);
        }
signals:
        void priorityChanged(QThread::Priority priority);
};
 
int main(int argc, char *argv[])
{
    CoreApplication a(argc, argv, QThread::HighestPriority);
    return a.exec();
}
 
#include "main.moc"

Вариант 3. Более легковесный вариант установки приоритета после входа в цикл событий, если вместо класса Object будет какой-нибудь MainWindow.
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
 
class Object : public QObject
{
    Q_OBJECT;
public:
    Object(QObject *parent = 0) : QObject(parent) {}
    void setThreadPriority(QThread::Priority priority)
    {
        QMetaObject::invokeMethod(this, "changePriority", Qt::QueuedConnection, Q_ARG(int, static_cast<int>(priority)));
    }
protected:
    Q_INVOKABLE void changePriority(int priority)
    {
        qApp->thread()->setPriority(static_cast<QThread::Priority>(priority));
    }
};
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
        Object object;
        object.setThreadPriority(QThread::HighestPriority);
    return a.exec();
}
 
#include "main.moc"


Для Windows стоит разделять понятия "класс приоритета приложения" и "приоритет потока". Все приложения изначально получают класс приоритета NORMAL_PRIORITY_CLASS и приоритет потока THREAD_PRIORITY_NORMAL. Предположим, что мы вызываем метод QThread::setPriority(QThread::TimeCriticalPriority), чтобы выделить самый высокий приоритет. К нашему удивлению в том же TaskManager'e приоритет будет стоять "Средний". Но в Windows количество возможных приоритетов аж 31 штука. Самый высокий достигается комбинацией установки класса REALTIME_PRIORITY_CLASS и приоритета THREAD_PRIORITY_TIME_CRITICAL. В Qt нет возможности установки класса приоритета, поэтому решением может быть вызов WINAPI ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);, или установка класса через TaskManager, или установка класса приоритета в момент запуска приложения:

start /REALTIME myprogram.exe


Установка приоритета приложения для linux может не работать в некоторых ситуациях о чем сказано в документации к метод QThread::setPriority().

Сообщение отредактировал SABROG - 23.2.2010, 16:58
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.2.2010, 19:22
Сообщение #62


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Ну собственно один вариант ещё и в списке рассылке, Где создаётся пользовательское событие.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 23.2.2010, 19:39
Сообщение #63


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(SergSh @ 27.8.2009, 9:49) *
Чтобы этого не происходило достаточно воспользоваться setGridSize().


Предпочтительней для этих целей использовать метод QListView::setUniformItemSizes(true), эффект аналогичный.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 2.4.2010, 0:05
Сообщение #64


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Выложу сегодня 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, в других версиях они могут не работать.

Сообщение отредактировал SABROG - 3.4.2010, 8:28
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
loz
  опции профиля:
сообщение 11.4.2010, 8:56
Сообщение #65


Новичок


Группа: Новичок
Сообщений: 2
Регистрация: 10.4.2010
Пользователь №: 1615

Спасибо сказали: 2 раз(а)




Репутация:   0  


Думаю что в данной теме необходимо упомянуть об интересной возможности Qt - функции прямого копировани участков памяти :
void *qMemCopy(void* dest, const void* src, size_t n)

Данная функция копирует n байт из src в dest. Разумеется, вся ответственность за проверку размеров лежит на программисте.

Для примера использования могу показать приведение типов, обычными способами которое производится довольно трудоемко, а именно - мне надо было работать со строками в их битовом представлении. В Qt есть два класса - QString и QBitArray, возможности нормальной конвертации данных между ними я найти не смог, а требование к производительности кода было достаточно высоко, пришлось сделать так:
inline QString bitsToString(QBitArray& arr) {
        QString r;
        r.resize(arr.size() / 16);   // длина массива должна быть точно кратна размеру символа в UTF-16, 16 битам
        qMemCopy(r.data_ptr()->data, arr.data_ptr()->data+1, r.length()*2);   // т.к. 1 символ = 2 байта
        return(r);
};

inline QBitArray stringToBits(const QString& str) {
        QBitArray r(str.length()*16);    // 16 бит в символе
        qMemCopy(r.data_ptr()->data+1, str.constData(), str.length()*2);
        return (r);
}


И здесь еще есть инетересная особенность класса QBitArray, как вы заметили для обращения к данным в нем мы прибавляли к указателю 1, т.е. данны идут со второго байта, но почему?
А потому, что биты из QBitArray хранятся как реальные биты, но т.к. в памяти минимальная еденица хранения - байт, то что же делать с массивом например из 9 бит?
Так вот в этом первом байте как раз хранится количество используемых бит последнего байта массива. Все просто =)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 17.4.2010, 15:48
Сообщение #66


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Цитата(SABROG @ 2.4.2010, 1:05) *
Выложу сегодня 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";
}

Вот у меня 2 вопроса :
что делает функция этого тимплейта?возвращает указатель на метод приватного класса по имени метода?(с тимплейтами знаком поверхностно, и с указателями на функции практически так же)
и 2ой :
Я так понимаю, метод и пропертя placeholderText для QLineEdit будет только в версии 4.7 ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 19.4.2010, 12:13
Сообщение #67


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(Andrewshkovskii @ 17.4.2010, 16:48) *
что делает функция этого тимплейта?

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

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

Да.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 24.4.2010, 11:55
Сообщение #68


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Администратор одного программерского форума удалил мой блог, который я вел 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"


Сообщение отредактировал SABROG - 24.4.2010, 17:23
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 24.4.2010, 12:11
Сообщение #69


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Да, я тоже заметил, что удалили. Хотел инфу кое-какую почитать..и на тебе..:)А почему удалили, не сказали?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 24.4.2010, 12:11
Сообщение #70


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата( SABROG)
Администратор одного программерского форума удалил мой блог, который я вел 2 года
. Имеешь в виду свой блог на vingrade. Очень жаль. Заглядывал иногда. Они как нибудь обосновали свои действия?

З,Ы, Может и нам расширение для блогов поставить?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 24.4.2010, 15:44
Сообщение #71


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Администратор это объяснил так:

Цитата
Все блоги, которые давно не обновлялись, и те, что использовались только для SEO были удалены.


Для SEO я блог не использовал. Обновлялся он конечно не часто, но это не повод удалять полезную информацию у которой нет срока давности.

Сообщение отредактировал SABROG - 24.4.2010, 15:45
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 26.5.2010, 17:27
Сообщение #72


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


На заметку:

Заполняем 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;
}


Сообщение отредактировал SABROG - 26.5.2010, 20:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.5.2010, 19:17
Сообщение #73


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


а зачем в
struct testAttributePredicate
оператор operator()(QWidget* widget) ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 26.5.2010, 20:13
Сообщение #74


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(Litkevich Yuriy @ 26.5.2010, 20:17) *
а зачем в
struct testAttributePredicate
оператор operator()(QWidget* widget) ?


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

// приблизительное поведение (не исходный код шаблона find_if)
template<class InputIterator, class testAttributePredicate>
  InputIterator find_if ( InputIterator first, InputIterator last, testAttributePredicate obj)
  {
    for (; first!=last; first++ ) if ( obj(*first) ) break; 
// obj(*first) - вызывается перегруженный оператор (). То есть функция заранее ожидает, что я его перегружу.
    return first;
  }
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 21.6.2010, 18:23
Сообщение #75


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Реализовал установку приоритета потока в параллельном программировании.

Как многие заметили в 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.: функция также может пригодится для создания потоко-безопасных синглтонов.
Прикрепленные файлы
Прикрепленный файл  call_once.tar.gz ( 1.62 килобайт ) Кол-во скачиваний: 1066
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 21.6.2010, 18:54
Сообщение #76


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


SABROG, а с Троллями (нокией) пробовали это обсудить? Мож они включат это в свой код?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 22.6.2010, 11:19
Сообщение #77


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(kuzulis @ 21.6.2010, 19:54) *
SABROG, а с Троллями (нокией) пробовали это обсудить? Мож они включат это в свой код?

Если руки дойдут попробую сделать commit request для git'a.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 23.6.2010, 14:52
Сообщение #78


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


В старом проекте на Borland Builder C++ у меня были кнопочки со стилем csFramed. Захотелось узнать возможно ли такие сделать в Qt. Нашел флаг для свойства border в qss - groove, но как выяснислось в нем нельзя задать контрастные цвета например черный и белый. То есть задать можно один цвет на основе которого вычисляется второй. Цвета типа черный или белый не подходят, создается просто черный бордюр. Пришлось написать собственную версию:



qss

QPushButton {
/*top right bottom left (clockwise)*/
background-color: #d6d3ce;
border-width: 2px 3px 3px 2px;
border-style: solid;
border-color:
qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 white, stop:0.5 white, stop:0.51 #848284, stop:1 #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:1, stop:0 white, stop:0.33 white, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0  #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 white, stop:0.33 white, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0 #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:1, stop:0 white, stop:0.5 white, stop:0.51 #848284, stop:1 #848284);
}

QPushButton:default{
border-width: 3px 4px 4px 3px;
border-color: 
qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 white, stop:0.33 white, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0 #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:1, stop:0 white, stop:0.25 white, stop:0.26 black, stop:0.50 black, stop:0.51 black, stop:0.75 black, stop:0.76 #848284, stop:1 #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 white, stop:0.25 white, stop:0.26 black, stop:0.50 black, stop:0.51 black, stop:0.75 black, stop:0.76 #848284, stop:1 #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:1, stop:0 white, stop:0.33 white, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0  #848284);
}

QPushButton:pressed{
border-width: 3px;
border-color:
qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 #848284, stop:0.33 #848284, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0 #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:1, stop:0 white, stop:0.33 white, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0  #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 white, stop:0.33 white, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0 #848284)
qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:1, stop:0 #848284, stop:0.33 #848284, stop:0.34 black, stop:0.67 black, stop:0.68 #848284, stop:1.0  #848284);
}



Сообщение отредактировал SABROG - 23.6.2010, 18:11
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 25.6.2010, 11:57
Сообщение #79


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


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



qss

QPushButton {
font-weight: bold;
border: 1px solid black;
border-radius: 7px;
color: white;
background-color: 
qradialgradient(spread:pad, cx:0.51, cy:-1.0, radius:2, fx:0.50, fy:0.0, stop:0.53 #81beff, stop:0.54 #268fff, stop:1 #268fff);
}

QPushButton:hover {
color: qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 black, stop:0.5 white);
}

QPushButton:pressed {
padding: 3px 0px 0px 3px;
background-color:
qradialgradient(spread:pad, cx:0.51, cy:-1.0, radius:2, fx:0.50, fy:0.0, stop:0.51 #0061ff, stop:0.52 #268fff, stop:1 #268fff);
}

QPushButton:default {
border-width: 2px;
}

QPushButton:focus {
border: 4px double black;
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 1.8.2010, 11:53
Сообщение #80


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


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

К примеру:

----------------
m1
----------------
A1 > (m2)
A2
A3
----------------



отделено от темы "Создание вложенного действия QAction"

----------------
m2
----------------
A4
A5 > (m1)
A6
----------------

Выбор пунктов A1>A5 покажет на экране опять таки меню m1


---------------------------------------------------
Уточнил - не всё так радужно.


    #include <QMenu>

    QMap<QString,QAction*> map;
    const char* text=0;


    //менюшка первого уровня
    QMenu& m1=*new QMenu(this);
        text="11";        map[text]=m1.addAction(text);
        text="12";        map[text]=m1.addAction(text);
        text="13";        map[text]=m1.addAction(text);
        
    //менюшка второго уровня
    QMenu& m2=*new QMenu(this);
        text="21";        map[text]=m2.addAction(text);
        text="22";        map[text]=m2.addAction(text);
        text="23";        map[text]=m2.addAction(text);
        
    //менюшки третьего уровня
    QMenu& m3_1=*new QMenu(this);
        text="311";        map[text]=m3_1.addAction(text);
        text="312";        map[text]=m3_1.addAction(text);
        text="313";        map[text]=m3_1.addAction(text);
        text="314";        map[text]=m3_1.addAction(text);
    QMenu& m3_2=*new QMenu(this);
        text="321";        map[text]=m3_2.addAction(text);
        text="322";        map[text]=m3_2.addAction(text);
        text="323";        map[text]=m3_2.addAction(text);
    QMenu& m3_3=*new QMenu(this);
        text="331";        map[text]=m3_3.addAction(text);
        text="332";        map[text]=m3_3.addAction(text);
        text="333";        map[text]=m3_3.addAction(text);


    //связываем вложенные меню
    map["12"]->setMenu(&m2);

    map["21"]->setMenu(&m3_1);
    map["22"]->setMenu(&m3_2);
    map["23"]->setMenu(&m3_3);

    map["311"]->setMenu(&m1);
    map["311"]->setText("open m1");//откроется меню первого уровня
    
    map["312"]->setMenu(&m2);
    map["312"]->setText("open m2");//ничего не произойдёт
    
    map["313"]->setMenu(&m3_1);
    map["313"]->setText("open m3_1");//ничего не произойдёт, только подсветка прыгнет наверх
    
    map["314"]->setMenu(&m3_2);
    map["314"]->setText("open m3_2");//откроется ещё один уровень вложенности (стандартное поведение)

    //отображаем меню    
    m1.popup(cursor().pos());


1) если в в любом вложенном меню указать меню первого уровня в качестве вложенного далее, то выбор этого пункта закроет все подменю и покажет только меню первого уровня

2) если так же указать одно из промежуточных подменю, то ничего не произойдёт

3) если так же указать самого себя в качестве подменю, то просто переоткроется (визуально ничего не произойдёт, кроме того, что подсветка в текущеи открытом подменю прыгнет наверх)

4) если так же указать не учавствовавшее в цепочке подменю, оно просто откроется как вложенное

Сообщение отредактировал Алексей1153 - 1.8.2010, 18:48
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 20.8.2010, 18:25
Сообщение #81


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Заметил интересную особенность при сериализации списка своих данных через оператор QDataStream в QSettings. Дело в том, что в принципе QDataStream умеет сериализовать QList, но для типа, который будет содержать контейнер нужно определять свои операторы <</>>. Предположим мы это сделали. Но при попытке сохранить список в QSettings мы получим ошибку, что тип не зарегестрирован как мета-тип:

error: ‘qt_metatype_id’ is not a member of ‘QMetaTypeId<QList<MyStruct> >’


Значит, чтобы поместить наш контейнер в QVariant надо еще прописать такую инструкцию:

Q_DECLARE_METATYPE(QList<MyStruct>)


Но и этого не достаточно. При запуске приложения мы получим ошибку:

QVariant::load: unable to load type 260.
QVariant::save: unable to save type 260.


Надо вызвать еще функцию:

qRegisterMetaTypeStreamOperators<QList<MyStruct> >("QList<MyStruct>");


Причем главное не напортачить с текстовым именем, оно должно точно совпадать с именем типа.

В итоге, чтобы поместить список с нашими данными, предположим, в .ini файл (QSettings) нужно прописать такое:

struct MyStruct
{
    QString name;
    qint32 key;
};

Q_DECLARE_METATYPE(MyStruct)
Q_DECLARE_METATYPE(QList<MyStruct>)

QDataStream& operator<<(QDataStream& ostream, const MyStruct& ms)
{
    ostream << ms.name << ms.key;
    return ostream;
}

QDataStream& operator>>(QDataStream& istream, MyStruct& ms)
{
    istream >> ms.name >> ms.key
    return istream;
}

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

    QSettings qsettings("settings.ini", QSettings::IniFormat);
    qRegisterMetaTypeStreamOperators<MyStruct>("MyStruct");
    qRegisterMetaTypeStreamOperators<QList<MyStruct> >("QList<MyStruct>");

    QList<MyStruct> msList;
    MyStruct ms = {"MyStruct name", 123};
    msList << ms;
    qsettings.setValue("ListMyStruct", qVariantFromValue(msList));
    return 0;
}


Обратите внимание, там где вызывается второй раз qRegisterMetaTypeStreamOperators обычно предполагается, что вы где-то реализовали операторы
для сериализации этого типа, но у нас эти операторы реализованы только для MyStruct. Дело в том, что Qt сама реализовала эти операторы для класса QList, нам лишь нужно сообщить какого типа данные он будет содержать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_xls_*
сообщение 31.8.2010, 11:31
Сообщение #82





Гости








    


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

К сожалению классы, у которых ##Private член не объявлен в *_p.h заголовочнике не позволяют сделать такой фокус.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 1.9.2010, 8:21
Сообщение #83


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(Гость_xls_* @ 31.8.2010, 12:31) *
К сожалению классы, у которых ##Private член не объявлен в *_p.h заголовочнике не позволяют сделать такой фокус.

А конкретный пример можно?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_xls_*
сообщение 2.9.2010, 9:08
Сообщение #84





Гости








    


Цитата(SABROG @ 1.9.2010, 8:21) *
Цитата(Гость_xls_* @ 31.8.2010, 12:31) *
К сожалению классы, у которых ##Private член не объявлен в *_p.h заголовочнике не позволяют сделать такой фокус.

А конкретный пример можно?

QTabWidgetPrivate из QTabWidget
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 5.9.2010, 18:55
Сообщение #85


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(xls @ 2.9.2010, 10:08) *
QTabWidgetPrivate из QTabWidget

Через include можно подключить и .cpp файл, в надежде на то, что он удачно скомпилиться, что иногда бывает, умный оптимизатор выкинет код, который не используется.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
xls
  опции профиля:
сообщение 6.9.2010, 9:27
Сообщение #86


Студент
*

Группа: Участник
Сообщений: 44
Регистрация: 6.9.2010
Пользователь №: 2013

Спасибо сказали: 7 раз(а)




Репутация:   2  


Цитата(SABROG @ 5.9.2010, 18:55) *
Через include можно подключить и .cpp файл, в надежде на то, что он удачно скомпилиться, что иногда бывает, умный оптимизатор выкинет код, который не используется.

Это будет не неиспользуемый, а дважды используемый код - один раз из моего cpp и второй из qt библиотеки - с соответствующим сообщением линковщика. ИМХО, лучше QObject::findChildren ничего еще не придумали.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 7.9.2010, 8:43
Сообщение #87


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(xls @ 6.9.2010, 10:27) *
ИМХО, лучше QObject::findChildren ничего еще не придумали.

findChildren() не работает, если у объекта нет родителя, да и не все D-Pointer'ы - QObject'ы или имеют имена.

Я считаю, что Вы наткнулись скорее на исключение из правил. Думаю это не стандартная практика объявлять классы в .cpp файлах.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_xls_*_*
сообщение 13.11.2010, 12:35
Сообщение #88





Гости








    


Цитата(SABROG @ 7.9.2010, 8:43) *
Цитата(xls @ 6.9.2010, 10:27) *
ИМХО, лучше QObject::findChildren ничего еще не придумали.

findChildren() не работает, если у объекта нет родителя, да и не все D-Pointer'ы - QObject'ы или имеют имена.

Я считаю, что Вы наткнулись скорее на исключение из правил. Думаю это не стандартная практика объявлять классы в .cpp файлах.

А вот что пишут по этому поводу тролли:
//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists for the convenience
// of qsql*model.h .  This header file may change from version to version
// without notice, or even be removed.
//
// We mean it.
//
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 13.11.2010, 13:15
Сообщение #89


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(SABROG @ 7.9.2010, 8:43) *
Думаю это не стандартная практика объявлять классы в .cpp файлах.

почему же?
вполне нормально об этом Саттер и Элджер в частности пишут.
используется при создании фабрик обЪектов с использованием NVI - невиртуального интерфейса.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Yuriy_*
сообщение 20.12.2010, 14:57
Сообщение #90





Гости








    


[quote name='Litkevich Yuriy' date='5.2.2009, 19:45' post='14041']
обнаружил интересное поведение в QTableView
если выделена ячейка в столбце N, то нажимая кнопки букв или цифр на клавиатуре будет осуществлятся навигация по этому столбцу


Здравствуйте! В QListWidget тоже присутствует такое поведение, при нажатии на букву, список перемещаеться на заглавную (нажатую) букву.
Вот, так может знает кто возможность отключения такого поведения , по причине , что при этом нету реакции на keyPressEvent(QKeyEvent *pe) . Реагирует только на кнопки Ф1 - Ф 12 , шифт, таб, и т.п
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 18.1.2011, 20:11
Сообщение #91


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Понадобилось отследить изменения в файле, который находится в шаре на удаленном компьютере. К сожалению, QFileSystemWatcher может отслеживать только файлы и директории находящиеся на жестком диске. Но есть недокументированная возможность использовать опрос (polling), который можно включить таким образом:

    QFileSystemWatcher watcher;
    watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_poller"));
    watcher.addPath(....);


На самом деле то, что идет до слова "poller", Qt особо не важно, главное, чтобы позиция слова в тексте совпадала.

Вы можете проголосовать, чтобы эту возможность включили в будущие дистрибутивы официально: тут
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 20.1.2011, 15:00
Сообщение #92


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Если вы пишите плагины для QtDesigner и хотите что бы на форме виджет не просто отрисовывался, а вел себя как настоящий виджет, присвойте ему имя вида
comboBox->setObjectName("__qt__passive_xxx");
, где xxx - это любая строка. Для эксперимента, киньте на форму комбобокс, добавьте в него пару итемов, после чего задайте имя в формате описанном выше. Посмотрите как изменилось поведение виджета.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.1.2011, 22:05
Сообщение #93


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(igor_bogomolov @ 20.1.2011, 17:00) *
Посмотрите как изменилось поведение виджета.

прикольно, но только после этого виджет не даёт редактировать свои свойства (помогает только откат действия)


Кстати, что я сюда зашёл то. Как раз тоже про комбобокс:
В поисках удобного выпадающего списка без прочих довесков, причём закрывающегося после потери фокуса или после выбора элемента, обнаружил следующее:

если создать комбобокс, но не показывать его (то есть он всегда hide() ), то, однако, список прекрасно вываливается методом showPopUp
Выбранный индекс берётся из сигнала currentIndexChanged.

перед выводом списка на экран, перед скрытием (hidePopup), очисткой или изменением элементов списка сигнал нужно отсоединять, чтобы не было ложных срабатываний выбора. Подключать же сигнал нужно сразу после метода showPopup


Появляется список под прямоугольником основного окна комбы, то есть так, как буд-то это окно было бы видимо. Если задать высоту комбы 0 (через setGeometry) , то верх списка будет совпадать с верхом комбы

Собственно, искомые мной свойства - закрывается по ESC или при потере фокуса
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 25.1.2011, 22:15
Сообщение #94


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


В Wiki, на Developer Network нашел интересный вариант размещения окна по центру:

#include <QtGui/QStyle>
#include <QtGui/QDesktopWidget>
... 
window->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, window->size(), qApp->desktop()->availableGeometry()));
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
aliks-os
  опции профиля:
сообщение 6.3.2011, 21:24
Сообщение #95


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 7.4.2010
Пользователь №: 1603

Спасибо сказали: 0 раз(а)




Репутация:   0  


Уважаемый Sabrog,
вы показали как записывать в ini - qsettings.setValue("ListMyStruct", qVariantFromValue(msList));. Был бы вам очень признателен, если бы вы в ваш пример добавили как считать записанные данные из ini файл, а то что то не особо получается...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 6.3.2011, 21:30
Сообщение #96


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(aliks-os @ 6.3.2011, 23:24) *
а то что то не особо получается...
приведи код того как делаешь, но создав отдельную тему (что бы эту не засорять, она у нас как копилка)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Day
  опции профиля:
сообщение 26.3.2012, 11:48
Сообщение #97


Новичок


Группа: Новичок
Сообщений: 5
Регистрация: 26.3.2012
Пользователь №: 3287

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Петров Виталий @ 18.9.2008, 8:31) *
Чтобы решить эту проблему можно вызывать метод QApplication::processEvents(); при каждой итерации цикла.
посмотрел этот метод у Макса Шлее. Нашел целых 2:
processEvents стр.602
processEvent стр.591
Видимо, последнее - опечатка? (в хедере не нашел)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 18.2.2013, 8:14
Сообщение #98


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Обсуждение вынес в отдельную тему: Работа с QSplitter в QtCreator
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PUMA
  опции профиля:
сообщение 30.4.2015, 1:30
Сообщение #99


Новичок


Группа: Новичок
Сообщений: 2
Регистрация: 30.4.2015
Пользователь №: 4373

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(SABROG @ 13.3.2009, 14:49) *
Добавлю метод альтернативный методу QTimer::singleShot(), чтобы выполнить слот при возврате в главный event loop, т.е. после выхода из метода.

QMetaObject::invokeMethod(this, "nashSlot", Qt::QueuedConnection);


Этот код помещает в очередь событий информацию о том, что надо вызвать наш слот. Эквивалентно emit signalName с connection type Qt::QueuedConnection.

В принципе таким методом можно и сигналы симулировать.


:) А есть способ убить слот, который стоит в очереди, но еще не выполнен? А посмотреть содержимое очереди?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 7.5.2015, 11:53
Сообщение #100


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(PUMA @ 30.4.2015, 3:30) *
А есть способ убить слот, который стоит в очереди, но еще не выполнен? А посмотреть содержимое очереди?
простого вроде - нет.

Покопайся в файлах moc_***.cpp (которые генерит MOC), как я помню, там простой массив указателей, который обходится разом.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

10 страниц V   1 2 3 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 9.4.2025, 22:37