Skip to content

General and Desktop

This is where all the desktop OS and general Qt questions belong.
83.6k Topics 457.7k Posts
  • Casting a custom class to QVariant (2020 but still relevant)

    Solved
    17
    0 Votes
    17 Posts
    3k Views
    D
    @mrjj Thanks! Clearly that was a dead end. I think I understand what Christian-Ehrlicher was telling me.
  • QMainWindow::createPopupMenu() shuffles when a menu is checked

    Unsolved
    6
    0 Votes
    6 Posts
    509 Views
    Christian EhrlicherC
    @Kita said in QMainWindow::createPopupMenu() shuffles when a menu is checked: do { if (!pMenu) break; QList<QAction*> liActions = pMenu->actions(); APopupMenu *pNewMenu = new APopupMenu(liActions, this); pMenu = pNewMenu; } while (false); What should this do? It runs exactly once, same for other really strang do .. while(false) loops. We need a fully compilable example to reproduce it on our system.
  • Calendar popup size

    Unsolved
    1
    0 Votes
    1 Posts
    387 Views
    No one has replied
  • Button not collinear with QGroupBox

    Unsolved stackedwidget qgroupbox qpushbutton sizepolicy
    4
    0 Votes
    4 Posts
    1k Views
    Pl45m4P
    @TUStudi Try a cascading horizontal + vertical layout for your page. Could be an issue with the stretch of the last column, where your green button lives or the QGridLayout in general. Edit: Yeah, that's probably it. Gridlayouts can have "empty" cells... Your two groupBoxes with your options take two cells above the button, which takes one, but expands to full size. As soon as you hide the content (grpBox 2nd opt) of second column, the gridLayout only has three rows (grpBx radio, grpBx first, green btn), but the QGridLayout won't delete its second column, but will leave it just empty and this takes some (little) space. Probably exact that amount of space, the green button expands to the right (aligning to the outter border of your grid). So try horizontal + vertical layouts or check, if there really is some empty cell (which should be, since you don't take the widget but just hide it). QGridLayout::columnCount() should return (at least) 2 when your app is in "small" mode (and also 2 or 3 when you switch to "big")
  • inet_pton 443: error: 'inet_pton' was not declared in this scope

    Unsolved windows 10 network
    17
    0 Votes
    17 Posts
    10k Views
    I
    @Christian-Ehrlicher Thanks dear. I will use this
  • Properly encrypt/decrypt data with Blowfish using crypto++ lib

    Unsolved
    2
    0 Votes
    2 Posts
    328 Views
    jsulmJ
    @DSpider Is this what you are looking for: https://www.cryptopp.com/wiki/Blowfish ?
  • How to reduce the time cost of QImage::save() ?

    Unsolved
    9
    0 Votes
    9 Posts
    2k Views
    mrjjM
    Hi I would also check out using a RAMDISk to write on if you have memory for it. Write speed is around 6000 MB/s so it's much faster than an HDD. https://sourceforge.net/projects/imdisk-toolkit/ But if file is only 100 kb, then it seems like as mentioned by the others, its indeed the compression that takes time. As even a HHD can write 100 kb fast :)
  • QSharedMemory, update signal?

    Unsolved
    8
    0 Votes
    8 Posts
    1k Views
    SPlattenS
    @jsulm , what I mean is a memory map is created where the size and purpose of the map is clearly defined, the map would contain various data types but offset 0 would always point to the start of the map. I've used exactly this system and design when sharing memory on a VME bus between industrial PLC's and VME PC's sharing the same rack space. The map is documented and both sides know exactly what is where, when a change occurs the offset is relative to position 0. There are various methods the applications can use to identify what the offsets mean but it could be that the offset if used correctly can be used to get a structure pointer to any position in the map.
  • OpenCV build problem

    Solved
    3
    0 Votes
    3 Posts
    359 Views
    H
    Hi, In facts the problem solved itself for no reason (maybe because I restarted the computer). Thanks for your help !
  • Which version of QT supports TLS1.2

    Solved
    10
    0 Votes
    10 Posts
    3k Views
    D
    @Christian-Ehrlicher Thank you , Now, I don’t know what causes sslContext->ctx to be NULL, or how to debug this problem? code of printing OpenSSL version is as follows: qDebug() << QSslSocket::supportsSsl() << QSslSocket::sslLibraryVersionNumber() << QSslSocket::sslLibraryVersionString(); log of outputing OpenSSL version : 20-10-21 18:48:39 Debug(main.cpp | 96): true 268443839 "OpenSSL 1.0.2k 26 Jan 2017" My code error log is as follows : 20-10-16 15:22:48 Pivotal(csocket.cpp | 407): connect to "187.72.72.78" 20-10-16 15:22:48 Debug(sslhelper.cpp | 124): socket Mode Change: 1 20-10-16 15:22:48 Error(csocket.cpp | 1530): sslsocket error: QAbstractSocket::SocketError( 21 ) "Error creating SSL context ()" 20-10-16 15:22:48 Error(chttpclient.cpp | 1271): http client error: 1021 "Error creating SSL context ()" I checked the source code of Q5.3.2 and found that there is a constant “case QSsl::TlsV1_2” judgment. The error message "Error creating SSL context (%1)" appears in the code below, and sslContext->ctx is NULL. QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) { QSslContext *sslContext = new QSslContext(); sslContext->sslConfiguration = configuration; sslContext->errorCode = QSslError::NoError; bool client = (mode == QSslSocket::SslClientMode); bool reinitialized = false; init_context: switch (sslContext->sslConfiguration.protocol()) { case QSsl::SslV2: #ifndef OPENSSL_NO_SSL2 sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method()); #else sslContext->ctx = 0; // SSL 2 not supported by the system, but chosen deliberately -> error #endif break; case QSsl::SslV3: sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); break; case QSsl::SecureProtocols: // SslV2 will be disabled below case QSsl::TlsV1SslV3: // SslV2 will be disabled below case QSsl::AnyProtocol: default: sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); break; case QSsl::TlsV1_0: sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method()); break; case QSsl::TlsV1_1: #if OPENSSL_VERSION_NUMBER >= 0x10001000L sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method()); #else sslContext->ctx = 0; // TLS 1.1 not supported by the system, but chosen deliberately -> error #endif break; case QSsl::TlsV1_2: #if OPENSSL_VERSION_NUMBER >= 0x10001000L sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method()); #else sslContext->ctx = 0; // TLS 1.2 not supported by the system, but chosen deliberately -> error #endif break; } if (!sslContext->ctx) { // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them // by re-initializing the library. if (!reinitialized) { reinitialized = true; if (q_SSL_library_init() == 1) goto init_context; } sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } // Enable bug workarounds. long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions); q_SSL_CTX_set_options(sslContext->ctx, options); #if OPENSSL_VERSION_NUMBER >= 0x10000000L // Tell OpenSSL to release memory early // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html if (q_SSLeay() >= 0x10000000L) q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS); #endif // Initialize ciphers QByteArray cipherString; int first = true; QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers(); if (ciphers.isEmpty()) ciphers = QSslSocketPrivate::defaultCiphers(); foreach (const QSslCipher &cipher, ciphers) { if (first) first = false; else cipherString.append(':'); cipherString.append(cipher.name().toLatin1()); } if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) { sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } // Add all our CAs to this store. foreach (const QSslCertificate &caCertificate, sslContext->sslConfiguration.caCertificates()) { // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html: // // If several CA certificates matching the name, key identifier, and // serial number condition are available, only the first one will be // examined. This may lead to unexpected results if the same CA // certificate is available with different expiration dates. If a // ``certificate expired'' verification error occurs, no other // certificate will be searched. Make sure to not have expired // certificates mixed with valid ones. // // See also: QSslSocketBackendPrivate::verify() if (caCertificate.expiryDate() >= QDateTime::currentDateTime()) { q_X509_STORE_add_cert(sslContext->ctx->cert_store, (X509 *)caCertificate.handle()); } } if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) { // tell OpenSSL the directories where to look up the root certs on demand QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories(); for (int a = 0; a < unixDirs.count(); ++a) q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDirs.at(a).constData()); } if (!sslContext->sslConfiguration.localCertificate().isNull()) { // Require a private key as well. if (sslContext->sslConfiguration.privateKey().isNull()) { sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } // Load certificate if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) { sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } if (configuration.d->privateKey.algorithm() == QSsl::Opaque) { sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle()); } else { // Load private key sslContext->pkey = q_EVP_PKEY_new(); // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free. // this lead to a memory leak. Now we use the *_set1_* functions which do not // take ownership of the RSA/DSA key instance because the QSslKey already has ownership. if (configuration.d->privateKey.algorithm() == QSsl::Rsa) q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle())); else q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle())); } if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) { sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } if (configuration.d->privateKey.algorithm() == QSsl::Opaque) sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey // Check if the certificate matches the private key. if (!q_SSL_CTX_check_private_key(sslContext->ctx)) { sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } // If we have any intermediate certificates then we need to add them to our chain bool first = true; foreach (const QSslCertificate &cert, configuration.d->localCertificateChain) { if (first) { first = false; continue; } q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, q_X509_dup(reinterpret_cast<X509 *>(cert.handle()))); } } // Initialize peer verification. if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) { q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0); } else { q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback); } // Set verification depth. if (sslContext->sslConfiguration.peerVerifyDepth() != 0) q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth()); // set persisted session if the user set it if (!configuration.sessionTicket().isEmpty()) sslContext->setSessionASN1(configuration.sessionTicket()); // Set temp DH params DH *dh = 0; dh = get_dh1024(); q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh); q_DH_free(dh); #ifndef OPENSSL_NO_EC // Set temp ECDH params EC_KEY *ecdh = 0; ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh); q_EC_KEY_free(ecdh); #endif // OPENSSL_NO_EC return sslContext; }
  • Qt Thread-Safe Logging

    Solved
    5
    0 Votes
    5 Posts
    2k Views
    aha_1980A
    @nsourl said in Qt Thread-Safe Logging: So, you suggest to use Qt's categorized logging and then use a message handler (I suppose by using QMutexLocker for multithreading) as described in the blog to redirect the logs to syslog. Is that right? No, as Qt already has integrated syslog capabilities. Please read my second link. Regards
  • Distinguish between Single Touch and MultiTouch

    Unsolved qttouchevent touch event handling multitouch
    4
    0 Votes
    4 Posts
    2k Views
    QTadQ
    Thank you very much for your answer! I must use QGraphicsProxyWidget because i need to flip the application of 180°! I'm in an embedded system with petalinux where i can't use a window system like x11 and so the rotation has to take place at a higher level (in the qt code)... The previous code with the if statement works quite well...sometimes it doesn't receive the multitouch but it's decent! I just don't understand why if i pass the TouchBegin to QGraphicsVIew::viewportEvent(event) no TouchUpdate arrives...instead if i return true TouchUpdate and End arrive...
  • QVector< QVBoxLayout * > crashing on adding layout

    Unsolved
    9
    0 Votes
    9 Posts
    902 Views
    JonBJ
    @Inzinejkr I can only say: start by creating separate instances of all your QVBoxLayouts: a given instance must only be used as a layout for a widget once, not re-used for multiple widgets as you presently show in your code.
  • Why does QMediaPlayer play a playlist with setMedia() but not with setPlaylist()?

    Solved
    7
    0 Votes
    7 Posts
    1k Views
    AlveinA
    OK. It seems I had an excessive expectation for the QtMultimedia's playlist management. According to the source code, just a few directives are handled, so forget about #EXT-X-STREAM-INF. Additionally, even after the stream has begun to play, I didn't find a safe way of getting the video details like bitrate, framerate or resolution. Not through QMediaPlayer's metadata, not through QMediaContent's resources. There's a "prospect" approach (talk about overkill), through QVideoWidget::videoSurface()::surfaceFormat(), but this thing was introduced in Qt 5.15. I have 5.14 and too lazy to upgrade just to check that. In the end, it's way simpler for me to download the playlist and parse the required directives myself.
  • Cell padding problem while centering a checkbox in QTableWidget

    3
    0 Votes
    3 Posts
    2k Views
    Christian EhrlicherC
    @KidTrent said in Cell padding problem while centering a checkbox in QTableWidget: views and not a single answer... Because it was answered already a lot of times elsewhere - Qt does not support it out of the box and the best is to use a custom item delegate and paint it by yourself.
  • QProcess SSH successful, now I want to sign in to MySql being served by the SSH Server

    Unsolved
    2
    0 Votes
    2 Posts
    586 Views
    jsulmJ
    @Katie-Trombetta I never used MySql over SSH tunnel. Take a look at https://linuxize.com/post/mysql-ssh-tunnel/ After establishing the SSH tunnel you should be able to access your database using https://doc.qt.io/qt-5/qtsql-index.html
  • Process and child process

    Solved
    35
    0 Votes
    35 Posts
    6k Views
    SPlattenS
    @JonB , @jsulm, just found: https://doc.qt.io/qt-5/ipc.html
  • Project [ moreless interactive Canvas and data visualization ]

    Unsolved
    4
    0 Votes
    4 Posts
    399 Views
    Pablo J. RoginaP
    @FutureDesigner please don't triple post! Since you already received replies in this post, you may need to close posts here and here.
  • How to work with MS Access (QODBC) multi-select fields?

    Solved qodbc sql delegates relational access
    5
    0 Votes
    5 Posts
    1k Views
    B
    Well, it took a lot of time for me to solve this problem. I solved it not in the way I wanted, but it works fine. Firstly, work with MS Access multi-valued fields is quite strange but quite simple: you should clear a field like DELETE Field.Value FROM MyTable WHERE Table.ID = MyID;. Then you can leave it clear or populate with new values performing several INSERT queries: INSERT INTO MyTable (Field.Value) VALUES (MyValue) WHERE MyTable.ID = MyID;. And it turned out that it's not that easy to make such code work in OnManualSubmit strategy table model, so I've made a widget which allows you to modify such fields. It is called MultiValueEditor. MultiValueEditor.h #ifndef MULTIVALUEEDITOR_H #define MULTIVALUEEDITOR_H #include <QDialog> #include <QListWidget> #include <QHash> #include <QSqlRelation> class MultiValueEditor : public QDialog { Q_OBJECT QModelIndex m_projectIndex; QListWidget* m_list; QHash<int, QListWidgetItem*> m_idToItem; public: explicit MultiValueEditor(QModelIndex t_index, const QSqlRelation& t_relation, QWidget* parent = nullptr); ~MultiValueEditor(); public slots: void accept() override; signals: void signalFinished(); }; #endif // MULTIVALUEEDITOR_H MultiValueEditor.cpp #include "multivalueeditor.h" #include <QSqlQuery> #include <QVBoxLayout> #include <QDialogButtonBox> #include <QPushButton> #include <QMessageBox> #include <QSqlError> #include <QDebug> #include <QSortFilterProxyModel> #include <QSqlTableModel> MultiValueEditor::MultiValueEditor(QModelIndex t_index, const QSqlRelation& t_relation, QWidget *parent) : QDialog(parent) , m_projectIndex(t_index) { const QString queryStr = QString("SELECT [%1], [%2] FROM [%3] ORDER BY [%2];") .arg(t_relation.indexColumn(), t_relation.displayColumn(), t_relation.tableName()); QSqlQuery query(queryStr, QSqlDatabase::database()); m_list = new QListWidget; while (query.next()) { const int id = query.value(0).toInt(); const QString value = query.value(1).toString(); QListWidgetItem* item = new QListWidgetItem(value); m_list->addItem(item); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(Qt::Unchecked); m_idToItem[id] = item; } QString value = m_projectIndex.data(Qt::EditRole).toString(); if (!value.isEmpty()) { for (const QString& id : value.split(';')) { m_idToItem[id.toInt()]->setCheckState(Qt::Checked); } } QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, this, &MultiValueEditor::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &MultiValueEditor::reject); QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addWidget(m_list); mainLayout->addWidget(buttonBox); setLayout(mainLayout); setWindowTitle(QString("Edit field '%1'").arg(t_relation.tableName())); setAttribute(Qt::WA_DeleteOnClose); } MultiValueEditor::~MultiValueEditor() {} void MultiValueEditor::accept() { // I use QSFPM, but there can be either QSqlTableModel or QSqlRelationalTableModel const QSortFilterProxyModel* proxyModel = qobject_cast<const QSortFilterProxyModel*>(m_projectIndex.model()); QSqlTableModel* sqlModel = qobject_cast<QSqlTableModel*>(proxyModel->sourceModel()); const QString primaryKeyName = sqlModel->headerData(0, Qt::Horizontal).toString(); const QString tableName = sqlModel->tableName(); const QString fieldName = sqlModel->headerData(m_projectIndex.column(), Qt::Horizontal).toString(); QString queryStr = QString("DELETE [%1].Value FROM [%2] WHERE [%3]=:tableId;") .arg(fieldName, tableName, primaryKeyName); QSqlQuery query; query.prepare(queryStr); const int tableId = m_projectIndex.siblingAtColumn(0).data().toInt(); query.bindValue(":tableId", tableId); if (!query.exec()) { QMessageBox msgBox(QMessageBox::Critical, ERROR_TITLE, QString("Error executing SQL-query\n%1") .arg(query.lastError().text()), QMessageBox::Ok, this); msgBox.exec(); } for (auto it = m_idToItem.constBegin(); it != m_idToItem.constEnd(); ++it) { if (it.value()->checkState() == Qt::Checked) { queryStr = QString("INSERT INTO [%1] ([%2].Value) " "VALUES (:fieldId) WHERE [%3]=:tableId;") .arg(tableName, fieldName, primaryKeyName); query.prepare(queryStr); query.bindValue(":fieldId", it.key()); query.bindValue(":tableId", tableId); query.exec(); } } emit signalFinished(); close(); } And in a place where you manage your table view (in my case in the MainWindow) you should connect TableView's double click with the execution of the MultiValueEditor. In my case it looks like this: MainWindow.cpp void MainWindow::setupDatabaseModels() { //... connect(m_projectTableView, &CustomTableView::doubleClicked, this, &MainWindow::slotEditProject); //... } void MainWindow::slotEditProject(const QModelIndex &index) { const int col = index.column(); if (col == 5) { QSqlRelation relation = QSqlRelation("Employees", "ID", "Name"); MultiValueEditor* multivalueEditor = new MultiValueEditor(index, relation, this); connect(multivalueEditor, &MultiValueEditor::signalFinished, [=](){ m_projectTableModel->select(); }); multivalueEditor->open(); } //... } Hope this will help somebody.
  • LNK1181: cannot open input file 'quazip.lib'

    Solved
    7
    0 Votes
    7 Posts
    870 Views
    A
    @Bonnie Okay Thank you