Просмотр сообщений
|
Страниц: [1] 2 3 ... 21
|
2
|
Qt / Вопросы новичков / Почему метод QString::count(QRegExp) не находит строки типа "(текст", "текст)"?
|
: Июль 12, 2021, 15:04
|
Добрый день. Когда-то был реализовал поиск текста по справке. Пользовался регулярными (QRegExp) выражениями: QRegExp("\\bтекст\\b") для поиска типа "только слова целиком"; QRegExp("текст") если не учитывая слова целиком. Чтобы учитывать регистр использовал метод QRegExp::setCaseSensitivity(Qt::CaseSensitivity cs). Поиск по тексту проводил методом QString::count(const QRegularExpression &re) const. На днях заметил, что текст типа "(текст" или "текст)" моя программа не находит. В то же время, текст типа "(текст)" находит. Регулярные выражения использовал лишь из-за того, чтобы можно было искать текст учитывая поиск "только слова целиком". Понимаю, что проблема в регулярном выражении. Но вот понять как правильно составить регулярное выражение для поиска всевозможного текста не могу понять. Ниже прикрепляю небольшой пример. Может кто-то уже решал подобную проблему. Буду рад любым советам. Исходники программы:FindSubstring.pro QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = FindSubstring TEMPLATE = app
SOURCES += main.cpp\ mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp #include "mainwindow.h" #include <QApplication>
int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow w; w.show();
return app.exec(); }
mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow>
namespace Ui { class MainWindow; }
class MainWindow : public QMainWindow { Q_OBJECT
public: explicit MainWindow(QWidget *parent = 0); ~MainWindow();
protected: void changeEvent(QEvent *e);
public slots: void substring_search();
private: Ui::MainWindow *ui; };
#endif // MAINWINDOW_H
mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this);
ui->source_text->setFont(QFont("Times New Roman", 12, QFont::Normal)); ui->source_text->setText("Беспилотный летательный аппарат (БЛА, БПЛА; в разговорной речи также «беспилотник» или «дрон», от англ. drone — трутень) — " "летательный аппарат без экипажа на борту." "БПЛА могут обладать разной степенью автономности — от управляемых дистанционно до полностью автоматических, а также различаться " "по конструкции, назначению и множеству других параметров. Управление БПЛА может осуществляться эпизодической подачей команд или " "непрерывно — в последнем случае БПЛА называют дистанционно-пилотируемым летательным аппаратом (ДПЛА). БПЛА могут решать разведывательные " "задачи (на сегодня это основное их предназначение), применяться для нанесения ударов по наземным и морским целям, перехвата воздушных целей, " "осуществлять постановку радиопомех, управления огнём и целеуказания, ретрансляции сообщений и данных, доставки грузов.");
QFont standart_font(QFont("Arial", 9, QFont::Normal)); ui->case_sensitive_ch->setFont(standart_font); ui->whole_words_ch->setFont(standart_font); ui->find_but->setFont(standart_font); ui->result_find_lb->setFont(standart_font); ui->find_edit->setFont(standart_font);
connect(ui->find_but, SIGNAL(clicked(bool)), this, SLOT(substring_search()));
}
MainWindow::~MainWindow() { delete ui; }
void MainWindow::changeEvent(QEvent *e) { QMainWindow::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } }
void MainWindow::substring_search() { ui->result_find_lb->setText("");
if(ui->find_edit->text() == "") { ui->result_find_lb->setText("Введите текст для поиска!"); } else { QString find_text;
if(ui->whole_words_ch->isChecked() == true) find_text = QString("\\b%1\\b").arg(ui->find_edit->text()); else find_text = QString("%1").arg(ui->find_edit->text());
QRegExp reg_find_text(find_text);
if(ui->case_sensitive_ch->isChecked() == true) reg_find_text.setCaseSensitivity(Qt::CaseSensitive); else reg_find_text.setCaseSensitivity(Qt::CaseInsensitive);
reg_find_text.setMinimal(true);
int count_find = ui->source_text->document()->toPlainText().count(reg_find_text);
if(count_find == 0) ui->result_find_lb->setText("В данном тексте нет такой подстроки."); else ui->result_find_lb->setText(QString("В данном тексте введенная вами строка " "встречается %1 раз.").arg(count_find)); } }
Скрин програмки и архив:
|
|
|
3
|
Qt / Вопросы новичков / Как заставить QTextBrowser читать значение атрибутов в величинах "pt" и "cm"?
|
: Декабрь 07, 2020, 14:13
|
Здравствуйте, господа форумчане. Усовершенствую простой браузер на основе QTextBrowser. Взял html страницу полученную из документа расширения .doc с помощью Microssoft Office Word. Заметил, что QTextBrowser не читает отступы (text-indent), которые были видны в Firefox. Присмотревшись понял, что конвектор Microssoft Office Word для большинства атрибутов тегов в html проставил значения в величинах "pt" и "cm". К примеру: <p class=MsoNormal style='text-indent:35.45pt'><a href="file4.htm">Регулярные выражения</a></p>
Заменив пару значений вручную на величины "px", я увидел что отступы отрабатывают. Решил, нужно пробежаться по html странницам, и в тегах в атрибутах преобразовать величины значений "pt" и "cm" в "px". Сначала решил использовать для этого либо QDomElement или QXmlStreamReader и QXmlStreamWriter. Но снова не вышло(. В моих html страницах в тегах все значения атрибутов, кроме тех, что в "style" не были взяты в кавычки (" или ') - как к примеру: class=MsoNormal. Из-за этого документ не читался. Решил с помощью регулярных выражений взять в кавычки значения атрибутов, и потом уже, с помощью, QDomElement заменить величины "pt" и "cm" на "px". Написал для взятия значения в кавычки следующий код: void change_html(QString page_html) { QFile file_html(page_html);
if(!file_html.open(QIODevice::ReadWrite)) { qDebug() << "File " << page_html << " not open!"; return; }
QByteArray file_data;
QRegExp reg_find_teg("<=(.*)[ ]>"); // регулярное выражение поиска значений атрибутов, // которые не в кавычках(не верное, не знаю как написать его) reg_find_teg.setMinimal(true);
file_data = file_html.readAll(); // считываю весь файл
QString text_file(file_data); // считанный текст с файла QString find_text; // найденный текст
int pos = 0; while((pos = reg_find_teg.indexIn(text_file, pos)) != -1) { find_text = reg_find_teg.cap(1); // найденный текст
text_file = text_file.replace(find_text, "\"" + find_text + "\""); // добавление кавычек с помощью // замены в основном тексте
pos += reg_find_teg.matchedLength(); }
file_html.seek(0); // перемежение в начало файла file_html.write(text_file.toUtf8()); // запись строки в файл
file_html.close(); }
Но не знаю как записать верно эту регулярку QRegExp reg_find_teg("<=(.*)[ ]>"); Может кто-то подскажет? Ну или направит меня на другое более верное решение проблемы не понимания QTextBrowser величин "pt" и "cm".
|
|
|
4
|
Qt / Вопросы новичков / Re: Как создать DelegateItem с wordWrap для QTreeWidget?
|
: Сентябрь 18, 2020, 16:01
|
Решил я вернуться к данной нерешенной задачи. Что-то никак не выходит реализовать этот QItemDelegate. (( Текст переносится по строкам, когда передвигаешь QSplitter. Но высота item в QTreeWidget остается неизменной (большая) (рис. ниже). Я так понимаю, это происходит из-за того, что я в методе sizeHint использую boundingRect, который как раз и возвращает максимальную область в которую помещается текст при максимальном переносе строк. text_size = option.fontMetrics.boundingRect(option.rect, Qt::TextWordWrap | Qt::AlignVCenter | Qt::AlignLeft, index.data().toString()).size();
Заметил, что setWidth и setHeight были лишними у меня в коде, у себя это убрал: text_size.setWidth(option.fontMetrics.boundingRect(option.rect, Qt::TextWordWrap | Qt::AlignVCenter | Qt::AlignLeft, index.data().toString()).size().width());
text_size.setHeight(option.fontMetrics.boundingRect(option.rect, Qt::TextWordWrap | Qt::AlignVCenter | Qt::AlignLeft, index.data().toString()).size().height());
Теперь догадаться бы как узнать во сколько строк влазить текст в текущий момент или текущую ширину item? Тогда можно будет как-то задать текущий размер item опираясь на уже имеющий размер text_size (с максимальным переносом строк) и размер, когда строка без переносов. Если у когото есть дельный совет, радости прошу.
|
|
|
5
|
Qt / Вопросы новичков / Re: Как в QCheckBox записать подстрочный текст?
|
: Август 13, 2020, 08:57
|
Создал я свой виджет CheckBoxHtml из виджета QCheckBox. Переопределил ему метод paintEvent(QPaintEvent *event). Решил зарисовать существующий текст цветом фона виджета, а вместо него используя QTextDocument нарисовать html документ с новым текстом. Исходники моего виджета:checkboxhtml.h#ifndef CHECKBOXHTML_H #define CHECKBOXHTML_H
#include <QCheckBox>
class CheckBoxHtml : public QCheckBox { Q_OBJECT
protected: void paintEvent(QPaintEvent *event);
public: CheckBoxHtml(QWidget *parent = 0); }; #endif
checkboxhtml.cpp#include "checkboxhtml.h" #include <QPaintEvent> #include <QTextDocument> #include <QPainter> #include <QStyle>
CheckBoxHtml::CheckBoxHtml(QWidget *parent) : QCheckBox(parent) {
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); setMinimumSize(1, 1);
setText("CheckBox"); }
void CheckBoxHtml::paintEvent(QPaintEvent *event) { QCheckBox::paintEvent(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true);
QFontMetrics font_metr = fontMetrics(); QRect rect_text; QRect rect_erase; QSize text_size = style()->itemTextRect(font_metr, QRect(), Qt::TextShowMnemonic, false, text()).size();
QSize icon_size_delta = QSize(iconSize().width(), iconSize().height());
if(layoutDirection() == Qt::LeftToRight) { rect_erase = QRect(icon_size_delta.width(), (rect().height()/2) - (text_size.height()/2), rect().width() - icon_size_delta.width(), text_size.height()) ; } else { rect_erase = QRect(0, (rect().height()/2) - (text_size.height()/2), rect().width() - icon_size_delta.width(), text_size.height()); }
QColor background_color = this->palette().background().color(); QBrush background_brush = this->palette().background(); painter.setPen(background_color); painter.setBrush(background_brush); painter.drawRect(rect_erase);
QTextDocument textDoc; textDoc.setDefaultFont(this->font()); textDoc.setDefaultStyleSheet("html {color: black; background-color: yellow;}"); textDoc.setHtml("<html>" + this->text() + "</html>");
if(layoutDirection() == Qt::LeftToRight) { rect_text = QRect(icon_size_delta.width(), (rect().height()/2) - (textDoc.size().height()/2), textDoc.size().width(), textDoc.size().height()); } else { rect_text = QRect(rect().width() - icon_size_delta.width() - textDoc.size().width(), (rect().height()/2) - (textDoc.size().height()/2), textDoc.size().width(), textDoc.size().height()); }
painter.translate(rect_text.x(), rect_text.y()); textDoc.drawContents(&painter); painter.end(); }
Создал новый проект ExampleCheckBox и добавил на форму свой виджет CheckBoxHtml, и взял его в QGridLayout. Задал в дизайнере размер окна 124 x 40, имя для виджета check_box_html, шрифт для check_box_html 12 Times New Roman жирный, а также его текст : "A = A<sub>1</sub> + A<sub>2</sub>". Проект прикреплю ниже. Но теперь я столкнулся со следующей проблемой:1. Как узнать позицию текста? Решил использовать для этого размер иконки (iconSize()). Но к сожалению, если в стилях задать для QCheckBox новый размер индикатора: setStyleSheet("QCheckBox::indicator {width: 30px; height: 30px;}");
то iconSize() возвращает другой размер (тот, что задан в дизайнере по-умолчанию 16x16, или тот, который может быть задан через setIconSize(QSize) и в моем виджете текст наезжает на иконку). Ниже также прикреплю рисунок. Пока заметил только эту проблему. Есть ли у кого-то соображения как избавится от данной проблемы. Может кто-то посоветует, как улучшить мой виджет.
|
|
|
9
|
Qt / Вопросы новичков / Как в QCheckBox записать подстрочный текст?
|
: Июль 31, 2020, 11:20
|
Здравствуйте, господа форумчане.
Ранее когда мне нужно было в QLabel написать подстрочный текст, я использовал тег <sub></sub>. К примеру: T<sub>A</sub>. В результате получал в программе: TA.
Теперь пришло время, когда мне подобное нужно отображать в QCheckBox. Увы здесь оно не работает, так как QCheckBox походу не понимает html тегов.
Есть ли способ все же заставить QCheckBox отображать подстрочный текст?
|
|
|
10
|
Qt / Вопросы новичков / Re: Как создать DelegateItem с wordWrap для QTreeWidget?
|
: Июль 28, 2020, 13:47
|
Что еще нужно дописать в DelegeteItem, чтобы при изменении ширины QTreeWidget менялась и высота для каждого QTreeWidgetItem?
Посмотрите setUniformRowHeights(false) Задал я это свойство для QTreeWidget, но ничего не изменилось. Думаю мне нужно в классе DelegateItem дописать какой-то метод, чтобы в метод paint option.rect попадал с измененной высотой. А то выходит, что option.rect.width меняется, а option.rect.height всегда постоянный для конкретного Itema, и походу эта высота максимальная (тоесть как буд-то у нас QTreeWidget зжат до минимальной ширины). Но пока не могу понять, куда мне дальше двигаться.
|
|
|
12
|
Qt / Вопросы новичков / Как создать DelegateItem с wordWrap для QTreeWidget?
|
: Июль 27, 2020, 16:17
|
Здравствуйте, господа форумчане. Задался тут я вопросом: Как в QTreeWidget для QTreeWidgetItem сделать перенос строки (wordWrap). QTreeWidget имеет свойство wordWrap, но оно просто добавляет три точки, а не переносит саму строку. Посмотрев в инете, нашел совет писать свой DelegateItem. Порывшись по примерам, что-то удалось написать. Создал форму QMaiWindow. На форму положил QWidget и QTextBrowser. Взял эти два компонента под горизонтальный сплитер. Далее на QWidget добавил QLabel и QTreeWidget, взял их в QGridLayout. Создал свой класс DelegateItem. Вот код, а то словами долго описывать придется: файл main.cpp#include "mainwindow.h" #include <QApplication>
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show();
return a.exec(); }
файл mainwindow.h#ifndef MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow>
namespace Ui { class MainWindow; }
class MainWindow : public QMainWindow { Q_OBJECT
public: explicit MainWindow(QWidget *parent = 0); ~MainWindow();
private: Ui::MainWindow *ui; };
#endif // MAINWINDOW_H
файл mainwindow.cpp#include "mainwindow.h" #include "ui_mainwindow.h" #include "delegateitem.h" #include <QStyleFactory>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this);
DelegateItem * delegate = new DelegateItem; ui->treeWidget->setItemDelegate(delegate); ui->treeWidget->resizeColumnToContents(0); ui->treeWidget->header()->setStretchLastSection(true); ui->treeWidget->setTextElideMode(Qt::ElideNone); ui->treeWidget->setStyle(QStyleFactory::create("windows"));
QIcon page_icon; page_icon.addPixmap(QPixmap(":/icons/file.png"), QIcon::Normal, QIcon::On);
QTreeWidgetItem *item1 = new QTreeWidgetItem; item1->setFlags(item1->flags() | Qt::ItemIsEditable); item1->setIcon(0, page_icon); item1->setText(0, "1. Вступ до історії України"); ui->treeWidget->addTopLevelItem(item1);
QTreeWidgetItem *item2 = new QTreeWidgetItem; item2->setFlags(item2->flags() | Qt::ItemIsEditable); item2->setIcon(0, page_icon); item2->setText(0, "2. Стародавня історія України"); ui->treeWidget->addTopLevelItem(item2);
QTreeWidgetItem *item3 = new QTreeWidgetItem; item3->setFlags(item3->flags() | Qt::ItemIsEditable); item3->setIcon(0, page_icon); item3->setText(0, "3. Київська держава (Русь-Україна)"); ui->treeWidget->addTopLevelItem(item3);
QTreeWidgetItem *item4 = new QTreeWidgetItem; item4->setFlags(item4->flags() | Qt::ItemIsEditable); item4->setIcon(0, page_icon); item4->setText(0, "4. Галицько-Волинська держава. Монгольська навала"); ui->treeWidget->addTopLevelItem(item4);
QTreeWidgetItem *item5 = new QTreeWidgetItem; item5->setFlags(item5->flags() | Qt::ItemIsEditable); item5->setIcon(0, page_icon); item5->setText(0, "5. Литовсько-Руська держава. Українські землі у складі Великого князівства Литовського та інших держав (у другій половині ХІV – першій половині ХVІ ст.)"); ui->treeWidget->addTopLevelItem(item5);
QTreeWidgetItem *item6 = new QTreeWidgetItem; item6->setFlags(item6->flags() | Qt::ItemIsEditable); item6->setIcon(0, page_icon); item6->setText(0, "6. Українські землі у складі Речі Посполитої (друга половина ХVІ ст.)"); ui->treeWidget->addTopLevelItem(item6); }
MainWindow::~MainWindow() { delete ui; }
файл delegateitem.h#ifndef DELEGATENEW_H #define DELEGATENEW_H
#include <QItemDelegate> #include <QTreeView> #include <QResizeEvent>
class DelegateItem : public QItemDelegate { protected: void resizeEvent(QResizeEvent *resize_event);
public: DelegateItem(); QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
}; #endif // DELEGATENEW_H
файл файл delegateitem.cpp#include "delegateitem.h"
#include <QPainter> #include <QTreeView>
DelegateItem::DelegateItem() { }
QSize DelegateItem::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize text_size;
text_size = option.fontMetrics.boundingRect(option.rect, Qt::TextWordWrap | Qt::AlignVCenter | Qt::AlignLeft, index.data().toString()).size();
text_size.setWidth(option.fontMetrics.boundingRect(option.rect, Qt::TextWordWrap | Qt::AlignVCenter | Qt::AlignLeft, index.data().toString()).size().width());
text_size.setHeight(option.fontMetrics.boundingRect(option.rect, Qt::TextWordWrap | Qt::AlignVCenter | Qt::AlignLeft, index.data().toString()).size().height());
return text_size; }
void DelegateItem::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.highlight()); painter->setPen(option.palette.highlightedText().color()); } else { painter->setPen(option.palette.text().color()); }
painter->drawText(QRect(option.rect.x() + option.decorationSize.width() + 5, option.rect.y(), option.rect.width(), option.rect.height()), Qt::TextWordWrap | Qt::AlignVCenter | Qt::AlignLeft, index.data(Qt::DisplayRole).toString());
sizeHint(option, index);
if (option.state & QStyle::State_Selected) { painter->setPen(QColor(Qt::black)); } else { painter->setPen(QColor(Qt::black)); }
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)); painter->drawPixmap(option.rect.x(), option.rect.y() + (option.rect.height() - option.decorationSize.height())/2, option.decorationSize.width(), option.decorationSize.height(),icon.pixmap(option.decorationSize)); }
файл icons.qrc<RCC> <qresource prefix="/"> <file>icons/file.png</file> </qresource> </RCC>
Врезультате, перенос строки в каждом DelegateItem удалось сделать, вот только, высота строки расчитывается максимальная (тоесть при самой маленькой ширине QTreeWidget). И эта высота остается постоянной, и при изменении ширины QTreeWidget она не меняется. Что еще нужно дописать в DelegeteItem, чтобы при изменении ширины QTreeWidget менялась и высота для каждого QTreeWidgetItem?
|
|
|
15
|
Qt / Вопросы новичков / Re: Как в QVBoxLayout скрыть виджет, не меняя разтяжения остальных виджетов?
|
: Июль 24, 2020, 11:55
|
Используй spacer
Сделал я вместо QVBoxLayout QGridLayout, рядом с первой кнопкой добавил вертикальный spacer (рис. 1). В результате, ситуация обстоит лучше, но все равно, вторая кнопка на пиксель стала больше (рис. 2 - линиями показана данная ситуация: а) до скрытия кнопки, б) - после скрытия кнопки). Как добиться, чтобы место под первый item, где находится первая кнопка в QGridLayout-е не менялся, и все кнопки не меняли своих размеров, после скрытия первой? А как быть с QVBoxLayout или с QHBoxLayout вообще не пойму. Разве, что вместо кнопки бросать в дизайнере spacer, а кнопку в коде потом добавлять. Но это как-то не серьезно.
|
|
|
|
|