QWebView with multiple frames/pages sharing the same session data - c++

I have a QWebView, and it loads a certain page, the user logs in and goes about his business. This all works fine.
What I would like to do is have a second frame/pae open, that uses the logged in users session and all that jazz to load a reports page that it will render to an image file for display on a little USB screen.
Right now, I accomplish this with a completely different webView, which can't access protected pages, which is a bit of a security risk.
Here is some pseudo code for what I am thinking of:
webView->mainFrame->loadNormalUrl
secretFrame = webView->createSecretFrame
secretFrame->useSessionOf(webView->mainFrame)
secretFrame->loadReportUrl
secretFrame->doStuffThatAlreadyWorks
Any help, pointers, links would be super helpful! Thanks :)

Well,
This question didn't receive and answer, so I pattered off to the qtwebkit mailing list, and they were very helpful.
The essential thing is to subclass QNetworkCookieJar, the most important method being the loading from disk, which you call in your constructor.
QList<QNetworkCookie> cookies;
if (m_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&m_file);
QString txt = in.readAll();
QStringList lines = txt.split("\n");
foreach (QString c, lines) {
cookies.append(QNetworkCookie::parseCookies(c.toUtf8()));
}
m_file.close();
}
setAllCookies(cookies);
Of Course, you'll also need a writing function, like so:
QTextStream out(&m_file);
foreach (const QByteArray &cookie, m_rawCookies)
out << cookie + "\n";
m_file.close();
And your raw cookies like so:
QList<QNetworkCookie> cookies = allCookies();
m_rawCookies.clear();
foreach (const QNetworkCookie &cookie, cookies) {
m_rawCookies.append(cookie.toRawForm());
}
If you download the webkit source, you can take a look at the testbrowser code for a more complete example.

One way you could approach this is to not try to do it with QWebViews at all, but instead subclass QNetworkManager and hook its signals to snoop the QNetworkReplys that are sent back.
Otherwise in your second QWebView you could just set its content to the HTML you want to display and you might be able to enforce only grabbing data from the cache.

Related

Performantly appending (rich) text into QTextEdit or QTextBrowser in Qt

QTextEdit can be appended text to simply using append(). However, if the document is rich text, every time you append to the document, it is apparently reparsed. This seems like a bit of a trap in Qt.
If you're using the edit box as a log window and appending text in fast successions as a result of external signals, the appending can easily hang your app with no intermediate appends shown until each of the appends have completed.
How do I append rich text to a QTextEdit without it slowing down the entire UI?
If you want each append to actually show quickly & separately (instead of waiting until they've all been appended before they are shown), you need to access the internal QTextDocument:
void fastAppend(QString message,QTextEdit *editWidget)
{
const bool atBottom = editWidget->verticalScrollBar()->value() == editWidget->verticalScrollBar()->maximum();
QTextDocument* doc = editWidget->document();
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End);
cursor.beginEditBlock();
cursor.insertBlock();
cursor.insertHtml(message);
cursor.endEditBlock();
//scroll scrollarea to bottom if it was at bottom when we started
//(we don't want to force scrolling to bottom if user is looking at a
//higher position)
if (atBottom) {
scrollLogToBottom(editWidget);
}
}
void scrollLogToBottom(QTextEdit *editWidget)
{
QScrollBar* bar = editWidget->verticalScrollBar();
bar->setValue(bar->maximum());
}
The scrolling to bottom is optional, but in logging use it's a reasonable default for UI behaviour.
Also, if your app is doing lots of other processing at the same time, appending this at the end of fastAppend, will prioritize actually getting the message displayed asap:
//show the message in output right away by triggering event loop
QCoreApplication::processEvents();
This actually seems a kind of trap in Qt. I would know why there isn't a fastAppend method directly in QTextEdit? Or are there caveats to this solution?
(My company actually paid KDAB for this advice, but this seems so silly that I thought this should be more common knowledge.)

Displaying picture that is not in resources of Qt

I am currently writing an application in Qt, which is basically a warehouse. An application reads CSV, enables user to process it and enables to show picture of each good. I tried displaying picture using QLabel and Pixmap, however nothing happens even though the file is in the same folder and the name provided is exactly as it should be. Is it the resources issue or my code fails somehow? Is there any possibility to display the image without adding it to resources in order to avoid adding many photos manually?
void ImageViewer::viewImage(QString imgName)
{
QString pathWithName = imgName;
pathWithName.append(".jpg");
ui->label->setPixmap( QPixmap(pathWithName) );
ui->label->show();
update();
}
Sorry for any mistakes in post creation or code displaying here- it's my first post.
Edit:
I am adding code from MainWindow (called CsvReader in my project) to how I'm invoking the method viewImage:
void CsvReader::on_imgView_clicked()
{
ImageViewer* img = new ImageViewer(this);
img->setModal(true);
img->exec();
QModelIndex List selInd ui->tableView->selectionModel()->selectedIndexes();
QString id = model->item(selInd.first().row(), 0)->text();
img->viewImage(id);
}
Edit 2:
Solved. Had to change path using QDir:
QDir* directory = new QDir("/home/kokos/Magazyn/photos");
QFileInfo checkFile(*directory, pathWithName);
Thanks in advance,
Kokos
Confirm your file's location and existence first. Add this;
QFileInfo checkFile(pathWithName);
if (checkFile.exists() && checkFile.isFile()) {
// your code
}

store input of line edit to string qt

I'm a beginner.I am making a simple gui program using qt in which you enter a url/website and that program will open that webpage in chrome.I used line edit in which user enters url and i used returnPressed() slot, but the problem is (it might sound stupid) that i don't know how to take the input by user and store it in a string so that i can pass that string as parameter to chrome.Is im asking something wrong.also tell me how can i save input to a txt file, i know how to do that in a console program.Is this process is same with others like text edit etc.
My mainwindow.cpp:
QString exeloc = "F:\\Users\\Amol-2\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe";
void MainWindow::on_site_returnPressed()
{
QString site;
getwchar(site);
QString space=" ";
QString result = exeloc + space + site;
QProcess::execute(result);
}
What im doing wrong.
thanks
You've got your approach slightly wrong, I can see where you're coming from though. It's actually a lot more simple than you're trying, Qt has a QDesktopServices class that allows you to interact with various system items, including open urls in the browser. There's documentation on it here.
QLineEdit has a text() function that will return a QString. So you can do something like this:
QString site = ui->site->text();
You don't have to use QProcess to open a web site in a browser. You can use QDesktopServices::openUrl static function.
Like this:
QString site = ui->site->text();
QUrl url(site);
QDesktopServices::openUrl(url);
Remember to include QDesktopServices and QUrl headers:
#include <QDesktopServices>
#include <QUrl>

QT Model/View like Log Viewer

I have a Monitoring program which runs another long process (can take days). The process generates huge amount of log information. This log information cant be stored in memory so I am redirecting it into log file. The problem is than Monitoring program need to display this log. I cant use a widget that requires storing entire text in memory. I need to have somting like
class TextView
{
void setModel(TextModel*)
}
class TextModel
{
int pageCount();
QString page(int i);
Q_SIGNALS:
void pageCountChanged(int cnt)
};
Implementation of TextModel will load page in memory per request.
Of courese I can implement Text Viewer widget from the scratch, but I have no enough time to do that. Any sugestions?
You can use QListView and derive your model from QAbstractListModel. You need to define rowCount and data methods in your model.

Using images in QListWidget, is this possible?

I am using QT to create a chat messenger client. To display the list of online users, I'm using a QListWidget, as created like this:
listWidget = new QListWidget(horizontalLayoutWidget);
listWidget->setObjectName("userList");
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(listWidget->sizePolicy().hasHeightForWidth());
listWidget->setSizePolicy(sizePolicy1);
listWidget->setMinimumSize(QSize(30, 0));
listWidget->setMaximumSize(QSize(150, 16777215));
listWidget->setBaseSize(QSize(100, 0));
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
Users are shown by constantly refreshing the list, like this: (Note: There are different channels, with different userlists, so refreshing it is the most efficient thing to do, as far as I know.)
void FMessenger::refreshUserlist()
{
if (currentPanel == 0)
return;
listWidget = this->findChild<QListWidget *>(QString("userList"));
listWidget->clear();
QList<FCharacter*> charList = currentPanel->charList();
QListWidgetItem* charitem = 0;
FCharacter* character;
foreach(character, charList)
{
charitem = new QListWidgetItem(character->name());
// charitem->setIcon(QIcon(":/Images/status.png"));
listWidget->addItem(charitem);
}
}
This has always worked perfectly. The line that I commented out is the one I have problems with: my current goal is to be able to display a user's online status with an image, which represents whether they are busy, away, available, etc. Using setIcon() does absolutely nothing though, apparently; the items still show up as they used to, without icons.
I'm aware that this is probably not the way this function needs to be used, but I have found little documentation about it online, and absolutely no useful examples of implementations. My question is, can anybody help me with fixing this problem?
This is how you may conduct your debugging:
Try the constructor that has both icon and text as arguments.
Try to use that icon in another context to ensure it is displayable (construct a QIcon with same argument and use it elsewhere, e.g. QLabel!).
Use icon() from the QListWidgetItem to receive back the icon and then look at that QIcon.
Create a new QListWidget, change nothing, and ordinarily add some stock items in your MainWidget's constructor. See if the icons show up there.