Qt Writing Custom Control 55-Mobile Address Book

I. Preface

In the previous several articles, the difficulty coefficient of the control is nearly 0, and there is even a suspicion of the number of controls. This time, we must have a strong control. The difficulty coefficient of this control ranks the top five among all the controls, and the amount of code is not small. The header files are 550 lines, and the implementation files are 1600 lines. Why are there so many? In fact, the control is good. When I write more complex controls, I usually divide them into functions one by one, and then think about whether the functions can be made into separate classes, which can be managed and compared. Convenient and easy to view the code. When we first got the requirement of this control, we also felt that it would not be simple. It is very convenient to use pure QWidget to realize all kinds of effects, such as sliding with qml, and it has inherent advantages. But QWidget needs to be realized by itself. The requirement is mainly five points, which can batch and add contact information (avatar + name + logo) individually. It can suspend scrollbars in sliding lists, automatically classify according to letters, provide direct and fast positioning of letters navigation bar, and click on contacts to send detailed information of corresponding contacts.

II. Functions of Realization

  • 1: Set the information set (icon + name + type + phone) and add a single contact
  • 2: Background picture + background color can be set
  • 3: You can set the list of right navigation letters + default color + highlight color
  • 4: Contact button name color + name body can be set
  • 5: Contact button type color + name body can be set
  • 6: Contact button can be set to select background color
  • 7: The style of alphabetical navigation can be set (background color + lines)
  • 8: Set the color + font size for alphabetical navigation
  • 9: Various margins + number of contacts + element spacing can be set.
  • 10:Supporting suspension scroll bar, hover time can be set
  • 11: Can set the normal color + highlight color of the suspension scroll bar
  • 12: Supports sliding, and can set sliding step speed.
  • 13: Support right-click alphabetic navigation positioning + text highlighting
  • 14: Click to send out the current contact's name + type + phone, etc.
  • 15:Contacts are arranged from small to large according to the alphabetical order of Chinese characters, with the function of transliterating Chinese characters into Pinyin.

III. EFFECT CHARACTERISTICS

Header file code

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT TelWidget : public QWidget
#else
class TelWidget : public QWidget
#endif

{
    Q_OBJECT
    Q_PROPERTY(QString names READ getNames WRITE setNames)
    Q_PROPERTY(QString types READ getTypes WRITE setTypes)
    Q_PROPERTY(QString tels READ getTels WRITE setTels)

    Q_PROPERTY(QPixmap bgImage READ getBgImage WRITE setBgImage)
    Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)

    Q_PROPERTY(int telHighFontSize READ getTelHighFontSize WRITE setTelHighFontSize)
    Q_PROPERTY(QPixmap telHighBgImage READ getTelHighBgImage WRITE setTelHighBgImage)
    Q_PROPERTY(QColor telHighBgColor READ getTelHighBgColor WRITE setTelHighBgColor)
    Q_PROPERTY(QColor telHighTextColor READ getTelHighTextColor WRITE setTelHighTextColor)

    Q_PROPERTY(QColor telBannerBgColor READ getTelBannerBgColor WRITE setTelBannerBgColor)
    Q_PROPERTY(QColor telBannerTextColor READ getTelBannerTextColor WRITE setTelBannerTextColor)
    Q_PROPERTY(QColor telBannerLineColor READ getTelBannerLineColor WRITE setTelBannerLineColor)

    Q_PROPERTY(QColor telLetterNormalColor READ getTelLetterNormalColor WRITE setTelLetterNormalColor)
    Q_PROPERTY(QColor telLetterHighColor READ getTelLetterHighColor WRITE setTelLetterHighColor)

    Q_PROPERTY(QColor telButtonBgColor READ getTelButtonBgColor WRITE setTelButtonBgColor)
    Q_PROPERTY(QColor telButtonNameColor READ getTelButtonNameColor WRITE setTelButtonNameColor)
    Q_PROPERTY(QColor telButtonTypeColor READ getTelButtonTypeColor WRITE setTelButtonTypeColor)

    Q_PROPERTY(QColor telPanelNormalColor READ getTelPanelNormalColor WRITE setTelPanelNormalColor)
    Q_PROPERTY(QColor telPanelHighColor READ getTelPanelHighColor WRITE setTelPanelHighColor)

public:
    //Contact structure
    struct TelInfo {
        QString letter;
        QString name;
        QString type;
        QString tel;
        QPixmap pixmap;

        bool operator <(const TelInfo &telInfo)const
        {
            return letter < telInfo.letter;
            //return (letter == "#") ? false : (letter < telInfo.letter);
        }

        bool operator >(const TelInfo &telInfo)const
        {
            return letter > telInfo.letter;
            //return (letter == "#") ? true : (letter > telInfo.letter);
        }
    };

    explicit TelWidget(QWidget *parent = 0);
    ~TelWidget();

protected:
    void resizeEvent(QResizeEvent *);
    void showEvent(QShowEvent *);
    void paintEvent(QPaintEvent *);

private:
    QString names;                  //Name collection
    QString types;                  //Type set
    QString tels;                   //Telephone set

    QPixmap bgImage;                //Background picture
    QColor bgColor;                 //background color

    int telHighFontSize;            //Highlight Label Font Size
    QPixmap telHighBgImage;         //Highlight Tag Background Picture
    QColor telHighBgColor;          //Background color of highlighted label
    QColor telHighTextColor;        //Highlight label text color

    QColor telBannerBgColor;        //Top letters navigate background color
    QColor telBannerTextColor;      //Top letter navigation text color
    QColor telBannerLineColor;      //Top alphabetic navigation line color

    QColor telLetterNormalColor;    //The right letter navigates the normal color
    QColor telLetterHighColor;      //Right letters navigate highlights

    QColor telButtonBgColor;        //Address Book Button Background Color
    QColor telButtonNameColor;      //Address Book Button Name Color
    QColor telButtonTypeColor;      //Address Book Button Type Color

    QColor telPanelNormalColor;     //Normal color of scrollbar
    QColor telPanelHighColor;       //Scrollbar highlight color

    int lastPosition;               //Final scrollbar position
    TelHigh *telHigh;               //Highlighted alphabetic labels
    TelBanner *telBanner;           //Top spacer letter navigation
    TelLetter *telLetter;           //Right Alphabet Label
    TelPanel *telPanel;             //Address Book Panel

    QList<QWidget *> items;         //Address Book Button Set
    QList<QWidget *> banners;       //Address Book Alphabet Segmentation Set
    QList<QPixmap> pixmaps;         //Contact Picture Collection
    QTimer *timer;                  //Hidden highlight label timer

public:
    QString getNames()              const;
    QString getTypes()              const;
    QString getTels()               const;

    QPixmap getBgImage()            const;
    QColor getBgColor()             const;

    int getTelHighFontSize()        const;
    QPixmap getTelHighBgImage()     const;
    QColor getTelHighBgColor()      const;
    QColor getTelHighTextColor()    const;

    QColor getTelBannerBgColor()    const;
    QColor getTelBannerTextColor()  const;
    QColor getTelBannerLineColor()  const;

    QColor getTelLetterNormalColor()const;
    QColor getTelLetterHighColor()  const;

    QColor getTelButtonBgColor()    const;
    QColor getTelButtonNameColor()  const;
    QColor getTelButtonTypeColor()  const;

    QColor getTelPanelNormalColor() const;
    QColor getTelPanelHighColor()   const;

    QSize sizeHint()                const;
    QSize minimumSizeHint()         const;

private slots:
    void initControl();
    void initForm();
    void btnPressed();
    void btnRelease();
    void positionChanged(int value);
    void letterClicked(const QString &letter, int letterY);

public Q_SLOTS:
    //Setting Name + Type + Telephone Collection
    void setNames(const QString &names);
    void setTypes(const QString &types);
    void setTels(const QString &tels);
    void setInfo(const QString &names, const QString &types, const QString &tels);
    void setInfo(const QStringList &names, const QStringList &types,
                 const QStringList &tels, const QList<QPixmap> &pixmaps);

    //Add a single contact
    void addInfo(const QString &name, const QString &type,
                 const QString &tel, const QPixmap &pixmap);

    //Setting Background Image + Background Color
    void setBgImage(const QPixmap &bgImage);
    void setBgColor(const QColor &bgColor);

    //Setting Highlighted Alphabet Label Related Properties
    void setTelHighFontSize(int telHighFontSize);
    void setTelHighBgImage(const QPixmap &telHighBgImage);
    void setTelHighBgColor(const QColor &telHighBgColor);
    void setTelHighTextColor(const QColor &telHighTextColor);

    //Setting Top Alphabet Navigation Related Properties
    void setTelBannerBgColor(const QColor &telBannerBgColor);
    void setTelBannerTextColor(const QColor &telBannerTextColor);
    void setTelBannerLineColor(const QColor &telBannerLineColor);

    //Setting the right-side alphabetic navigation-related properties
    void setTelLetterNormalColor(const QColor &telLetterNormalColor);
    void setTelLetterHighColor(const QColor &telLetterHighColor);

    //Setting Address Book Button Related Properties
    void setTelButtonBgColor(const QColor &telButtonBgColor);
    void setTelButtonNameColor(const QColor &telButtonNameColor);
    void setTelButtonTypeColor(const QColor &telButtonTypeColor);

    //Setting Scrollbar Related Properties
    void setTelPanelNormalColor(const QColor &telPanelNormalColor);
    void setTelPanelHighColor(const QColor &telPanelHighColor);

Q_SIGNALS:
    void telClicked(const QString &name, const QString &type, const QString &tel);
};

V. Core Code

void TelWidget::setInfo(const QStringList &names, const QStringList &types,
                        const QStringList &tels, const QList<QPixmap> &pixmaps)
{
    this->names = names.join("|");
    this->types = types.join("|");
    this->tels = tels.join("|");
    this->pixmaps = pixmaps;

    if (names.isEmpty() || types.isEmpty() || tels.isEmpty()) {
        return;
    }

    //Line identifier text set
    QList<QString> texts;
    texts << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H" << "I" << "J" << "K" << "L" << "M"
          << "N" << "O" << "P" << "Q" << "R" << "S" << "T" << "U" << "V" << "W" << "X" << "Y" << "Z" << "#";

    QList<QString> listName = names;
    QList<QString> listType = types;
    QList<QString> listTel = tels;
    QList<QPixmap> listPix = pixmaps;
    int countName = listName.count();
    int countType = listType.count();
    int countTel = listTel.count();
    int countPix = listPix.count();

    if (countName == countType && countType == countTel && countTel == countPix) {
        //Take out the corresponding initials of Chinese characters. First, sort all names according to the alphabet from small to large.
        QList<TelInfo> poundInfos, telInfos;
        for (int i = 0; i < countName; i++) {
            TelInfo telInfo;
            telInfo.name = listName.at(i);
            telInfo.type = listType.at(i);
            telInfo.tel = listTel.at(i);
            telInfo.pixmap = listPix.at(i);

            //If the initial letter is not found, it comes down to the classification.
            QString letter = ZhToPY::Instance()->zhToZM(listName.at(i).at(0));
            if (texts.contains(letter)) {
                telInfo.letter = ZhToPY::Instance()->zhToJP(listName.at(i));
                telInfos << telInfo;
            } else {
                telInfo.letter = "#";
                poundInfos << telInfo;
            }
        }

        //Sort information sets in ascending order
        qSort(telInfos.begin(), telInfos.end());

        //Append the last # category to the end
        foreach (TelInfo telInfo, poundInfos) {
            telInfos << telInfo;
        }

        //Clear all the elements first
        qDeleteAll(items);
        qDeleteAll(banners);
        items.clear();
        banners.clear();

        //Generate Phonebook Button
        for (int i = 0; i < countName; i++) {
            TelInfo telInfo = telInfos.at(i);
            TelButton *btn = new TelButton;
            connect(btn, SIGNAL(btnPressed()), this, SLOT(btnPressed()));
            connect(btn, SIGNAL(btnRelease()), this, SLOT(btnRelease()));

            //Setting alphabetic properties
            QString letter = telInfo.letter.at(0);
            btn->setProperty("letter", letter);

            //Setting Head Image + Name + Type + Telephone
            btn->setPixmap(telInfo.pixmap);
            btn->setName(telInfo.name);
            btn->setType(telInfo.type);
            btn->setTel(telInfo.tel);
            items << btn;
        }

        //Calculate the index of letters one by one
        QList<int> tempIndex;
        int textCount = texts.count();
        for (int j = 0; j < textCount; j++) {
            QString text = texts.at(j);
            int index = -1;
            for (int k = 0; k < items.count(); k++) {
                if (items.at(k)->property("letter").toString() == text) {
                    index = k;
                    break;
                }
            }

            tempIndex << index;
        }

        //Filter index, identifier index >= 0
        QList<int> indexs;
        for (int j = 0; j < textCount; j++) {
            int index = tempIndex.at(j);
            if (index >= 0) {
                TelBanner *banner = new TelBanner;
                banner->setText(texts.at(j));
                banners << banner;
                indexs << index;
            }
        }

        //Setting identifier + element set
        telPanel->setIndexs(indexs);
        telPanel->setBanners(banners);
        telPanel->setItems(items);

        //Reset the color
        setTelHighBgColor(telHighBgColor);
        setTelBannerBgColor(telBannerBgColor);
        setTelBannerTextColor(telBannerTextColor);
        setTelLetterNormalColor(telLetterNormalColor);
        setTelLetterHighColor(telLetterHighColor);
        setTelButtonNameColor(telButtonNameColor);
        setTelButtonTypeColor(telButtonTypeColor);
        setTelPanelNormalColor(telPanelNormalColor);
        setTelPanelHighColor(telPanelHighColor);
    }
}

void TelWidget::addInfo(const QString &name, const QString &type,
                        const QString &tel, const QPixmap &pixmap)
{
    names = names + "|" + name;
    types = types + "|" + type;
    tels = tels + "|" + tel;
    pixmaps.append(pixmap);
    setInfo(names.split("|"), types.split("|"), tels.split("|"), pixmaps);
}

Introduction of Control

  1. More than 150 exquisite controls, covering a variety of dashboards, progress bars, progress balls, compasses, curves, rulers, thermometers, navigation bars, navigation bars, flatui, highlighted buttons, sliding selectors, lunar calendar, etc. Far more controls than qwt integrates.
  2. Each class can be separated into a separate control, zero-coupling, each control has a header file and an implementation file, independent of other files, to facilitate the integration of a single control in the form of source code into the project, less code. The control classes of qwt are interlinked and highly coupled. If you want to use one of the controls, you must include all the code.
  3. All pure Qt writing, QWidget+QPainter drawing, support any Qt version from Qt4.6 to Qt5.13, support mingw, msvc, gcc and other compilers, support any operating system such as windows+linux+mac + embedded linux, no scrambling, can be directly integrated into Qt Creator, as with its own controls, most of the effects as long as set up. Several attributes can be used, which is very convenient.
  4. Each control has a corresponding separate DEMO containing the source code of the control, which is convenient for reference. It also provides an integrated DEMO for all controls.
  5. The source code of each control has detailed Chinese annotations, which are compiled in accordance with the unified design specifications. It is convenient to learn how to compile custom controls.
  6. Each control's default color matching and demo's corresponding color matching are very beautiful.
  7. More than 130 visible controls and 6 invisible controls.
  8. Some controls provide a variety of style choices, a variety of indicator style choices.
  9. All controls adapt to form stretching changes.
  10. Integrate custom control property designer, support drag design, WYSIWYG, support import and export xml format.
  11. With activex control demo, all controls can run directly in ie browser.
  12. Integrate fontawesome graphic fonts + hundreds of graphic fonts collected by Alibaba iconfont to enjoy the fun of graphic fonts.
  13. All controls eventually generate a dynamic library file (dll or so, etc.) that can be directly integrated into the qtcreator to drag the design to use.
  14. At present, there is a version of qml, pyqt version will be considered later, if the user demand is large.
  15. Custom Control Plug-in Open Dynamic Library (permanently free), without any backdoor and restrictions, please feel free to use.
  16. At present, 26 versions of dll have been provided, including qt5.12.3 MSVC 2017 32 + 64 MinGW 32 + 64.
  17. Increase control and improve control from time to time, update SDK from time to time. Welcome to make suggestions. Thank you!
  18. The QT introduction books recommend Huo Yafei's "Qt Creator quick start", "Qt5 Programming Introduction", and the QT advanced books recommend the official "C++ GUI Qt4 programming".
  19. I strongly recommend programmers'self-cultivation and planning series "Talking about Programmers", "Programmers' Growth Course" and "Solution Programmers". They benefit a lot and benefit a lifetime!
  20. SDK Download Link: https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ Extraction code: 877p

Tags: Mobile Qt Qt5 Linux SDK

Posted on Fri, 20 Sep 2019 08:02:14 -0700 by robert_gsfame